Merge jdk8-b12

Fri, 28 Oct 2011 17:49:36 -0700

author
lana
date
Fri, 28 Oct 2011 17:49:36 -0700
changeset 1119
f2d6ed25857d
parent 1107
8ff85191a7ac
parent 1118
52df2131e294
child 1120
ae25163501bc

Merge

src/share/classes/com/sun/tools/javac/file/Paths.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/parser/Keywords.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/parser/Token.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/apt/main/AptJavaCompiler.java	Thu Oct 27 13:54:50 2011 -0700
     1.2 +++ b/src/share/classes/com/sun/tools/apt/main/AptJavaCompiler.java	Fri Oct 28 17:49:36 2011 -0700
     1.3 @@ -42,7 +42,6 @@
     1.4  import com.sun.tools.apt.comp.*;
     1.5  import com.sun.tools.apt.util.Bark;
     1.6  import com.sun.mirror.apt.AnnotationProcessorFactory;
     1.7 -import com.sun.tools.javac.parser.DocCommentScanner;
     1.8  
     1.9  /**
    1.10   *  <p><b>This is NOT part of any supported API.
     2.1 --- a/src/share/classes/com/sun/tools/apt/main/Main.java	Thu Oct 27 13:54:50 2011 -0700
     2.2 +++ b/src/share/classes/com/sun/tools/apt/main/Main.java	Fri Oct 28 17:49:36 2011 -0700
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
     2.6 + * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
     2.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.8   *
     2.9   * This code is free software; you can redistribute it and/or modify it
    2.10 @@ -56,7 +56,7 @@
    2.11  import com.sun.tools.apt.util.Bark;
    2.12  import com.sun.mirror.apt.AnnotationProcessorFactory;
    2.13  
    2.14 -import static com.sun.tools.javac.file.Paths.pathToURLs;
    2.15 +import static com.sun.tools.javac.file.Locations.pathToURLs;
    2.16  
    2.17  /** This class provides a commandline interface to the apt build-time
    2.18   *  tool.
     3.1 --- a/src/share/classes/com/sun/tools/javac/code/Printer.java	Thu Oct 27 13:54:50 2011 -0700
     3.2 +++ b/src/share/classes/com/sun/tools/javac/code/Printer.java	Fri Oct 28 17:49:36 2011 -0700
     3.3 @@ -258,7 +258,7 @@
     3.4              ClassType norm = (ClassType) t.tsym.type;
     3.5              if (norm == null) {
     3.6                  s = localize(locale, "compiler.misc.anonymous.class", (Object) null);
     3.7 -            } else if (norm.interfaces_field.nonEmpty()) {
     3.8 +            } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
     3.9                  s = localize(locale, "compiler.misc.anonymous.class",
    3.10                          visit(norm.interfaces_field.head, locale));
    3.11              } else {
     4.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Oct 27 13:54:50 2011 -0700
     4.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Fri Oct 28 17:49:36 2011 -0700
     4.3 @@ -278,7 +278,6 @@
     4.4          boolean tPrimitive = t.isPrimitive();
     4.5          boolean sPrimitive = s.isPrimitive();
     4.6          if (tPrimitive == sPrimitive) {
     4.7 -            checkUnsafeVarargsConversion(t, s, warn);
     4.8              return isSubtypeUnchecked(t, s, warn);
     4.9          }
    4.10          if (!allowBoxing) return false;
    4.11 @@ -286,27 +285,6 @@
    4.12              ? isSubtype(boxedClass(t).type, s)
    4.13              : isSubtype(unboxedType(t), s);
    4.14      }
    4.15 -    //where
    4.16 -    private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {
    4.17 -        if (t.tag != ARRAY || isReifiable(t)) return;
    4.18 -        ArrayType from = (ArrayType)t;
    4.19 -        boolean shouldWarn = false;
    4.20 -        switch (s.tag) {
    4.21 -            case ARRAY:
    4.22 -                ArrayType to = (ArrayType)s;
    4.23 -                shouldWarn = from.isVarargs() &&
    4.24 -                        !to.isVarargs() &&
    4.25 -                        !isReifiable(from);
    4.26 -                break;
    4.27 -            case CLASS:
    4.28 -                shouldWarn = from.isVarargs() &&
    4.29 -                        isSubtype(from, s);
    4.30 -                break;
    4.31 -        }
    4.32 -        if (shouldWarn) {
    4.33 -            warn.warn(LintCategory.VARARGS);
    4.34 -        }
    4.35 -    }
    4.36  
    4.37      /**
    4.38       * Is t a subtype of or convertiable via boxing/unboxing
    4.39 @@ -328,42 +306,63 @@
    4.40       * Is t an unchecked subtype of s?
    4.41       */
    4.42      public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
    4.43 -        if (t.tag == ARRAY && s.tag == ARRAY) {
    4.44 -            if (((ArrayType)t).elemtype.tag <= lastBaseTag) {
    4.45 -                return isSameType(elemtype(t), elemtype(s));
    4.46 -            } else {
    4.47 -                ArrayType from = (ArrayType)t;
    4.48 -                ArrayType to = (ArrayType)s;
    4.49 -                if (from.isVarargs() &&
    4.50 -                        !to.isVarargs() &&
    4.51 -                        !isReifiable(from)) {
    4.52 -                    warn.warn(LintCategory.VARARGS);
    4.53 +        boolean result = isSubtypeUncheckedInternal(t, s, warn);
    4.54 +        if (result) {
    4.55 +            checkUnsafeVarargsConversion(t, s, warn);
    4.56 +        }
    4.57 +        return result;
    4.58 +    }
    4.59 +    //where
    4.60 +        private boolean isSubtypeUncheckedInternal(Type t, Type s, Warner warn) {
    4.61 +            if (t.tag == ARRAY && s.tag == ARRAY) {
    4.62 +                if (((ArrayType)t).elemtype.tag <= lastBaseTag) {
    4.63 +                    return isSameType(elemtype(t), elemtype(s));
    4.64 +                } else {
    4.65 +                    return isSubtypeUnchecked(elemtype(t), elemtype(s), warn);
    4.66                  }
    4.67 -                return isSubtypeUnchecked(elemtype(t), elemtype(s), warn);
    4.68 -            }
    4.69 -        } else if (isSubtype(t, s)) {
    4.70 -            return true;
    4.71 -        }
    4.72 -        else if (t.tag == TYPEVAR) {
    4.73 -            return isSubtypeUnchecked(t.getUpperBound(), s, warn);
    4.74 -        }
    4.75 -        else if (s.tag == UNDETVAR) {
    4.76 -            UndetVar uv = (UndetVar)s;
    4.77 -            if (uv.inst != null)
    4.78 -                return isSubtypeUnchecked(t, uv.inst, warn);
    4.79 -        }
    4.80 -        else if (!s.isRaw()) {
    4.81 -            Type t2 = asSuper(t, s.tsym);
    4.82 -            if (t2 != null && t2.isRaw()) {
    4.83 -                if (isReifiable(s))
    4.84 -                    warn.silentWarn(LintCategory.UNCHECKED);
    4.85 -                else
    4.86 -                    warn.warn(LintCategory.UNCHECKED);
    4.87 +            } else if (isSubtype(t, s)) {
    4.88                  return true;
    4.89              }
    4.90 +            else if (t.tag == TYPEVAR) {
    4.91 +                return isSubtypeUnchecked(t.getUpperBound(), s, warn);
    4.92 +            }
    4.93 +            else if (s.tag == UNDETVAR) {
    4.94 +                UndetVar uv = (UndetVar)s;
    4.95 +                if (uv.inst != null)
    4.96 +                    return isSubtypeUnchecked(t, uv.inst, warn);
    4.97 +            }
    4.98 +            else if (!s.isRaw()) {
    4.99 +                Type t2 = asSuper(t, s.tsym);
   4.100 +                if (t2 != null && t2.isRaw()) {
   4.101 +                    if (isReifiable(s))
   4.102 +                        warn.silentWarn(LintCategory.UNCHECKED);
   4.103 +                    else
   4.104 +                        warn.warn(LintCategory.UNCHECKED);
   4.105 +                    return true;
   4.106 +                }
   4.107 +            }
   4.108 +            return false;
   4.109          }
   4.110 -        return false;
   4.111 -    }
   4.112 +
   4.113 +        private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {
   4.114 +            if (t.tag != ARRAY || isReifiable(t)) return;
   4.115 +            ArrayType from = (ArrayType)t;
   4.116 +            boolean shouldWarn = false;
   4.117 +            switch (s.tag) {
   4.118 +                case ARRAY:
   4.119 +                    ArrayType to = (ArrayType)s;
   4.120 +                    shouldWarn = from.isVarargs() &&
   4.121 +                            !to.isVarargs() &&
   4.122 +                            !isReifiable(from);
   4.123 +                    break;
   4.124 +                case CLASS:
   4.125 +                    shouldWarn = from.isVarargs();
   4.126 +                    break;
   4.127 +            }
   4.128 +            if (shouldWarn) {
   4.129 +                warn.warn(LintCategory.VARARGS);
   4.130 +            }
   4.131 +        }
   4.132  
   4.133      /**
   4.134       * Is t a subtype of s?<br>
     5.1 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Thu Oct 27 13:54:50 2011 -0700
     5.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Fri Oct 28 17:49:36 2011 -0700
     5.3 @@ -34,7 +34,8 @@
     5.4  import com.sun.tools.javac.code.Type.*;
     5.5  import com.sun.tools.javac.code.Type.ForAll.ConstraintKind;
     5.6  import com.sun.tools.javac.code.Symbol.*;
     5.7 -import com.sun.tools.javac.util.JCDiagnostic;
     5.8 +import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
     5.9 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    5.10  
    5.11  import static com.sun.tools.javac.code.TypeTags.*;
    5.12  
    5.13 @@ -56,6 +57,7 @@
    5.14      Types types;
    5.15      Check chk;
    5.16      Resolve rs;
    5.17 +    Log log;
    5.18      JCDiagnostic.Factory diags;
    5.19  
    5.20      public static Infer instance(Context context) {
    5.21 @@ -70,6 +72,7 @@
    5.22          syms = Symtab.instance(context);
    5.23          types = Types.instance(context);
    5.24          rs = Resolve.instance(context);
    5.25 +        log = Log.instance(context);
    5.26          chk = Check.instance(context);
    5.27          diags = JCDiagnostic.Factory.instance(context);
    5.28          ambiguousNoInstanceException =
    5.29 @@ -460,7 +463,7 @@
    5.30              // quantify result type with them
    5.31              final List<Type> inferredTypes = insttypes.toList();
    5.32              final List<Type> all_tvars = tvars; //this is the wrong tvars
    5.33 -            return new UninferredMethodType(mt, restvars.toList()) {
    5.34 +            return new UninferredMethodType(env.tree.pos(), msym, mt, restvars.toList()) {
    5.35                  @Override
    5.36                  List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
    5.37                      for (Type t : restundet.toList()) {
    5.38 @@ -502,13 +505,17 @@
    5.39           * type - when the return type is instantiated (see Infer.instantiateExpr)
    5.40           * the underlying method type is also updated.
    5.41           */
    5.42 -        static abstract class UninferredMethodType extends DelegatedType {
    5.43 +        abstract class UninferredMethodType extends DelegatedType {
    5.44  
    5.45              final List<Type> tvars;
    5.46 +            final Symbol msym;
    5.47 +            final DiagnosticPosition pos;
    5.48  
    5.49 -            public UninferredMethodType(MethodType mtype, List<Type> tvars) {
    5.50 +            public UninferredMethodType(DiagnosticPosition pos, Symbol msym, MethodType mtype, List<Type> tvars) {
    5.51                  super(METHOD, new MethodType(mtype.argtypes, null, mtype.thrown, mtype.tsym));
    5.52                  this.tvars = tvars;
    5.53 +                this.msym = msym;
    5.54 +                this.pos = pos;
    5.55                  asMethodType().restype = new UninferredReturnType(tvars, mtype.restype);
    5.56              }
    5.57  
    5.58 @@ -543,6 +550,9 @@
    5.59                  public Type inst(List<Type> actuals, Types types) {
    5.60                      Type newRestype = super.inst(actuals, types);
    5.61                      instantiateReturnType(newRestype, actuals, types);
    5.62 +                    if (rs.verboseResolutionMode.contains(VerboseResolutionMode.DEFERRED_INST)) {
    5.63 +                        log.note(pos, "deferred.method.inst", msym, UninferredMethodType.this.qtype, newRestype);
    5.64 +                    }
    5.65                      return newRestype;
    5.66                  }
    5.67                  @Override
     6.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Oct 27 13:54:50 2011 -0700
     6.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri Oct 28 17:49:36 2011 -0700
     6.3 @@ -25,29 +25,33 @@
     6.4  
     6.5  package com.sun.tools.javac.comp;
     6.6  
     6.7 -import com.sun.tools.javac.util.*;
     6.8 -import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
     6.9 +import com.sun.tools.javac.api.Formattable.LocalizedString;
    6.10  import com.sun.tools.javac.code.*;
    6.11 +import com.sun.tools.javac.code.Type.*;
    6.12 +import com.sun.tools.javac.code.Symbol.*;
    6.13  import com.sun.tools.javac.jvm.*;
    6.14  import com.sun.tools.javac.tree.*;
    6.15 -import com.sun.tools.javac.api.Formattable.LocalizedString;
    6.16 -import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
    6.17 +import com.sun.tools.javac.tree.JCTree.*;
    6.18 +import com.sun.tools.javac.util.*;
    6.19 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
    6.20 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    6.21 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
    6.22  
    6.23 -import com.sun.tools.javac.code.Type.*;
    6.24 -import com.sun.tools.javac.code.Symbol.*;
    6.25 -import com.sun.tools.javac.tree.JCTree.*;
    6.26 +import java.util.Arrays;
    6.27 +import java.util.Collection;
    6.28 +import java.util.EnumSet;
    6.29 +import java.util.HashMap;
    6.30 +import java.util.HashSet;
    6.31 +import java.util.LinkedHashMap;
    6.32 +import java.util.Map;
    6.33 +import java.util.Set;
    6.34 +
    6.35 +import javax.lang.model.element.ElementVisitor;
    6.36  
    6.37  import static com.sun.tools.javac.code.Flags.*;
    6.38  import static com.sun.tools.javac.code.Kinds.*;
    6.39  import static com.sun.tools.javac.code.TypeTags.*;
    6.40 -import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
    6.41 -import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
    6.42 -import javax.lang.model.element.ElementVisitor;
    6.43 -
    6.44 -import java.util.Map;
    6.45 -import java.util.Set;
    6.46 -import java.util.HashMap;
    6.47 -import java.util.HashSet;
    6.48 +import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
    6.49  
    6.50  /** Helper class for name resolution, used mostly by the attribution phase.
    6.51   *
    6.52 @@ -73,9 +77,45 @@
    6.53      public final boolean varargsEnabled; // = source.allowVarargs();
    6.54      public final boolean allowMethodHandles;
    6.55      private final boolean debugResolve;
    6.56 +    final EnumSet<VerboseResolutionMode> verboseResolutionMode;
    6.57  
    6.58      Scope polymorphicSignatureScope;
    6.59  
    6.60 +    enum VerboseResolutionMode {
    6.61 +        SUCCESS("success"),
    6.62 +        FAILURE("failure"),
    6.63 +        APPLICABLE("applicable"),
    6.64 +        INAPPLICABLE("inapplicable"),
    6.65 +        DEFERRED_INST("deferred-inference"),
    6.66 +        PREDEF("predef"),
    6.67 +        OBJECT_INIT("object-init"),
    6.68 +        INTERNAL("internal");
    6.69 +
    6.70 +        String opt;
    6.71 +
    6.72 +        private VerboseResolutionMode(String opt) {
    6.73 +            this.opt = opt;
    6.74 +        }
    6.75 +
    6.76 +        static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) {
    6.77 +            String s = opts.get("verboseResolution");
    6.78 +            EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class);
    6.79 +            if (s == null) return res;
    6.80 +            if (s.contains("all")) {
    6.81 +                res = EnumSet.allOf(VerboseResolutionMode.class);
    6.82 +            }
    6.83 +            Collection<String> args = Arrays.asList(s.split(","));
    6.84 +            for (VerboseResolutionMode mode : values()) {
    6.85 +                if (args.contains(mode.opt)) {
    6.86 +                    res.add(mode);
    6.87 +                } else if (args.contains("-" + mode.opt)) {
    6.88 +                    res.remove(mode);
    6.89 +                }
    6.90 +            }
    6.91 +            return res;
    6.92 +        }
    6.93 +    }
    6.94 +
    6.95      public static Resolve instance(Context context) {
    6.96          Resolve instance = context.get(resolveKey);
    6.97          if (instance == null)
    6.98 @@ -111,6 +151,7 @@
    6.99          varargsEnabled = source.allowVarargs();
   6.100          Options options = Options.instance(context);
   6.101          debugResolve = options.isSet("debugresolve");
   6.102 +        verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
   6.103          Target target = Target.instance(context);
   6.104          allowMethodHandles = target.hasMethodHandles();
   6.105          polymorphicSignatureScope = new Scope(syms.noSymbol);
   6.106 @@ -684,13 +725,16 @@
   6.107          if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
   6.108          Assert.check(sym.kind < AMBIGUOUS);
   6.109          try {
   6.110 -            rawInstantiate(env, site, sym, argtypes, typeargtypes,
   6.111 +            Type mt = rawInstantiate(env, site, sym, argtypes, typeargtypes,
   6.112                                 allowBoxing, useVarargs, Warner.noWarnings);
   6.113 +            if (!operator) addVerboseApplicableCandidateDiag(sym ,mt);
   6.114          } catch (InapplicableMethodException ex) {
   6.115 +            if (!operator) addVerboseInapplicableCandidateDiag(sym, ex.getDiagnostic());
   6.116              switch (bestSoFar.kind) {
   6.117              case ABSENT_MTH:
   6.118                  return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
   6.119              case WRONG_MTH:
   6.120 +                if (operator) return bestSoFar;
   6.121                  wrongMethods.addCandidate(currentStep, wrongMethod.sym, wrongMethod.explanation);
   6.122              case WRONG_MTHS:
   6.123                  return wrongMethods.addCandidate(currentStep, sym, ex.getDiagnostic());
   6.124 @@ -708,6 +752,34 @@
   6.125              : mostSpecific(sym, bestSoFar, env, site,
   6.126                             allowBoxing && operator, useVarargs);
   6.127      }
   6.128 +    //where
   6.129 +        void addVerboseApplicableCandidateDiag(Symbol sym, Type inst) {
   6.130 +            if (!verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE))
   6.131 +                return;
   6.132 +
   6.133 +            JCDiagnostic subDiag = null;
   6.134 +            if (inst.getReturnType().tag == FORALL) {
   6.135 +                Type diagType = types.createMethodTypeWithReturn(inst.asMethodType(),
   6.136 +                                                                ((ForAll)inst.getReturnType()).qtype);
   6.137 +                subDiag = diags.fragment("partial.inst.sig", diagType);
   6.138 +            } else if (sym.type.tag == FORALL) {
   6.139 +                subDiag = diags.fragment("full.inst.sig", inst.asMethodType());
   6.140 +            }
   6.141 +
   6.142 +            String key = subDiag == null ?
   6.143 +                    "applicable.method.found" :
   6.144 +                    "applicable.method.found.1";
   6.145 +
   6.146 +            verboseResolutionCandidateDiags.put(sym,
   6.147 +                    diags.fragment(key, verboseResolutionCandidateDiags.size(), sym, subDiag));
   6.148 +        }
   6.149 +
   6.150 +        void addVerboseInapplicableCandidateDiag(Symbol sym, JCDiagnostic subDiag) {
   6.151 +            if (!verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))
   6.152 +                return;
   6.153 +            verboseResolutionCandidateDiags.put(sym,
   6.154 +                    diags.fragment("not.applicable.method.found", verboseResolutionCandidateDiags.size(), sym, subDiag));
   6.155 +        }
   6.156  
   6.157      /* Return the most specific of the two methods for a call,
   6.158       *  given that both are accessible and applicable.
   6.159 @@ -905,8 +977,9 @@
   6.160                        boolean allowBoxing,
   6.161                        boolean useVarargs,
   6.162                        boolean operator) {
   6.163 +        verboseResolutionCandidateDiags.clear();
   6.164          Symbol bestSoFar = methodNotFound;
   6.165 -        return findMethod(env,
   6.166 +        bestSoFar = findMethod(env,
   6.167                            site,
   6.168                            name,
   6.169                            argtypes,
   6.170 @@ -918,6 +991,8 @@
   6.171                            useVarargs,
   6.172                            operator,
   6.173                            new HashSet<TypeSymbol>());
   6.174 +        reportVerboseResolutionDiagnostic(env.tree.pos(), name, site, argtypes, typeargtypes, bestSoFar);
   6.175 +        return bestSoFar;
   6.176      }
   6.177      // where
   6.178      private Symbol findMethod(Env<AttrContext> env,
   6.179 @@ -975,6 +1050,37 @@
   6.180          }
   6.181          return bestSoFar;
   6.182      }
   6.183 +    //where
   6.184 +        void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
   6.185 +            boolean success = bestSoFar.kind < ERRONEOUS;
   6.186 +
   6.187 +            if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
   6.188 +                return;
   6.189 +            } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
   6.190 +                return;
   6.191 +            }
   6.192 +
   6.193 +            if (bestSoFar.name == names.init &&
   6.194 +                    bestSoFar.owner == syms.objectType.tsym &&
   6.195 +                    !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
   6.196 +                return; //skip diags for Object constructor resolution
   6.197 +            } else if (site == syms.predefClass.type && !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
   6.198 +                return; //skip spurious diags for predef symbols (i.e. operators)
   6.199 +            } else if (internalResolution && !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
   6.200 +                return;
   6.201 +            }
   6.202 +
   6.203 +            int pos = 0;
   6.204 +            for (Symbol s : verboseResolutionCandidateDiags.keySet()) {
   6.205 +                if (s == bestSoFar) break;
   6.206 +                pos++;
   6.207 +            }
   6.208 +            String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
   6.209 +            JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name, site.tsym, pos, currentStep,
   6.210 +                    methodArguments(argtypes), methodArguments(typeargtypes));
   6.211 +            JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, List.from(verboseResolutionCandidateDiags.values().toArray(new JCDiagnostic[verboseResolutionCandidateDiags.size()])));
   6.212 +            log.report(d);
   6.213 +        }
   6.214  
   6.215      /** Find unqualified method matching given name, type and value arguments.
   6.216       *  @param env       The current environment.
   6.217 @@ -1543,12 +1649,19 @@
   6.218                                          Type site, Name name,
   6.219                                          List<Type> argtypes,
   6.220                                          List<Type> typeargtypes) {
   6.221 -        Symbol sym = resolveQualifiedMethod(
   6.222 -            pos, env, site.tsym, site, name, argtypes, typeargtypes);
   6.223 -        if (sym.kind == MTH) return (MethodSymbol)sym;
   6.224 -        else throw new FatalError(
   6.225 -                 diags.fragment("fatal.err.cant.locate.meth",
   6.226 -                                name));
   6.227 +        boolean prevInternal = internalResolution;
   6.228 +        try {
   6.229 +            internalResolution = true;
   6.230 +            Symbol sym = resolveQualifiedMethod(
   6.231 +                pos, env, site.tsym, site, name, argtypes, typeargtypes);
   6.232 +            if (sym.kind == MTH) return (MethodSymbol)sym;
   6.233 +            else throw new FatalError(
   6.234 +                     diags.fragment("fatal.err.cant.locate.meth",
   6.235 +                                    name));
   6.236 +        }
   6.237 +        finally {
   6.238 +            internalResolution = prevInternal;
   6.239 +        }
   6.240      }
   6.241  
   6.242      /** Resolve constructor.
   6.243 @@ -1685,6 +1798,7 @@
   6.244       */
   6.245      Symbol resolveOperator(DiagnosticPosition pos, int optag,
   6.246                             Env<AttrContext> env, List<Type> argtypes) {
   6.247 +        startResolution();
   6.248          Name name = treeinfo.operatorName(optag);
   6.249          Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
   6.250                                  null, false, false, true);
   6.251 @@ -1828,7 +1942,7 @@
   6.252      private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
   6.253  
   6.254      public Object methodArguments(List<Type> argtypes) {
   6.255 -        return argtypes.isEmpty() ? noArgs : argtypes;
   6.256 +        return argtypes == null || argtypes.isEmpty() ? noArgs : argtypes;
   6.257      }
   6.258  
   6.259      /**
   6.260 @@ -2375,10 +2489,15 @@
   6.261      private Map<MethodResolutionPhase, Symbol> methodResolutionCache =
   6.262          new HashMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.values().length);
   6.263  
   6.264 +    private Map<Symbol, JCDiagnostic> verboseResolutionCandidateDiags =
   6.265 +        new LinkedHashMap<Symbol, JCDiagnostic>();
   6.266 +
   6.267      final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
   6.268  
   6.269      private MethodResolutionPhase currentStep = null;
   6.270  
   6.271 +    private boolean internalResolution = false;
   6.272 +
   6.273      private MethodResolutionPhase firstErroneousResolutionPhase() {
   6.274          MethodResolutionPhase bestSoFar = BASIC;
   6.275          Symbol sym = methodNotFound;
     7.1 --- a/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Thu Oct 27 13:54:50 2011 -0700
     7.2 +++ b/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Fri Oct 28 17:49:36 2011 -0700
     7.3 @@ -25,7 +25,6 @@
     7.4  
     7.5  package com.sun.tools.javac.file;
     7.6  
     7.7 -import java.util.Comparator;
     7.8  import java.io.ByteArrayOutputStream;
     7.9  import java.io.File;
    7.10  import java.io.FileNotFoundException;
    7.11 @@ -41,6 +40,7 @@
    7.12  import java.util.Arrays;
    7.13  import java.util.Collection;
    7.14  import java.util.Collections;
    7.15 +import java.util.Comparator;
    7.16  import java.util.EnumSet;
    7.17  import java.util.HashMap;
    7.18  import java.util.Iterator;
    7.19 @@ -56,14 +56,12 @@
    7.20  
    7.21  import com.sun.tools.javac.file.RelativePath.RelativeFile;
    7.22  import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
    7.23 -import com.sun.tools.javac.main.OptionName;
    7.24  import com.sun.tools.javac.util.BaseFileManager;
    7.25  import com.sun.tools.javac.util.Context;
    7.26  import com.sun.tools.javac.util.List;
    7.27  import com.sun.tools.javac.util.ListBuffer;
    7.28  
    7.29  import static javax.tools.StandardLocation.*;
    7.30 -import static com.sun.tools.javac.main.OptionName.*;
    7.31  
    7.32  /**
    7.33   * This class provides access to the source, class and other files
    7.34 @@ -83,32 +81,14 @@
    7.35              return buffer.toString().toCharArray();
    7.36      }
    7.37  
    7.38 -    /** Encapsulates knowledge of paths
    7.39 -     */
    7.40 -    private Paths paths;
    7.41 -
    7.42      private FSInfo fsInfo;
    7.43  
    7.44      private boolean contextUseOptimizedZip;
    7.45      private ZipFileIndexCache zipFileIndexCache;
    7.46  
    7.47 -    private final File uninited = new File("U N I N I T E D");
    7.48 -
    7.49      private final Set<JavaFileObject.Kind> sourceOrClass =
    7.50          EnumSet.of(JavaFileObject.Kind.SOURCE, JavaFileObject.Kind.CLASS);
    7.51  
    7.52 -    /** The standard output directory, primarily used for classes.
    7.53 -     *  Initialized by the "-d" option.
    7.54 -     *  If classOutDir = null, files are written into same directory as the sources
    7.55 -     *  they were generated from.
    7.56 -     */
    7.57 -    private File classOutDir = uninited;
    7.58 -
    7.59 -    /** The output directory, used when generating sources while processing annotations.
    7.60 -     *  Initialized by the "-s" option.
    7.61 -     */
    7.62 -    private File sourceOutDir = uninited;
    7.63 -
    7.64      protected boolean mmappedIO;
    7.65      protected boolean ignoreSymbolFile;
    7.66  
    7.67 @@ -154,13 +134,6 @@
    7.68      @Override
    7.69      public void setContext(Context context) {
    7.70          super.setContext(context);
    7.71 -        if (paths == null) {
    7.72 -            paths = Paths.instance(context);
    7.73 -        } else {
    7.74 -            // Reuse the Paths object as it stores the locations that
    7.75 -            // have been set with setLocation, etc.
    7.76 -            paths.setContext(context);
    7.77 -        }
    7.78  
    7.79          fsInfo = FSInfo.instance(context);
    7.80  
    7.81 @@ -179,7 +152,7 @@
    7.82  
    7.83      @Override
    7.84      public boolean isDefaultBootClassPath() {
    7.85 -        return paths.isDefaultBootClassPath();
    7.86 +        return locations.isDefaultBootClassPath();
    7.87      }
    7.88  
    7.89      public JavaFileObject getFileForInput(String name) {
    7.90 @@ -493,7 +466,7 @@
    7.91       */
    7.92      private Archive openArchive(File zipFileName, boolean useOptimizedZip) throws IOException {
    7.93          File origZipFileName = zipFileName;
    7.94 -        if (!ignoreSymbolFile && paths.isDefaultBootClassPathRtJar(zipFileName)) {
    7.95 +        if (!ignoreSymbolFile && locations.isDefaultBootClassPathRtJar(zipFileName)) {
    7.96              File file = zipFileName.getParentFile().getParentFile(); // ${java.home}
    7.97              if (new File(file.getName()).equals(new File("jre")))
    7.98                  file = file.getParentFile();
    7.99 @@ -780,7 +753,7 @@
   7.100          } else if (location == SOURCE_OUTPUT) {
   7.101              dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir());
   7.102          } else {
   7.103 -            Iterable<? extends File> path = paths.getPathForLocation(location);
   7.104 +            Iterable<? extends File> path = locations.getLocation(location);
   7.105              dir = null;
   7.106              for (File f: path) {
   7.107                  dir = f;
   7.108 @@ -815,64 +788,20 @@
   7.109          throws IOException
   7.110      {
   7.111          nullCheck(location);
   7.112 -        paths.lazy();
   7.113 -
   7.114 -        final File dir = location.isOutputLocation() ? getOutputDirectory(path) : null;
   7.115 -
   7.116 -        if (location == CLASS_OUTPUT)
   7.117 -            classOutDir = getOutputLocation(dir, D);
   7.118 -        else if (location == SOURCE_OUTPUT)
   7.119 -            sourceOutDir = getOutputLocation(dir, S);
   7.120 -        else
   7.121 -            paths.setPathForLocation(location, path);
   7.122 -    }
   7.123 -    // where
   7.124 -        private File getOutputDirectory(Iterable<? extends File> path) throws IOException {
   7.125 -            if (path == null)
   7.126 -                return null;
   7.127 -            Iterator<? extends File> pathIter = path.iterator();
   7.128 -            if (!pathIter.hasNext())
   7.129 -                throw new IllegalArgumentException("empty path for directory");
   7.130 -            File dir = pathIter.next();
   7.131 -            if (pathIter.hasNext())
   7.132 -                throw new IllegalArgumentException("path too long for directory");
   7.133 -            if (!dir.exists())
   7.134 -                throw new FileNotFoundException(dir + ": does not exist");
   7.135 -            else if (!dir.isDirectory())
   7.136 -                throw new IOException(dir + ": not a directory");
   7.137 -            return dir;
   7.138 -        }
   7.139 -
   7.140 -    private File getOutputLocation(File dir, OptionName defaultOptionName) {
   7.141 -        if (dir != null)
   7.142 -            return dir;
   7.143 -        String arg = options.get(defaultOptionName);
   7.144 -        if (arg == null)
   7.145 -            return null;
   7.146 -        return new File(arg);
   7.147 +        locations.setLocation(location, path);
   7.148      }
   7.149  
   7.150      public Iterable<? extends File> getLocation(Location location) {
   7.151          nullCheck(location);
   7.152 -        paths.lazy();
   7.153 -        if (location == CLASS_OUTPUT) {
   7.154 -            return (getClassOutDir() == null ? null : List.of(getClassOutDir()));
   7.155 -        } else if (location == SOURCE_OUTPUT) {
   7.156 -            return (getSourceOutDir() == null ? null : List.of(getSourceOutDir()));
   7.157 -        } else
   7.158 -            return paths.getPathForLocation(location);
   7.159 +        return locations.getLocation(location);
   7.160      }
   7.161  
   7.162      private File getClassOutDir() {
   7.163 -        if (classOutDir == uninited)
   7.164 -            classOutDir = getOutputLocation(null, D);
   7.165 -        return classOutDir;
   7.166 +        return locations.getOutputLocation(CLASS_OUTPUT);
   7.167      }
   7.168  
   7.169      private File getSourceOutDir() {
   7.170 -        if (sourceOutDir == uninited)
   7.171 -            sourceOutDir = getOutputLocation(null, S);
   7.172 -        return sourceOutDir;
   7.173 +        return locations.getOutputLocation(SOURCE_OUTPUT);
   7.174      }
   7.175  
   7.176      /**
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/share/classes/com/sun/tools/javac/file/Locations.java	Fri Oct 28 17:49:36 2011 -0700
     8.3 @@ -0,0 +1,771 @@
     8.4 +/*
     8.5 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
     8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.7 + *
     8.8 + * This code is free software; you can redistribute it and/or modify it
     8.9 + * under the terms of the GNU General Public License version 2 only, as
    8.10 + * published by the Free Software Foundation.  Oracle designates this
    8.11 + * particular file as subject to the "Classpath" exception as provided
    8.12 + * by Oracle in the LICENSE file that accompanied this code.
    8.13 + *
    8.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    8.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    8.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    8.17 + * version 2 for more details (a copy is included in the LICENSE file that
    8.18 + * accompanied this code).
    8.19 + *
    8.20 + * You should have received a copy of the GNU General Public License version
    8.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    8.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    8.23 + *
    8.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    8.25 + * or visit www.oracle.com if you need additional information or have any
    8.26 + * questions.
    8.27 + */
    8.28 +
    8.29 +package com.sun.tools.javac.file;
    8.30 +
    8.31 +import java.io.FileNotFoundException;
    8.32 +import java.util.Iterator;
    8.33 +import java.io.File;
    8.34 +import java.io.IOException;
    8.35 +import java.net.MalformedURLException;
    8.36 +import java.net.URL;
    8.37 +import java.util.Arrays;
    8.38 +import java.util.Collection;
    8.39 +import java.util.Collections;
    8.40 +import java.util.EnumMap;
    8.41 +import java.util.EnumSet;
    8.42 +import java.util.HashMap;
    8.43 +import java.util.HashSet;
    8.44 +import java.util.LinkedHashSet;
    8.45 +import java.util.Map;
    8.46 +import java.util.Set;
    8.47 +import java.util.StringTokenizer;
    8.48 +import java.util.zip.ZipFile;
    8.49 +import javax.tools.JavaFileManager.Location;
    8.50 +import javax.tools.StandardLocation;
    8.51 +
    8.52 +import com.sun.tools.javac.code.Lint;
    8.53 +import com.sun.tools.javac.main.OptionName;
    8.54 +import com.sun.tools.javac.util.ListBuffer;
    8.55 +import com.sun.tools.javac.util.Log;
    8.56 +import com.sun.tools.javac.util.Options;
    8.57 +
    8.58 +import javax.tools.JavaFileManager;
    8.59 +import static javax.tools.StandardLocation.*;
    8.60 +import static com.sun.tools.javac.main.OptionName.*;
    8.61 +
    8.62 +/** This class converts command line arguments, environment variables
    8.63 + *  and system properties (in File.pathSeparator-separated String form)
    8.64 + *  into a boot class path, user class path, and source path (in
    8.65 + *  Collection<String> form).
    8.66 + *
    8.67 + *  <p><b>This is NOT part of any supported API.
    8.68 + *  If you write code that depends on this, you do so at your own risk.
    8.69 + *  This code and its internal interfaces are subject to change or
    8.70 + *  deletion without notice.</b>
    8.71 + */
    8.72 +public class Locations {
    8.73 +
    8.74 +    /** The log to use for warning output */
    8.75 +    private Log log;
    8.76 +
    8.77 +    /** Collection of command-line options */
    8.78 +    private Options options;
    8.79 +
    8.80 +    /** Handler for -Xlint options */
    8.81 +    private Lint lint;
    8.82 +
    8.83 +    /** Access to (possibly cached) file info */
    8.84 +    private FSInfo fsInfo;
    8.85 +
    8.86 +    /** Whether to warn about non-existent path elements */
    8.87 +    private boolean warn;
    8.88 +
    8.89 +    // TODO: remove need for this
    8.90 +    private boolean inited = false; // TODO? caching bad?
    8.91 +
    8.92 +    public Locations() {
    8.93 +        initHandlers();
    8.94 +    }
    8.95 +
    8.96 +    public void update(Log log, Options options, Lint lint, FSInfo fsInfo) {
    8.97 +        this.log = log;
    8.98 +        this.options = options;
    8.99 +        this.lint = lint;
   8.100 +        this.fsInfo = fsInfo;
   8.101 +    }
   8.102 +
   8.103 +    public Collection<File> bootClassPath() {
   8.104 +        return getLocation(PLATFORM_CLASS_PATH);
   8.105 +    }
   8.106 +
   8.107 +    public boolean isDefaultBootClassPath() {
   8.108 +        BootClassPathLocationHandler h =
   8.109 +                (BootClassPathLocationHandler) getHandler(PLATFORM_CLASS_PATH);
   8.110 +        return h.isDefault();
   8.111 +    }
   8.112 +
   8.113 +    boolean isDefaultBootClassPathRtJar(File file) {
   8.114 +        BootClassPathLocationHandler h =
   8.115 +                (BootClassPathLocationHandler) getHandler(PLATFORM_CLASS_PATH);
   8.116 +        return h.isDefaultRtJar(file);
   8.117 +    }
   8.118 +
   8.119 +    public Collection<File> userClassPath() {
   8.120 +        return getLocation(CLASS_PATH);
   8.121 +    }
   8.122 +
   8.123 +    public Collection<File> sourcePath() {
   8.124 +        Collection<File> p = getLocation(SOURCE_PATH);
   8.125 +        // TODO: this should be handled by the LocationHandler
   8.126 +        return p == null || p.isEmpty() ? null : p;
   8.127 +    }
   8.128 +
   8.129 +    /**
   8.130 +     * Split a path into its elements. Empty path elements will be ignored.
   8.131 +     * @param path The path to be split
   8.132 +     * @return The elements of the path
   8.133 +     */
   8.134 +    private static Iterable<File> getPathEntries(String path) {
   8.135 +        return getPathEntries(path, null);
   8.136 +    }
   8.137 +
   8.138 +    /**
   8.139 +     * Split a path into its elements. If emptyPathDefault is not null, all
   8.140 +     * empty elements in the path, including empty elements at either end of
   8.141 +     * the path, will be replaced with the value of emptyPathDefault.
   8.142 +     * @param path The path to be split
   8.143 +     * @param emptyPathDefault The value to substitute for empty path elements,
   8.144 +     *  or null, to ignore empty path elements
   8.145 +     * @return The elements of the path
   8.146 +     */
   8.147 +    private static Iterable<File> getPathEntries(String path, File emptyPathDefault) {
   8.148 +        ListBuffer<File> entries = new ListBuffer<File>();
   8.149 +        int start = 0;
   8.150 +        while (start <= path.length()) {
   8.151 +            int sep = path.indexOf(File.pathSeparatorChar, start);
   8.152 +            if (sep == -1)
   8.153 +                sep = path.length();
   8.154 +            if (start < sep)
   8.155 +                entries.add(new File(path.substring(start, sep)));
   8.156 +            else if (emptyPathDefault != null)
   8.157 +                entries.add(emptyPathDefault);
   8.158 +            start = sep + 1;
   8.159 +        }
   8.160 +        return entries;
   8.161 +    }
   8.162 +
   8.163 +    /**
   8.164 +     * Utility class to help evaluate a path option.
   8.165 +     * Duplicate entries are ignored, jar class paths can be expanded.
   8.166 +     */
   8.167 +    private class Path extends LinkedHashSet<File> {
   8.168 +        private static final long serialVersionUID = 0;
   8.169 +
   8.170 +        private boolean expandJarClassPaths = false;
   8.171 +        private Set<File> canonicalValues = new HashSet<File>();
   8.172 +
   8.173 +        public Path expandJarClassPaths(boolean x) {
   8.174 +            expandJarClassPaths = x;
   8.175 +            return this;
   8.176 +        }
   8.177 +
   8.178 +        /** What to use when path element is the empty string */
   8.179 +        private File emptyPathDefault = null;
   8.180 +
   8.181 +        public Path emptyPathDefault(File x) {
   8.182 +            emptyPathDefault = x;
   8.183 +            return this;
   8.184 +        }
   8.185 +
   8.186 +        public Path() { super(); }
   8.187 +
   8.188 +        public Path addDirectories(String dirs, boolean warn) {
   8.189 +            boolean prev = expandJarClassPaths;
   8.190 +            expandJarClassPaths = true;
   8.191 +            try {
   8.192 +                if (dirs != null)
   8.193 +                    for (File dir : getPathEntries(dirs))
   8.194 +                        addDirectory(dir, warn);
   8.195 +                return this;
   8.196 +            } finally {
   8.197 +                expandJarClassPaths = prev;
   8.198 +            }
   8.199 +        }
   8.200 +
   8.201 +        public Path addDirectories(String dirs) {
   8.202 +            return addDirectories(dirs, warn);
   8.203 +        }
   8.204 +
   8.205 +        private void addDirectory(File dir, boolean warn) {
   8.206 +            if (!dir.isDirectory()) {
   8.207 +                if (warn)
   8.208 +                    log.warning(Lint.LintCategory.PATH,
   8.209 +                            "dir.path.element.not.found", dir);
   8.210 +                return;
   8.211 +            }
   8.212 +
   8.213 +            File[] files = dir.listFiles();
   8.214 +            if (files == null)
   8.215 +                return;
   8.216 +
   8.217 +            for (File direntry : files) {
   8.218 +                if (isArchive(direntry))
   8.219 +                    addFile(direntry, warn);
   8.220 +            }
   8.221 +        }
   8.222 +
   8.223 +        public Path addFiles(String files, boolean warn) {
   8.224 +            if (files != null) {
   8.225 +                addFiles(getPathEntries(files, emptyPathDefault), warn);
   8.226 +            }
   8.227 +            return this;
   8.228 +        }
   8.229 +
   8.230 +        public Path addFiles(String files) {
   8.231 +            return addFiles(files, warn);
   8.232 +        }
   8.233 +
   8.234 +        public Path addFiles(Iterable<? extends File> files, boolean warn) {
   8.235 +            if (files != null) {
   8.236 +                for (File file: files)
   8.237 +                    addFile(file, warn);
   8.238 +            }
   8.239 +            return this;
   8.240 +        }
   8.241 +
   8.242 +        public Path addFiles(Iterable<? extends File> files) {
   8.243 +            return addFiles(files, warn);
   8.244 +        }
   8.245 +
   8.246 +        public void addFile(File file, boolean warn) {
   8.247 +            if (contains(file)) {
   8.248 +                // discard duplicates
   8.249 +                return;
   8.250 +            }
   8.251 +
   8.252 +            if (! fsInfo.exists(file)) {
   8.253 +                /* No such file or directory exists */
   8.254 +                if (warn) {
   8.255 +                    log.warning(Lint.LintCategory.PATH,
   8.256 +                            "path.element.not.found", file);
   8.257 +                }
   8.258 +                super.add(file);
   8.259 +                return;
   8.260 +            }
   8.261 +
   8.262 +            File canonFile = fsInfo.getCanonicalFile(file);
   8.263 +            if (canonicalValues.contains(canonFile)) {
   8.264 +                /* Discard duplicates and avoid infinite recursion */
   8.265 +                return;
   8.266 +            }
   8.267 +
   8.268 +            if (fsInfo.isFile(file)) {
   8.269 +                /* File is an ordinary file. */
   8.270 +                if (!isArchive(file)) {
   8.271 +                    /* Not a recognized extension; open it to see if
   8.272 +                     it looks like a valid zip file. */
   8.273 +                    try {
   8.274 +                        ZipFile z = new ZipFile(file);
   8.275 +                        z.close();
   8.276 +                        if (warn) {
   8.277 +                            log.warning(Lint.LintCategory.PATH,
   8.278 +                                    "unexpected.archive.file", file);
   8.279 +                        }
   8.280 +                    } catch (IOException e) {
   8.281 +                        // FIXME: include e.getLocalizedMessage in warning
   8.282 +                        if (warn) {
   8.283 +                            log.warning(Lint.LintCategory.PATH,
   8.284 +                                    "invalid.archive.file", file);
   8.285 +                        }
   8.286 +                        return;
   8.287 +                    }
   8.288 +                }
   8.289 +            }
   8.290 +
   8.291 +            /* Now what we have left is either a directory or a file name
   8.292 +               conforming to archive naming convention */
   8.293 +            super.add(file);
   8.294 +            canonicalValues.add(canonFile);
   8.295 +
   8.296 +            if (expandJarClassPaths && fsInfo.isFile(file))
   8.297 +                addJarClassPath(file, warn);
   8.298 +        }
   8.299 +
   8.300 +        // Adds referenced classpath elements from a jar's Class-Path
   8.301 +        // Manifest entry.  In some future release, we may want to
   8.302 +        // update this code to recognize URLs rather than simple
   8.303 +        // filenames, but if we do, we should redo all path-related code.
   8.304 +        private void addJarClassPath(File jarFile, boolean warn) {
   8.305 +            try {
   8.306 +                for (File f: fsInfo.getJarClassPath(jarFile)) {
   8.307 +                    addFile(f, warn);
   8.308 +                }
   8.309 +            } catch (IOException e) {
   8.310 +                log.error("error.reading.file", jarFile, JavacFileManager.getMessage(e));
   8.311 +            }
   8.312 +        }
   8.313 +    }
   8.314 +
   8.315 +    /**
   8.316 +     * Base class for handling support for the representation of Locations.
   8.317 +     * Implementations are responsible for handling the interactions between
   8.318 +     * the command line options for a location, and API access via setLocation.
   8.319 +     * @see #initHandlers
   8.320 +     * @see #getHandler
   8.321 +     */
   8.322 +    protected abstract class LocationHandler {
   8.323 +        final Location location;
   8.324 +        final Set<OptionName> options;
   8.325 +
   8.326 +        /**
   8.327 +         * Create a handler. The location and options provide a way to map
   8.328 +         * from a location or an option to the corresponding handler.
   8.329 +         * @see #initHandlers
   8.330 +         */
   8.331 +        protected LocationHandler(Location location, OptionName... options) {
   8.332 +            this.location = location;
   8.333 +            this.options = options.length == 0 ?
   8.334 +                EnumSet.noneOf(OptionName.class):
   8.335 +                EnumSet.copyOf(Arrays.asList(options));
   8.336 +        }
   8.337 +
   8.338 +        // TODO: TEMPORARY, while Options still used for command line options
   8.339 +        void update(Options optionTable) {
   8.340 +            for (OptionName o: options) {
   8.341 +                String v = optionTable.get(o);
   8.342 +                if (v != null) {
   8.343 +                    handleOption(o, v);
   8.344 +                }
   8.345 +            }
   8.346 +        }
   8.347 +
   8.348 +        /** @see JavaFileManager#handleOption. */
   8.349 +        abstract boolean handleOption(OptionName option, String value);
   8.350 +        /** @see JavaFileManager#getLocation. */
   8.351 +        abstract Collection<File> getLocation();
   8.352 +        /** @see JavaFileManager#setLocation. */
   8.353 +        abstract void setLocation(Iterable<? extends File> files) throws IOException;
   8.354 +    }
   8.355 +
   8.356 +    /**
   8.357 +     * General purpose implementation for output locations,
   8.358 +     * such as -d/CLASS_OUTPUT and -s/SOURCE_OUTPUT.
   8.359 +     * All options are treated as equivalent (i.e. aliases.)
   8.360 +     * The value is a single file, possibly null.
   8.361 +     */
   8.362 +    private class OutputLocationHandler extends LocationHandler {
   8.363 +        private File outputDir;
   8.364 +
   8.365 +        OutputLocationHandler(Location location, OptionName... options) {
   8.366 +            super(location, options);
   8.367 +        }
   8.368 +
   8.369 +        @Override
   8.370 +        boolean handleOption(OptionName option, String value) {
   8.371 +            if (!options.contains(option))
   8.372 +                return false;
   8.373 +
   8.374 +            // TODO: could/should validate outputDir exists and is a directory
   8.375 +            // need to decide how best to report issue for benefit of
   8.376 +            // direct API call on JavaFileManager.handleOption(specifies IAE)
   8.377 +            // vs. command line decoding.
   8.378 +            outputDir = new File(value);
   8.379 +            return true;
   8.380 +        }
   8.381 +
   8.382 +        @Override
   8.383 +        Collection<File> getLocation() {
   8.384 +            return (outputDir == null) ? null : Collections.singleton(outputDir);
   8.385 +        }
   8.386 +
   8.387 +        @Override
   8.388 +        void setLocation(Iterable<? extends File> files) throws IOException {
   8.389 +            if (files == null) {
   8.390 +                outputDir = null;
   8.391 +            } else {
   8.392 +                Iterator<? extends File> pathIter = files.iterator();
   8.393 +                if (!pathIter.hasNext())
   8.394 +                    throw new IllegalArgumentException("empty path for directory");
   8.395 +                File dir = pathIter.next();
   8.396 +                if (pathIter.hasNext())
   8.397 +                    throw new IllegalArgumentException("path too long for directory");
   8.398 +                if (!dir.exists())
   8.399 +                    throw new FileNotFoundException(dir + ": does not exist");
   8.400 +                else if (!dir.isDirectory())
   8.401 +                    throw new IOException(dir + ": not a directory");
   8.402 +                outputDir = dir;
   8.403 +            }
   8.404 +        }
   8.405 +    }
   8.406 +
   8.407 +    /**
   8.408 +     * General purpose implementation for search path locations,
   8.409 +     * such as -sourcepath/SOURCE_PATH and -processorPath/ANNOTATION_PROCESS_PATH.
   8.410 +     * All options are treated as equivalent (i.e. aliases.)
   8.411 +     * The value is an ordered set of files and/or directories.
   8.412 +     */
   8.413 +    private class SimpleLocationHandler extends LocationHandler {
   8.414 +        protected Collection<File> searchPath;
   8.415 +
   8.416 +        SimpleLocationHandler(Location location, OptionName... options) {
   8.417 +            super(location, options);
   8.418 +        }
   8.419 +
   8.420 +        @Override
   8.421 +        boolean handleOption(OptionName option, String value) {
   8.422 +            if (!options.contains(option))
   8.423 +                return false;
   8.424 +            searchPath = value == null ? null :
   8.425 +                    Collections.unmodifiableCollection(computePath(value));
   8.426 +            return true;
   8.427 +        }
   8.428 +
   8.429 +        protected Path computePath(String value) {
   8.430 +            return new Path().addFiles(value);
   8.431 +        }
   8.432 +
   8.433 +        @Override
   8.434 +        Collection<File> getLocation() {
   8.435 +            return searchPath;
   8.436 +        }
   8.437 +
   8.438 +        @Override
   8.439 +        void setLocation(Iterable<? extends File> files) {
   8.440 +            Path p;
   8.441 +            if (files == null) {
   8.442 +                p = computePath(null);
   8.443 +            } else {
   8.444 +                p = new Path().addFiles(files);
   8.445 +            }
   8.446 +            searchPath = Collections.unmodifiableCollection(p);
   8.447 +        }
   8.448 +    }
   8.449 +
   8.450 +    /**
   8.451 +     * Subtype of SimpleLocationHandler for -classpath/CLASS_PATH.
   8.452 +     * If no value is given, a default is provided, based on system properties
   8.453 +     * and other values.
   8.454 +     */
   8.455 +    private class ClassPathLocationHandler extends SimpleLocationHandler {
   8.456 +        ClassPathLocationHandler() {
   8.457 +            super(StandardLocation.CLASS_PATH,
   8.458 +                    OptionName.CLASSPATH, OptionName.CP);
   8.459 +        }
   8.460 +
   8.461 +        @Override
   8.462 +        Collection<File> getLocation() {
   8.463 +            lazy();
   8.464 +            return searchPath;
   8.465 +        }
   8.466 +
   8.467 +        @Override
   8.468 +        protected Path computePath(String value) {
   8.469 +            String cp = value;
   8.470 +
   8.471 +            // CLASSPATH environment variable when run from `javac'.
   8.472 +            if (cp == null) cp = System.getProperty("env.class.path");
   8.473 +
   8.474 +            // If invoked via a java VM (not the javac launcher), use the
   8.475 +            // platform class path
   8.476 +            if (cp == null && System.getProperty("application.home") == null)
   8.477 +                cp = System.getProperty("java.class.path");
   8.478 +
   8.479 +            // Default to current working directory.
   8.480 +            if (cp == null) cp = ".";
   8.481 +
   8.482 +            return new Path()
   8.483 +                .expandJarClassPaths(true)        // Only search user jars for Class-Paths
   8.484 +                .emptyPathDefault(new File("."))  // Empty path elt ==> current directory
   8.485 +                .addFiles(cp);
   8.486 +            }
   8.487 +
   8.488 +        private void lazy() {
   8.489 +            if (searchPath == null)
   8.490 +                setLocation(null);
   8.491 +        }
   8.492 +    }
   8.493 +
   8.494 +    /**
   8.495 +     * Custom subtype of LocationHandler for PLATFORM_CLASS_PATH.
   8.496 +     * Various options are supported for different components of the
   8.497 +     * platform class path.
   8.498 +     * Setting a value with setLocation overrides all existing option values.
   8.499 +     * Setting any option overrides any value set with setLocation, and reverts
   8.500 +     * to using default values for options that have not been set.
   8.501 +     * Setting -bootclasspath or -Xbootclasspath overrides any existing
   8.502 +     * value for -Xbootclasspath/p: and -Xbootclasspath/a:.
   8.503 +     */
   8.504 +    private class BootClassPathLocationHandler extends LocationHandler {
   8.505 +        private Collection<File> searchPath;
   8.506 +        final Map<OptionName, String> optionValues = new EnumMap<OptionName,String>(OptionName.class);
   8.507 +
   8.508 +        /**
   8.509 +         * rt.jar as found on the default bootclasspath.
   8.510 +         * If the user specified a bootclasspath, null is used.
   8.511 +         */
   8.512 +        private File defaultBootClassPathRtJar = null;
   8.513 +
   8.514 +        /**
   8.515 +         *  Is bootclasspath the default?
   8.516 +         */
   8.517 +        private boolean isDefaultBootClassPath;
   8.518 +
   8.519 +        BootClassPathLocationHandler() {
   8.520 +            super(StandardLocation.PLATFORM_CLASS_PATH,
   8.521 +                    OptionName.BOOTCLASSPATH, OptionName.XBOOTCLASSPATH,
   8.522 +                    OptionName.XBOOTCLASSPATH_PREPEND,
   8.523 +                    OptionName.XBOOTCLASSPATH_APPEND,
   8.524 +                    OptionName.ENDORSEDDIRS, OptionName.DJAVA_ENDORSED_DIRS,
   8.525 +                    OptionName.EXTDIRS, OptionName.DJAVA_EXT_DIRS);
   8.526 +        }
   8.527 +
   8.528 +        boolean isDefault() {
   8.529 +            lazy();
   8.530 +            return isDefaultBootClassPath;
   8.531 +        }
   8.532 +
   8.533 +        boolean isDefaultRtJar(File file) {
   8.534 +            lazy();
   8.535 +            return file.equals(defaultBootClassPathRtJar);
   8.536 +        }
   8.537 +
   8.538 +        @Override
   8.539 +        boolean handleOption(OptionName option, String value) {
   8.540 +            if (!options.contains(option))
   8.541 +                return false;
   8.542 +
   8.543 +            option = canonicalize(option);
   8.544 +            optionValues.put(option, value);
   8.545 +            if (option == BOOTCLASSPATH) {
   8.546 +                optionValues.remove(XBOOTCLASSPATH_PREPEND);
   8.547 +                optionValues.remove(XBOOTCLASSPATH_APPEND);
   8.548 +            }
   8.549 +            searchPath = null;  // reset to "uninitialized"
   8.550 +            return true;
   8.551 +        }
   8.552 +        // where
   8.553 +            // TODO: would be better if option aliasing was handled at a higher
   8.554 +            // level
   8.555 +            private OptionName canonicalize(OptionName option) {
   8.556 +                switch (option) {
   8.557 +                    case XBOOTCLASSPATH:
   8.558 +                        return OptionName.BOOTCLASSPATH;
   8.559 +                    case DJAVA_ENDORSED_DIRS:
   8.560 +                        return OptionName.ENDORSEDDIRS;
   8.561 +                    case DJAVA_EXT_DIRS:
   8.562 +                        return OptionName.EXTDIRS;
   8.563 +                    default:
   8.564 +                        return option;
   8.565 +                }
   8.566 +            }
   8.567 +
   8.568 +        @Override
   8.569 +        Collection<File> getLocation() {
   8.570 +            lazy();
   8.571 +            return searchPath;
   8.572 +        }
   8.573 +
   8.574 +        @Override
   8.575 +        void setLocation(Iterable<? extends File> files) {
   8.576 +            if (files == null) {
   8.577 +                searchPath = null;  // reset to "uninitialized"
   8.578 +            } else {
   8.579 +                defaultBootClassPathRtJar = null;
   8.580 +                isDefaultBootClassPath = false;
   8.581 +                Path p = new Path().addFiles(files, false);
   8.582 +                searchPath = Collections.unmodifiableCollection(p);
   8.583 +                optionValues.clear();
   8.584 +            }
   8.585 +        }
   8.586 +
   8.587 +        Path computePath() {
   8.588 +            defaultBootClassPathRtJar = null;
   8.589 +            Path path = new Path();
   8.590 +
   8.591 +            String bootclasspathOpt = optionValues.get(BOOTCLASSPATH);
   8.592 +            String endorseddirsOpt = optionValues.get(ENDORSEDDIRS);
   8.593 +            String extdirsOpt = optionValues.get(EXTDIRS);
   8.594 +            String xbootclasspathPrependOpt = optionValues.get(XBOOTCLASSPATH_PREPEND);
   8.595 +            String xbootclasspathAppendOpt = optionValues.get(XBOOTCLASSPATH_APPEND);
   8.596 +
   8.597 +            path.addFiles(xbootclasspathPrependOpt);
   8.598 +
   8.599 +            if (endorseddirsOpt != null)
   8.600 +                path.addDirectories(endorseddirsOpt);
   8.601 +            else
   8.602 +                path.addDirectories(System.getProperty("java.endorsed.dirs"), false);
   8.603 +
   8.604 +            if (bootclasspathOpt != null) {
   8.605 +                path.addFiles(bootclasspathOpt);
   8.606 +            } else {
   8.607 +                // Standard system classes for this compiler's release.
   8.608 +                String files = System.getProperty("sun.boot.class.path");
   8.609 +                path.addFiles(files, false);
   8.610 +                File rt_jar = new File("rt.jar");
   8.611 +                for (File file : getPathEntries(files)) {
   8.612 +                    if (new File(file.getName()).equals(rt_jar))
   8.613 +                        defaultBootClassPathRtJar = file;
   8.614 +                }
   8.615 +            }
   8.616 +
   8.617 +            path.addFiles(xbootclasspathAppendOpt);
   8.618 +
   8.619 +            // Strictly speaking, standard extensions are not bootstrap
   8.620 +            // classes, but we treat them identically, so we'll pretend
   8.621 +            // that they are.
   8.622 +            if (extdirsOpt != null)
   8.623 +                path.addDirectories(extdirsOpt);
   8.624 +            else
   8.625 +                path.addDirectories(System.getProperty("java.ext.dirs"), false);
   8.626 +
   8.627 +            isDefaultBootClassPath =
   8.628 +                    (xbootclasspathPrependOpt == null) &&
   8.629 +                    (bootclasspathOpt == null) &&
   8.630 +                    (xbootclasspathAppendOpt == null);
   8.631 +
   8.632 +            return path;
   8.633 +        }
   8.634 +
   8.635 +        private void lazy() {
   8.636 +            if (searchPath == null)
   8.637 +                searchPath = Collections.unmodifiableCollection(computePath());
   8.638 +        }
   8.639 +    }
   8.640 +
   8.641 +    Map<Location, LocationHandler> handlersForLocation;
   8.642 +    Map<OptionName, LocationHandler> handlersForOption;
   8.643 +
   8.644 +    void initHandlers() {
   8.645 +        handlersForLocation = new HashMap<Location, LocationHandler>();
   8.646 +        handlersForOption = new EnumMap<OptionName, LocationHandler>(OptionName.class);
   8.647 +
   8.648 +        LocationHandler[] handlers = {
   8.649 +            new BootClassPathLocationHandler(),
   8.650 +            new ClassPathLocationHandler(),
   8.651 +            new SimpleLocationHandler(StandardLocation.SOURCE_PATH, OptionName.SOURCEPATH),
   8.652 +            new SimpleLocationHandler(StandardLocation.ANNOTATION_PROCESSOR_PATH, OptionName.PROCESSORPATH),
   8.653 +            new OutputLocationHandler((StandardLocation.CLASS_OUTPUT), OptionName.D),
   8.654 +            new OutputLocationHandler((StandardLocation.SOURCE_OUTPUT), OptionName.S)
   8.655 +        };
   8.656 +
   8.657 +        for (LocationHandler h: handlers) {
   8.658 +            handlersForLocation.put(h.location, h);
   8.659 +            for (OptionName o: h.options)
   8.660 +                handlersForOption.put(o, h);
   8.661 +        }
   8.662 +    }
   8.663 +
   8.664 +    boolean handleOption(OptionName option, String value) {
   8.665 +        LocationHandler h = handlersForOption.get(option);
   8.666 +        return (h == null ? false : h.handleOption(option, value));
   8.667 +    }
   8.668 +
   8.669 +    Collection<File> getLocation(Location location) {
   8.670 +        LocationHandler h = getHandler(location);
   8.671 +        return (h == null ? null : h.getLocation());
   8.672 +    }
   8.673 +
   8.674 +    File getOutputLocation(Location location) {
   8.675 +        if (!location.isOutputLocation())
   8.676 +            throw new IllegalArgumentException();
   8.677 +        LocationHandler h = getHandler(location);
   8.678 +        return ((OutputLocationHandler) h).outputDir;
   8.679 +    }
   8.680 +
   8.681 +    void setLocation(Location location, Iterable<? extends File> files) throws IOException {
   8.682 +        LocationHandler h = getHandler(location);
   8.683 +        if (h == null) {
   8.684 +            if (location.isOutputLocation())
   8.685 +                h = new OutputLocationHandler(location);
   8.686 +            else
   8.687 +                h = new SimpleLocationHandler(location);
   8.688 +            handlersForLocation.put(location, h);
   8.689 +        }
   8.690 +        h.setLocation(files);
   8.691 +    }
   8.692 +
   8.693 +    protected LocationHandler getHandler(Location location) {
   8.694 +        location.getClass(); // null check
   8.695 +        lazy();
   8.696 +        return handlersForLocation.get(location);
   8.697 +    }
   8.698 +
   8.699 +// TOGO
   8.700 +    protected void lazy() {
   8.701 +        if (!inited) {
   8.702 +            warn = lint.isEnabled(Lint.LintCategory.PATH);
   8.703 +
   8.704 +            for (LocationHandler h: handlersForLocation.values()) {
   8.705 +                h.update(options);
   8.706 +            }
   8.707 +
   8.708 +            inited = true;
   8.709 +        }
   8.710 +    }
   8.711 +
   8.712 +    /** Is this the name of an archive file? */
   8.713 +    private boolean isArchive(File file) {
   8.714 +        String n = file.getName().toLowerCase();
   8.715 +        return fsInfo.isFile(file)
   8.716 +            && (n.endsWith(".jar") || n.endsWith(".zip"));
   8.717 +    }
   8.718 +
   8.719 +    /**
   8.720 +     * Utility method for converting a search path string to an array
   8.721 +     * of directory and JAR file URLs.
   8.722 +     *
   8.723 +     * Note that this method is called by apt and the DocletInvoker.
   8.724 +     *
   8.725 +     * @param path the search path string
   8.726 +     * @return the resulting array of directory and JAR file URLs
   8.727 +     */
   8.728 +    public static URL[] pathToURLs(String path) {
   8.729 +        StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
   8.730 +        URL[] urls = new URL[st.countTokens()];
   8.731 +        int count = 0;
   8.732 +        while (st.hasMoreTokens()) {
   8.733 +            URL url = fileToURL(new File(st.nextToken()));
   8.734 +            if (url != null) {
   8.735 +                urls[count++] = url;
   8.736 +            }
   8.737 +        }
   8.738 +        if (urls.length != count) {
   8.739 +            URL[] tmp = new URL[count];
   8.740 +            System.arraycopy(urls, 0, tmp, 0, count);
   8.741 +            urls = tmp;
   8.742 +        }
   8.743 +        return urls;
   8.744 +    }
   8.745 +
   8.746 +    /**
   8.747 +     * Returns the directory or JAR file URL corresponding to the specified
   8.748 +     * local file name.
   8.749 +     *
   8.750 +     * @param file the File object
   8.751 +     * @return the resulting directory or JAR file URL, or null if unknown
   8.752 +     */
   8.753 +    private static URL fileToURL(File file) {
   8.754 +        String name;
   8.755 +        try {
   8.756 +            name = file.getCanonicalPath();
   8.757 +        } catch (IOException e) {
   8.758 +            name = file.getAbsolutePath();
   8.759 +        }
   8.760 +        name = name.replace(File.separatorChar, '/');
   8.761 +        if (!name.startsWith("/")) {
   8.762 +            name = "/" + name;
   8.763 +        }
   8.764 +        // If the file does not exist, then assume that it's a directory
   8.765 +        if (!file.isFile()) {
   8.766 +            name = name + "/";
   8.767 +        }
   8.768 +        try {
   8.769 +            return new URL("file", "", name);
   8.770 +        } catch (MalformedURLException e) {
   8.771 +            throw new IllegalArgumentException(file.toString());
   8.772 +        }
   8.773 +    }
   8.774 +}
     9.1 --- a/src/share/classes/com/sun/tools/javac/file/Paths.java	Thu Oct 27 13:54:50 2011 -0700
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,558 +0,0 @@
     9.4 -/*
     9.5 - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
     9.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.7 - *
     9.8 - * This code is free software; you can redistribute it and/or modify it
     9.9 - * under the terms of the GNU General Public License version 2 only, as
    9.10 - * published by the Free Software Foundation.  Oracle designates this
    9.11 - * particular file as subject to the "Classpath" exception as provided
    9.12 - * by Oracle in the LICENSE file that accompanied this code.
    9.13 - *
    9.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
    9.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    9.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    9.17 - * version 2 for more details (a copy is included in the LICENSE file that
    9.18 - * accompanied this code).
    9.19 - *
    9.20 - * You should have received a copy of the GNU General Public License version
    9.21 - * 2 along with this work; if not, write to the Free Software Foundation,
    9.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    9.23 - *
    9.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    9.25 - * or visit www.oracle.com if you need additional information or have any
    9.26 - * questions.
    9.27 - */
    9.28 -
    9.29 -package com.sun.tools.javac.file;
    9.30 -
    9.31 -import java.io.File;
    9.32 -import java.io.IOException;
    9.33 -import java.net.MalformedURLException;
    9.34 -import java.net.URL;
    9.35 -import java.util.HashMap;
    9.36 -import java.util.HashSet;
    9.37 -import java.util.Map;
    9.38 -import java.util.Set;
    9.39 -import java.util.Collection;
    9.40 -import java.util.Collections;
    9.41 -import java.util.LinkedHashSet;
    9.42 -import java.util.StringTokenizer;
    9.43 -import java.util.zip.ZipFile;
    9.44 -import javax.tools.JavaFileManager.Location;
    9.45 -
    9.46 -import com.sun.tools.javac.code.Lint;
    9.47 -import com.sun.tools.javac.util.Context;
    9.48 -import com.sun.tools.javac.util.ListBuffer;
    9.49 -import com.sun.tools.javac.util.Log;
    9.50 -import com.sun.tools.javac.util.Options;
    9.51 -
    9.52 -import static javax.tools.StandardLocation.*;
    9.53 -import static com.sun.tools.javac.main.OptionName.*;
    9.54 -
    9.55 -/** This class converts command line arguments, environment variables
    9.56 - *  and system properties (in File.pathSeparator-separated String form)
    9.57 - *  into a boot class path, user class path, and source path (in
    9.58 - *  Collection<String> form).
    9.59 - *
    9.60 - *  <p><b>This is NOT part of any supported API.
    9.61 - *  If you write code that depends on this, you do so at your own risk.
    9.62 - *  This code and its internal interfaces are subject to change or
    9.63 - *  deletion without notice.</b>
    9.64 - */
    9.65 -public class Paths {
    9.66 -
    9.67 -    /** The context key for the todo list */
    9.68 -    protected static final Context.Key<Paths> pathsKey =
    9.69 -        new Context.Key<Paths>();
    9.70 -
    9.71 -    /** Get the Paths instance for this context.
    9.72 -     *  @param context the context
    9.73 -     *  @return the Paths instance for this context
    9.74 -     */
    9.75 -    public static Paths instance(Context context) {
    9.76 -        Paths instance = context.get(pathsKey);
    9.77 -        if (instance == null)
    9.78 -            instance = new Paths(context);
    9.79 -        return instance;
    9.80 -    }
    9.81 -
    9.82 -    /** The log to use for warning output */
    9.83 -    private Log log;
    9.84 -
    9.85 -    /** Collection of command-line options */
    9.86 -    private Options options;
    9.87 -
    9.88 -    /** Handler for -Xlint options */
    9.89 -    private Lint lint;
    9.90 -
    9.91 -    /** Access to (possibly cached) file info */
    9.92 -    private FSInfo fsInfo;
    9.93 -
    9.94 -    protected Paths(Context context) {
    9.95 -        context.put(pathsKey, this);
    9.96 -        pathsForLocation = new HashMap<Location,Path>(16);
    9.97 -        setContext(context);
    9.98 -    }
    9.99 -
   9.100 -    void setContext(Context context) {
   9.101 -        log = Log.instance(context);
   9.102 -        options = Options.instance(context);
   9.103 -        lint = Lint.instance(context);
   9.104 -        fsInfo = FSInfo.instance(context);
   9.105 -    }
   9.106 -
   9.107 -    /** Whether to warn about non-existent path elements */
   9.108 -    private boolean warn;
   9.109 -
   9.110 -    private Map<Location, Path> pathsForLocation;
   9.111 -
   9.112 -    private boolean inited = false; // TODO? caching bad?
   9.113 -
   9.114 -    /**
   9.115 -     * rt.jar as found on the default bootclass path.  If the user specified a
   9.116 -     * bootclasspath, null is used.
   9.117 -     */
   9.118 -    private File defaultBootClassPathRtJar = null;
   9.119 -
   9.120 -    /**
   9.121 -     *  Is bootclasspath the default?
   9.122 -     */
   9.123 -    private boolean isDefaultBootClassPath;
   9.124 -
   9.125 -    Path getPathForLocation(Location location) {
   9.126 -        Path path = pathsForLocation.get(location);
   9.127 -        if (path == null)
   9.128 -            setPathForLocation(location, null);
   9.129 -        return pathsForLocation.get(location);
   9.130 -    }
   9.131 -
   9.132 -    void setPathForLocation(Location location, Iterable<? extends File> path) {
   9.133 -        // TODO? if (inited) throw new IllegalStateException
   9.134 -        // TODO: otherwise reset sourceSearchPath, classSearchPath as needed
   9.135 -        Path p;
   9.136 -        if (path == null) {
   9.137 -            if (location == CLASS_PATH)
   9.138 -                p = computeUserClassPath();
   9.139 -            else if (location == PLATFORM_CLASS_PATH)
   9.140 -                p = computeBootClassPath(); // sets isDefaultBootClassPath
   9.141 -            else if (location == ANNOTATION_PROCESSOR_PATH)
   9.142 -                p = computeAnnotationProcessorPath();
   9.143 -            else if (location == SOURCE_PATH)
   9.144 -                p = computeSourcePath();
   9.145 -            else
   9.146 -                // no defaults for other paths
   9.147 -                p = null;
   9.148 -        } else {
   9.149 -            if (location == PLATFORM_CLASS_PATH) {
   9.150 -                defaultBootClassPathRtJar = null;
   9.151 -                isDefaultBootClassPath = false;
   9.152 -            }
   9.153 -            p = new Path();
   9.154 -            for (File f: path)
   9.155 -                p.addFile(f, warn); // TODO: is use of warn appropriate?
   9.156 -        }
   9.157 -        pathsForLocation.put(location, p);
   9.158 -    }
   9.159 -
   9.160 -    public boolean isDefaultBootClassPath() {
   9.161 -        lazy();
   9.162 -        return isDefaultBootClassPath;
   9.163 -    }
   9.164 -
   9.165 -    protected void lazy() {
   9.166 -        if (!inited) {
   9.167 -            warn = lint.isEnabled(Lint.LintCategory.PATH);
   9.168 -
   9.169 -            pathsForLocation.put(PLATFORM_CLASS_PATH, computeBootClassPath());
   9.170 -            pathsForLocation.put(CLASS_PATH, computeUserClassPath());
   9.171 -            pathsForLocation.put(SOURCE_PATH, computeSourcePath());
   9.172 -
   9.173 -            inited = true;
   9.174 -        }
   9.175 -    }
   9.176 -
   9.177 -    public Collection<File> bootClassPath() {
   9.178 -        lazy();
   9.179 -        return Collections.unmodifiableCollection(getPathForLocation(PLATFORM_CLASS_PATH));
   9.180 -    }
   9.181 -    public Collection<File> userClassPath() {
   9.182 -        lazy();
   9.183 -        return Collections.unmodifiableCollection(getPathForLocation(CLASS_PATH));
   9.184 -    }
   9.185 -    public Collection<File> sourcePath() {
   9.186 -        lazy();
   9.187 -        Path p = getPathForLocation(SOURCE_PATH);
   9.188 -        return p == null || p.size() == 0
   9.189 -            ? null
   9.190 -            : Collections.unmodifiableCollection(p);
   9.191 -    }
   9.192 -
   9.193 -    boolean isDefaultBootClassPathRtJar(File file) {
   9.194 -        return file.equals(defaultBootClassPathRtJar);
   9.195 -    }
   9.196 -
   9.197 -    /**
   9.198 -     * Split a path into its elements. Empty path elements will be ignored.
   9.199 -     * @param path The path to be split
   9.200 -     * @return The elements of the path
   9.201 -     */
   9.202 -    private static Iterable<File> getPathEntries(String path) {
   9.203 -        return getPathEntries(path, null);
   9.204 -    }
   9.205 -
   9.206 -    /**
   9.207 -     * Split a path into its elements. If emptyPathDefault is not null, all
   9.208 -     * empty elements in the path, including empty elements at either end of
   9.209 -     * the path, will be replaced with the value of emptyPathDefault.
   9.210 -     * @param path The path to be split
   9.211 -     * @param emptyPathDefault The value to substitute for empty path elements,
   9.212 -     *  or null, to ignore empty path elements
   9.213 -     * @return The elements of the path
   9.214 -     */
   9.215 -    private static Iterable<File> getPathEntries(String path, File emptyPathDefault) {
   9.216 -        ListBuffer<File> entries = new ListBuffer<File>();
   9.217 -        int start = 0;
   9.218 -        while (start <= path.length()) {
   9.219 -            int sep = path.indexOf(File.pathSeparatorChar, start);
   9.220 -            if (sep == -1)
   9.221 -                sep = path.length();
   9.222 -            if (start < sep)
   9.223 -                entries.add(new File(path.substring(start, sep)));
   9.224 -            else if (emptyPathDefault != null)
   9.225 -                entries.add(emptyPathDefault);
   9.226 -            start = sep + 1;
   9.227 -        }
   9.228 -        return entries;
   9.229 -    }
   9.230 -
   9.231 -    private class Path extends LinkedHashSet<File> {
   9.232 -        private static final long serialVersionUID = 0;
   9.233 -
   9.234 -        private boolean expandJarClassPaths = false;
   9.235 -        private Set<File> canonicalValues = new HashSet<File>();
   9.236 -
   9.237 -        public Path expandJarClassPaths(boolean x) {
   9.238 -            expandJarClassPaths = x;
   9.239 -            return this;
   9.240 -        }
   9.241 -
   9.242 -        /** What to use when path element is the empty string */
   9.243 -        private File emptyPathDefault = null;
   9.244 -
   9.245 -        public Path emptyPathDefault(File x) {
   9.246 -            emptyPathDefault = x;
   9.247 -            return this;
   9.248 -        }
   9.249 -
   9.250 -        public Path() { super(); }
   9.251 -
   9.252 -        public Path addDirectories(String dirs, boolean warn) {
   9.253 -            boolean prev = expandJarClassPaths;
   9.254 -            expandJarClassPaths = true;
   9.255 -            try {
   9.256 -                if (dirs != null)
   9.257 -                    for (File dir : getPathEntries(dirs))
   9.258 -                        addDirectory(dir, warn);
   9.259 -                return this;
   9.260 -            } finally {
   9.261 -                expandJarClassPaths = prev;
   9.262 -            }
   9.263 -        }
   9.264 -
   9.265 -        public Path addDirectories(String dirs) {
   9.266 -            return addDirectories(dirs, warn);
   9.267 -        }
   9.268 -
   9.269 -        private void addDirectory(File dir, boolean warn) {
   9.270 -            if (!dir.isDirectory()) {
   9.271 -                if (warn)
   9.272 -                    log.warning(Lint.LintCategory.PATH,
   9.273 -                            "dir.path.element.not.found", dir);
   9.274 -                return;
   9.275 -            }
   9.276 -
   9.277 -            File[] files = dir.listFiles();
   9.278 -            if (files == null)
   9.279 -                return;
   9.280 -
   9.281 -            for (File direntry : files) {
   9.282 -                if (isArchive(direntry))
   9.283 -                    addFile(direntry, warn);
   9.284 -            }
   9.285 -        }
   9.286 -
   9.287 -        public Path addFiles(String files, boolean warn) {
   9.288 -            if (files != null) {
   9.289 -                for (File file : getPathEntries(files, emptyPathDefault))
   9.290 -                    addFile(file, warn);
   9.291 -            }
   9.292 -            return this;
   9.293 -        }
   9.294 -
   9.295 -        public Path addFiles(String files) {
   9.296 -            return addFiles(files, warn);
   9.297 -        }
   9.298 -
   9.299 -        public void addFile(File file, boolean warn) {
   9.300 -            if (contains(file)) {
   9.301 -                // discard duplicates
   9.302 -                return;
   9.303 -            }
   9.304 -
   9.305 -            if (! fsInfo.exists(file)) {
   9.306 -                /* No such file or directory exists */
   9.307 -                if (warn) {
   9.308 -                    log.warning(Lint.LintCategory.PATH,
   9.309 -                            "path.element.not.found", file);
   9.310 -                }
   9.311 -                super.add(file);
   9.312 -                return;
   9.313 -            }
   9.314 -
   9.315 -            File canonFile = fsInfo.getCanonicalFile(file);
   9.316 -            if (canonicalValues.contains(canonFile)) {
   9.317 -                /* Discard duplicates and avoid infinite recursion */
   9.318 -                return;
   9.319 -            }
   9.320 -
   9.321 -            if (fsInfo.isFile(file)) {
   9.322 -                /* File is an ordinary file. */
   9.323 -                if (!isArchive(file)) {
   9.324 -                    /* Not a recognized extension; open it to see if
   9.325 -                     it looks like a valid zip file. */
   9.326 -                    try {
   9.327 -                        ZipFile z = new ZipFile(file);
   9.328 -                        z.close();
   9.329 -                        if (warn) {
   9.330 -                            log.warning(Lint.LintCategory.PATH,
   9.331 -                                    "unexpected.archive.file", file);
   9.332 -                        }
   9.333 -                    } catch (IOException e) {
   9.334 -                        // FIXME: include e.getLocalizedMessage in warning
   9.335 -                        if (warn) {
   9.336 -                            log.warning(Lint.LintCategory.PATH,
   9.337 -                                    "invalid.archive.file", file);
   9.338 -                        }
   9.339 -                        return;
   9.340 -                    }
   9.341 -                }
   9.342 -            }
   9.343 -
   9.344 -            /* Now what we have left is either a directory or a file name
   9.345 -               conforming to archive naming convention */
   9.346 -            super.add(file);
   9.347 -            canonicalValues.add(canonFile);
   9.348 -
   9.349 -            if (expandJarClassPaths && fsInfo.isFile(file))
   9.350 -                addJarClassPath(file, warn);
   9.351 -        }
   9.352 -
   9.353 -        // Adds referenced classpath elements from a jar's Class-Path
   9.354 -        // Manifest entry.  In some future release, we may want to
   9.355 -        // update this code to recognize URLs rather than simple
   9.356 -        // filenames, but if we do, we should redo all path-related code.
   9.357 -        private void addJarClassPath(File jarFile, boolean warn) {
   9.358 -            try {
   9.359 -                for (File f: fsInfo.getJarClassPath(jarFile)) {
   9.360 -                    addFile(f, warn);
   9.361 -                }
   9.362 -            } catch (IOException e) {
   9.363 -                log.error("error.reading.file", jarFile, JavacFileManager.getMessage(e));
   9.364 -            }
   9.365 -        }
   9.366 -    }
   9.367 -
   9.368 -    private Path computeBootClassPath() {
   9.369 -        defaultBootClassPathRtJar = null;
   9.370 -        Path path = new Path();
   9.371 -
   9.372 -        String bootclasspathOpt = options.get(BOOTCLASSPATH);
   9.373 -        String endorseddirsOpt = options.get(ENDORSEDDIRS);
   9.374 -        String extdirsOpt = options.get(EXTDIRS);
   9.375 -        String xbootclasspathPrependOpt = options.get(XBOOTCLASSPATH_PREPEND);
   9.376 -        String xbootclasspathAppendOpt = options.get(XBOOTCLASSPATH_APPEND);
   9.377 -
   9.378 -        path.addFiles(xbootclasspathPrependOpt);
   9.379 -
   9.380 -        if (endorseddirsOpt != null)
   9.381 -            path.addDirectories(endorseddirsOpt);
   9.382 -        else
   9.383 -            path.addDirectories(System.getProperty("java.endorsed.dirs"), false);
   9.384 -
   9.385 -        if (bootclasspathOpt != null) {
   9.386 -            path.addFiles(bootclasspathOpt);
   9.387 -        } else {
   9.388 -            // Standard system classes for this compiler's release.
   9.389 -            String files = System.getProperty("sun.boot.class.path");
   9.390 -            path.addFiles(files, false);
   9.391 -            File rt_jar = new File("rt.jar");
   9.392 -            for (File file : getPathEntries(files)) {
   9.393 -                if (new File(file.getName()).equals(rt_jar))
   9.394 -                    defaultBootClassPathRtJar = file;
   9.395 -            }
   9.396 -        }
   9.397 -
   9.398 -        path.addFiles(xbootclasspathAppendOpt);
   9.399 -
   9.400 -        // Strictly speaking, standard extensions are not bootstrap
   9.401 -        // classes, but we treat them identically, so we'll pretend
   9.402 -        // that they are.
   9.403 -        if (extdirsOpt != null)
   9.404 -            path.addDirectories(extdirsOpt);
   9.405 -        else
   9.406 -            path.addDirectories(System.getProperty("java.ext.dirs"), false);
   9.407 -
   9.408 -        isDefaultBootClassPath =
   9.409 -                (xbootclasspathPrependOpt == null) &&
   9.410 -                (bootclasspathOpt == null) &&
   9.411 -                (xbootclasspathAppendOpt == null);
   9.412 -
   9.413 -        return path;
   9.414 -    }
   9.415 -
   9.416 -    private Path computeUserClassPath() {
   9.417 -        String cp = options.get(CLASSPATH);
   9.418 -
   9.419 -        // CLASSPATH environment variable when run from `javac'.
   9.420 -        if (cp == null) cp = System.getProperty("env.class.path");
   9.421 -
   9.422 -        // If invoked via a java VM (not the javac launcher), use the
   9.423 -        // platform class path
   9.424 -        if (cp == null && System.getProperty("application.home") == null)
   9.425 -            cp = System.getProperty("java.class.path");
   9.426 -
   9.427 -        // Default to current working directory.
   9.428 -        if (cp == null) cp = ".";
   9.429 -
   9.430 -        return new Path()
   9.431 -            .expandJarClassPaths(true)        // Only search user jars for Class-Paths
   9.432 -            .emptyPathDefault(new File("."))  // Empty path elt ==> current directory
   9.433 -            .addFiles(cp);
   9.434 -    }
   9.435 -
   9.436 -    private Path computeSourcePath() {
   9.437 -        String sourcePathArg = options.get(SOURCEPATH);
   9.438 -        if (sourcePathArg == null)
   9.439 -            return null;
   9.440 -
   9.441 -        return new Path().addFiles(sourcePathArg);
   9.442 -    }
   9.443 -
   9.444 -    private Path computeAnnotationProcessorPath() {
   9.445 -        String processorPathArg = options.get(PROCESSORPATH);
   9.446 -        if (processorPathArg == null)
   9.447 -            return null;
   9.448 -
   9.449 -        return new Path().addFiles(processorPathArg);
   9.450 -    }
   9.451 -
   9.452 -    /** The actual effective locations searched for sources */
   9.453 -    private Path sourceSearchPath;
   9.454 -
   9.455 -    public Collection<File> sourceSearchPath() {
   9.456 -        if (sourceSearchPath == null) {
   9.457 -            lazy();
   9.458 -            Path sourcePath = getPathForLocation(SOURCE_PATH);
   9.459 -            Path userClassPath = getPathForLocation(CLASS_PATH);
   9.460 -            sourceSearchPath = sourcePath != null ? sourcePath : userClassPath;
   9.461 -        }
   9.462 -        return Collections.unmodifiableCollection(sourceSearchPath);
   9.463 -    }
   9.464 -
   9.465 -    /** The actual effective locations searched for classes */
   9.466 -    private Path classSearchPath;
   9.467 -
   9.468 -    public Collection<File> classSearchPath() {
   9.469 -        if (classSearchPath == null) {
   9.470 -            lazy();
   9.471 -            Path bootClassPath = getPathForLocation(PLATFORM_CLASS_PATH);
   9.472 -            Path userClassPath = getPathForLocation(CLASS_PATH);
   9.473 -            classSearchPath = new Path();
   9.474 -            classSearchPath.addAll(bootClassPath);
   9.475 -            classSearchPath.addAll(userClassPath);
   9.476 -        }
   9.477 -        return Collections.unmodifiableCollection(classSearchPath);
   9.478 -    }
   9.479 -
   9.480 -    /** The actual effective locations for non-source, non-class files */
   9.481 -    private Path otherSearchPath;
   9.482 -
   9.483 -    Collection<File> otherSearchPath() {
   9.484 -        if (otherSearchPath == null) {
   9.485 -            lazy();
   9.486 -            Path userClassPath = getPathForLocation(CLASS_PATH);
   9.487 -            Path sourcePath = getPathForLocation(SOURCE_PATH);
   9.488 -            if (sourcePath == null)
   9.489 -                otherSearchPath = userClassPath;
   9.490 -            else {
   9.491 -                otherSearchPath = new Path();
   9.492 -                otherSearchPath.addAll(userClassPath);
   9.493 -                otherSearchPath.addAll(sourcePath);
   9.494 -            }
   9.495 -        }
   9.496 -        return Collections.unmodifiableCollection(otherSearchPath);
   9.497 -    }
   9.498 -
   9.499 -    /** Is this the name of an archive file? */
   9.500 -    private boolean isArchive(File file) {
   9.501 -        String n = file.getName().toLowerCase();
   9.502 -        return fsInfo.isFile(file)
   9.503 -            && (n.endsWith(".jar") || n.endsWith(".zip"));
   9.504 -    }
   9.505 -
   9.506 -    /**
   9.507 -     * Utility method for converting a search path string to an array
   9.508 -     * of directory and JAR file URLs.
   9.509 -     *
   9.510 -     * Note that this method is called by apt and the DocletInvoker.
   9.511 -     *
   9.512 -     * @param path the search path string
   9.513 -     * @return the resulting array of directory and JAR file URLs
   9.514 -     */
   9.515 -    public static URL[] pathToURLs(String path) {
   9.516 -        StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
   9.517 -        URL[] urls = new URL[st.countTokens()];
   9.518 -        int count = 0;
   9.519 -        while (st.hasMoreTokens()) {
   9.520 -            URL url = fileToURL(new File(st.nextToken()));
   9.521 -            if (url != null) {
   9.522 -                urls[count++] = url;
   9.523 -            }
   9.524 -        }
   9.525 -        if (urls.length != count) {
   9.526 -            URL[] tmp = new URL[count];
   9.527 -            System.arraycopy(urls, 0, tmp, 0, count);
   9.528 -            urls = tmp;
   9.529 -        }
   9.530 -        return urls;
   9.531 -    }
   9.532 -
   9.533 -    /**
   9.534 -     * Returns the directory or JAR file URL corresponding to the specified
   9.535 -     * local file name.
   9.536 -     *
   9.537 -     * @param file the File object
   9.538 -     * @return the resulting directory or JAR file URL, or null if unknown
   9.539 -     */
   9.540 -    private static URL fileToURL(File file) {
   9.541 -        String name;
   9.542 -        try {
   9.543 -            name = file.getCanonicalPath();
   9.544 -        } catch (IOException e) {
   9.545 -            name = file.getAbsolutePath();
   9.546 -        }
   9.547 -        name = name.replace(File.separatorChar, '/');
   9.548 -        if (!name.startsWith("/")) {
   9.549 -            name = "/" + name;
   9.550 -        }
   9.551 -        // If the file does not exist, then assume that it's a directory
   9.552 -        if (!file.isFile()) {
   9.553 -            name = name + "/";
   9.554 -        }
   9.555 -        try {
   9.556 -            return new URL("file", "", name);
   9.557 -        } catch (MalformedURLException e) {
   9.558 -            throw new IllegalArgumentException(file.toString());
   9.559 -        }
   9.560 -    }
   9.561 -}
    10.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Code.java	Thu Oct 27 13:54:50 2011 -0700
    10.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java	Fri Oct 28 17:49:36 2011 -0700
    10.3 @@ -1542,7 +1542,28 @@
    10.4       */
    10.5      public void addCatch(
    10.6          char startPc, char endPc, char handlerPc, char catchType) {
    10.7 -        catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});
    10.8 +            catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});
    10.9 +        }
   10.10 +
   10.11 +
   10.12 +    public void compressCatchTable() {
   10.13 +        ListBuffer<char[]> compressedCatchInfo = ListBuffer.lb();
   10.14 +        List<Integer> handlerPcs = List.nil();
   10.15 +        for (char[] catchEntry : catchInfo.elems) {
   10.16 +            handlerPcs = handlerPcs.prepend((int)catchEntry[2]);
   10.17 +        }
   10.18 +        for (char[] catchEntry : catchInfo.elems) {
   10.19 +            int startpc = catchEntry[0];
   10.20 +            int endpc = catchEntry[1];
   10.21 +            if (startpc == endpc ||
   10.22 +                    (startpc == (endpc - 1) &&
   10.23 +                    handlerPcs.contains(startpc))) {
   10.24 +                continue;
   10.25 +            } else {
   10.26 +                compressedCatchInfo.append(catchEntry);
   10.27 +            }
   10.28 +        }
   10.29 +        catchInfo = compressedCatchInfo;
   10.30      }
   10.31  
   10.32  
    11.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Thu Oct 27 13:54:50 2011 -0700
    11.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Fri Oct 28 17:49:36 2011 -0700
    11.3 @@ -959,6 +959,9 @@
    11.4                      code.lastFrame = null;
    11.5                      code.frameBeforeLast = null;
    11.6                  }
    11.7 +
    11.8 +                //compress exception table
    11.9 +                code.compressCatchTable();
   11.10              }
   11.11          }
   11.12  
   11.13 @@ -1437,7 +1440,6 @@
   11.14                      code.markDead();
   11.15                  }
   11.16              }
   11.17 -
   11.18              // Resolve all breaks.
   11.19              code.resolve(exitChain);
   11.20  
   11.21 @@ -1496,23 +1498,21 @@
   11.22          void registerCatch(DiagnosticPosition pos,
   11.23                             int startpc, int endpc,
   11.24                             int handler_pc, int catch_type) {
   11.25 -            if (startpc != endpc) {
   11.26 -                char startpc1 = (char)startpc;
   11.27 -                char endpc1 = (char)endpc;
   11.28 -                char handler_pc1 = (char)handler_pc;
   11.29 -                if (startpc1 == startpc &&
   11.30 -                    endpc1 == endpc &&
   11.31 -                    handler_pc1 == handler_pc) {
   11.32 -                    code.addCatch(startpc1, endpc1, handler_pc1,
   11.33 -                                  (char)catch_type);
   11.34 +            char startpc1 = (char)startpc;
   11.35 +            char endpc1 = (char)endpc;
   11.36 +            char handler_pc1 = (char)handler_pc;
   11.37 +            if (startpc1 == startpc &&
   11.38 +                endpc1 == endpc &&
   11.39 +                handler_pc1 == handler_pc) {
   11.40 +                code.addCatch(startpc1, endpc1, handler_pc1,
   11.41 +                              (char)catch_type);
   11.42 +            } else {
   11.43 +                if (!useJsrLocally && !target.generateStackMapTable()) {
   11.44 +                    useJsrLocally = true;
   11.45 +                    throw new CodeSizeOverflow();
   11.46                  } else {
   11.47 -                    if (!useJsrLocally && !target.generateStackMapTable()) {
   11.48 -                        useJsrLocally = true;
   11.49 -                        throw new CodeSizeOverflow();
   11.50 -                    } else {
   11.51 -                        log.error(pos, "limit.code.too.large.for.try.stmt");
   11.52 -                        nerrs++;
   11.53 -                    }
   11.54 +                    log.error(pos, "limit.code.too.large.for.try.stmt");
   11.55 +                    nerrs++;
   11.56                  }
   11.57              }
   11.58          }
    12.1 --- a/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java	Thu Oct 27 13:54:50 2011 -0700
    12.2 +++ b/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java	Fri Oct 28 17:49:36 2011 -0700
    12.3 @@ -25,9 +25,7 @@
    12.4  
    12.5  package com.sun.tools.javac.nio;
    12.6  
    12.7 -
    12.8  import java.io.File;
    12.9 -import java.io.FileNotFoundException;
   12.10  import java.io.IOException;
   12.11  import java.net.MalformedURLException;
   12.12  import java.net.URL;
   12.13 @@ -60,7 +58,6 @@
   12.14  import static java.nio.file.FileVisitOption.*;
   12.15  import static javax.tools.StandardLocation.*;
   12.16  
   12.17 -import com.sun.tools.javac.file.Paths;
   12.18  import com.sun.tools.javac.util.BaseFileManager;
   12.19  import com.sun.tools.javac.util.Context;
   12.20  import com.sun.tools.javac.util.List;
   12.21 @@ -125,9 +122,8 @@
   12.22       * Set the context for JavacPathFileManager.
   12.23       */
   12.24      @Override
   12.25 -    protected void setContext(Context context) {
   12.26 +    public void setContext(Context context) {
   12.27          super.setContext(context);
   12.28 -        searchPaths = Paths.instance(context);
   12.29      }
   12.30  
   12.31      @Override
   12.32 @@ -173,7 +169,7 @@
   12.33  
   12.34      @Override
   12.35      public boolean isDefaultBootClassPath() {
   12.36 -        return searchPaths.isDefaultBootClassPath();
   12.37 +        return locations.isDefaultBootClassPath();
   12.38      }
   12.39  
   12.40      // <editor-fold defaultstate="collapsed" desc="Location handling">
   12.41 @@ -231,13 +227,13 @@
   12.42          if (locn instanceof StandardLocation) {
   12.43              switch ((StandardLocation) locn) {
   12.44                  case CLASS_PATH:
   12.45 -                    files = searchPaths.userClassPath();
   12.46 +                    files = locations.userClassPath();
   12.47                      break;
   12.48                  case PLATFORM_CLASS_PATH:
   12.49 -                    files = searchPaths.bootClassPath();
   12.50 +                    files = locations.bootClassPath();
   12.51                      break;
   12.52                  case SOURCE_PATH:
   12.53 -                    files = searchPaths.sourcePath();
   12.54 +                    files = locations.sourcePath();
   12.55                      break;
   12.56                  case CLASS_OUTPUT: {
   12.57                      String arg = options.get(D);
   12.58 @@ -272,7 +268,6 @@
   12.59          private boolean inited = false;
   12.60  
   12.61      private Map<Location, PathsForLocation> pathsForLocation;
   12.62 -    private Paths searchPaths;
   12.63  
   12.64      private static class PathsForLocation extends LinkedHashSet<Path> {
   12.65          private static final long serialVersionUID = 6788510222394486733L;
    13.1 --- a/src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java	Thu Oct 27 13:54:50 2011 -0700
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,420 +0,0 @@
    13.4 -/*
    13.5 - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
    13.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.7 - *
    13.8 - * This code is free software; you can redistribute it and/or modify it
    13.9 - * under the terms of the GNU General Public License version 2 only, as
   13.10 - * published by the Free Software Foundation.  Oracle designates this
   13.11 - * particular file as subject to the "Classpath" exception as provided
   13.12 - * by Oracle in the LICENSE file that accompanied this code.
   13.13 - *
   13.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
   13.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13.17 - * version 2 for more details (a copy is included in the LICENSE file that
   13.18 - * accompanied this code).
   13.19 - *
   13.20 - * You should have received a copy of the GNU General Public License version
   13.21 - * 2 along with this work; if not, write to the Free Software Foundation,
   13.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   13.23 - *
   13.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   13.25 - * or visit www.oracle.com if you need additional information or have any
   13.26 - * questions.
   13.27 - */
   13.28 -
   13.29 -package com.sun.tools.javac.parser;
   13.30 -
   13.31 -import java.nio.*;
   13.32 -
   13.33 -import com.sun.tools.javac.util.*;
   13.34 -import static com.sun.tools.javac.util.LayoutCharacters.*;
   13.35 -
   13.36 -/** An extension to the base lexical analyzer that captures
   13.37 - *  and processes the contents of doc comments.  It does so by
   13.38 - *  translating Unicode escape sequences and by stripping the
   13.39 - *  leading whitespace and starts from each line of the comment.
   13.40 - *
   13.41 - *  <p><b>This is NOT part of any supported API.
   13.42 - *  If you write code that depends on this, you do so at your own risk.
   13.43 - *  This code and its internal interfaces are subject to change or
   13.44 - *  deletion without notice.</b>
   13.45 - */
   13.46 -public class DocCommentScanner extends Scanner {
   13.47 -
   13.48 -    /** Create a scanner from the input buffer.  buffer must implement
   13.49 -     *  array() and compact(), and remaining() must be less than limit().
   13.50 -     */
   13.51 -    protected DocCommentScanner(ScannerFactory fac, CharBuffer buffer) {
   13.52 -        super(fac, buffer);
   13.53 -    }
   13.54 -
   13.55 -    /** Create a scanner from the input array.  The array must have at
   13.56 -     *  least a single character of extra space.
   13.57 -     */
   13.58 -    protected DocCommentScanner(ScannerFactory fac, char[] input, int inputLength) {
   13.59 -        super(fac, input, inputLength);
   13.60 -    }
   13.61 -
   13.62 -    /** Starting position of the comment in original source
   13.63 -     */
   13.64 -    private int pos;
   13.65 -
   13.66 -    /** The comment input buffer, index of next chacter to be read,
   13.67 -     *  index of one past last character in buffer.
   13.68 -     */
   13.69 -    private char[] buf;
   13.70 -    private int bp;
   13.71 -    private int buflen;
   13.72 -
   13.73 -    /** The current character.
   13.74 -     */
   13.75 -    private char ch;
   13.76 -
   13.77 -    /** The column number position of the current character.
   13.78 -     */
   13.79 -    private int col;
   13.80 -
   13.81 -    /** The buffer index of the last converted Unicode character
   13.82 -     */
   13.83 -    private int unicodeConversionBp = 0;
   13.84 -
   13.85 -    /**
   13.86 -     * Buffer for doc comment.
   13.87 -     */
   13.88 -    private char[] docCommentBuffer = new char[1024];
   13.89 -
   13.90 -    /**
   13.91 -     * Number of characters in doc comment buffer.
   13.92 -     */
   13.93 -    private int docCommentCount;
   13.94 -
   13.95 -    /**
   13.96 -     * Translated and stripped contents of doc comment
   13.97 -     */
   13.98 -    private String docComment = null;
   13.99 -
  13.100 -
  13.101 -    /** Unconditionally expand the comment buffer.
  13.102 -     */
  13.103 -    private void expandCommentBuffer() {
  13.104 -        char[] newBuffer = new char[docCommentBuffer.length * 2];
  13.105 -        System.arraycopy(docCommentBuffer, 0, newBuffer,
  13.106 -                         0, docCommentBuffer.length);
  13.107 -        docCommentBuffer = newBuffer;
  13.108 -    }
  13.109 -
  13.110 -    /** Convert an ASCII digit from its base (8, 10, or 16)
  13.111 -     *  to its value.
  13.112 -     */
  13.113 -    private int digit(int base) {
  13.114 -        char c = ch;
  13.115 -        int result = Character.digit(c, base);
  13.116 -        if (result >= 0 && c > 0x7f) {
  13.117 -            ch = "0123456789abcdef".charAt(result);
  13.118 -        }
  13.119 -        return result;
  13.120 -    }
  13.121 -
  13.122 -    /** Convert Unicode escape; bp points to initial '\' character
  13.123 -     *  (Spec 3.3).
  13.124 -     */
  13.125 -    private void convertUnicode() {
  13.126 -        if (ch == '\\' && unicodeConversionBp != bp) {
  13.127 -            bp++; ch = buf[bp]; col++;
  13.128 -            if (ch == 'u') {
  13.129 -                do {
  13.130 -                    bp++; ch = buf[bp]; col++;
  13.131 -                } while (ch == 'u');
  13.132 -                int limit = bp + 3;
  13.133 -                if (limit < buflen) {
  13.134 -                    int d = digit(16);
  13.135 -                    int code = d;
  13.136 -                    while (bp < limit && d >= 0) {
  13.137 -                        bp++; ch = buf[bp]; col++;
  13.138 -                        d = digit(16);
  13.139 -                        code = (code << 4) + d;
  13.140 -                    }
  13.141 -                    if (d >= 0) {
  13.142 -                        ch = (char)code;
  13.143 -                        unicodeConversionBp = bp;
  13.144 -                        return;
  13.145 -                    }
  13.146 -                }
  13.147 -                // "illegal.Unicode.esc", reported by base scanner
  13.148 -            } else {
  13.149 -                bp--;
  13.150 -                ch = '\\';
  13.151 -                col--;
  13.152 -            }
  13.153 -        }
  13.154 -    }
  13.155 -
  13.156 -
  13.157 -    /** Read next character.
  13.158 -     */
  13.159 -    private void scanChar() {
  13.160 -        bp++;
  13.161 -        ch = buf[bp];
  13.162 -        switch (ch) {
  13.163 -        case '\r': // return
  13.164 -            col = 0;
  13.165 -            break;
  13.166 -        case '\n': // newline
  13.167 -            if (bp == 0 || buf[bp-1] != '\r') {
  13.168 -                col = 0;
  13.169 -            }
  13.170 -            break;
  13.171 -        case '\t': // tab
  13.172 -            col = (col / TabInc * TabInc) + TabInc;
  13.173 -            break;
  13.174 -        case '\\': // possible Unicode
  13.175 -            col++;
  13.176 -            convertUnicode();
  13.177 -            break;
  13.178 -        default:
  13.179 -            col++;
  13.180 -            break;
  13.181 -        }
  13.182 -    }
  13.183 -
  13.184 -    /**
  13.185 -     * Read next character in doc comment, skipping over double '\' characters.
  13.186 -     * If a double '\' is skipped, put in the buffer and update buffer count.
  13.187 -     */
  13.188 -    private void scanDocCommentChar() {
  13.189 -        scanChar();
  13.190 -        if (ch == '\\') {
  13.191 -            if (buf[bp+1] == '\\' && unicodeConversionBp != bp) {
  13.192 -                if (docCommentCount == docCommentBuffer.length)
  13.193 -                    expandCommentBuffer();
  13.194 -                docCommentBuffer[docCommentCount++] = ch;
  13.195 -                bp++; col++;
  13.196 -            } else {
  13.197 -                convertUnicode();
  13.198 -            }
  13.199 -        }
  13.200 -    }
  13.201 -
  13.202 -    /* Reset doc comment before reading each new token
  13.203 -     */
  13.204 -    public void nextToken() {
  13.205 -        docComment = null;
  13.206 -        super.nextToken();
  13.207 -    }
  13.208 -
  13.209 -    /**
  13.210 -     * Returns the documentation string of the current token.
  13.211 -     */
  13.212 -    public String docComment() {
  13.213 -        return docComment;
  13.214 -    }
  13.215 -
  13.216 -    /**
  13.217 -     * Process a doc comment and make the string content available.
  13.218 -     * Strips leading whitespace and stars.
  13.219 -     */
  13.220 -    @SuppressWarnings("fallthrough")
  13.221 -    protected void processComment(CommentStyle style) {
  13.222 -        if (style != CommentStyle.JAVADOC) {
  13.223 -            return;
  13.224 -        }
  13.225 -
  13.226 -        pos = pos();
  13.227 -        buf = getRawCharacters(pos, endPos());
  13.228 -        buflen = buf.length;
  13.229 -        bp = 0;
  13.230 -        col = 0;
  13.231 -
  13.232 -        docCommentCount = 0;
  13.233 -
  13.234 -        boolean firstLine = true;
  13.235 -
  13.236 -        // Skip over first slash
  13.237 -        scanDocCommentChar();
  13.238 -        // Skip over first star
  13.239 -        scanDocCommentChar();
  13.240 -
  13.241 -        // consume any number of stars
  13.242 -        while (bp < buflen && ch == '*') {
  13.243 -            scanDocCommentChar();
  13.244 -        }
  13.245 -        // is the comment in the form /**/, /***/, /****/, etc. ?
  13.246 -        if (bp < buflen && ch == '/') {
  13.247 -            docComment = "";
  13.248 -            return;
  13.249 -        }
  13.250 -
  13.251 -        // skip a newline on the first line of the comment.
  13.252 -        if (bp < buflen) {
  13.253 -            if (ch == LF) {
  13.254 -                scanDocCommentChar();
  13.255 -                firstLine = false;
  13.256 -            } else if (ch == CR) {
  13.257 -                scanDocCommentChar();
  13.258 -                if (ch == LF) {
  13.259 -                    scanDocCommentChar();
  13.260 -                    firstLine = false;
  13.261 -                }
  13.262 -            }
  13.263 -        }
  13.264 -
  13.265 -    outerLoop:
  13.266 -
  13.267 -        // The outerLoop processes the doc comment, looping once
  13.268 -        // for each line.  For each line, it first strips off
  13.269 -        // whitespace, then it consumes any stars, then it
  13.270 -        // puts the rest of the line into our buffer.
  13.271 -        while (bp < buflen) {
  13.272 -
  13.273 -            // The wsLoop consumes whitespace from the beginning
  13.274 -            // of each line.
  13.275 -        wsLoop:
  13.276 -
  13.277 -            while (bp < buflen) {
  13.278 -                switch(ch) {
  13.279 -                case ' ':
  13.280 -                    scanDocCommentChar();
  13.281 -                    break;
  13.282 -                case '\t':
  13.283 -                    col = ((col - 1) / TabInc * TabInc) + TabInc;
  13.284 -                    scanDocCommentChar();
  13.285 -                    break;
  13.286 -                case FF:
  13.287 -                    col = 0;
  13.288 -                    scanDocCommentChar();
  13.289 -                    break;
  13.290 -// Treat newline at beginning of line (blank line, no star)
  13.291 -// as comment text.  Old Javadoc compatibility requires this.
  13.292 -/*---------------------------------*
  13.293 -                case CR: // (Spec 3.4)
  13.294 -                    scanDocCommentChar();
  13.295 -                    if (ch == LF) {
  13.296 -                        col = 0;
  13.297 -                        scanDocCommentChar();
  13.298 -                    }
  13.299 -                    break;
  13.300 -                case LF: // (Spec 3.4)
  13.301 -                    scanDocCommentChar();
  13.302 -                    break;
  13.303 -*---------------------------------*/
  13.304 -                default:
  13.305 -                    // we've seen something that isn't whitespace;
  13.306 -                    // jump out.
  13.307 -                    break wsLoop;
  13.308 -                }
  13.309 -            }
  13.310 -
  13.311 -            // Are there stars here?  If so, consume them all
  13.312 -            // and check for the end of comment.
  13.313 -            if (ch == '*') {
  13.314 -                // skip all of the stars
  13.315 -                do {
  13.316 -                    scanDocCommentChar();
  13.317 -                } while (ch == '*');
  13.318 -
  13.319 -                // check for the closing slash.
  13.320 -                if (ch == '/') {
  13.321 -                    // We're done with the doc comment
  13.322 -                    // scanChar() and breakout.
  13.323 -                    break outerLoop;
  13.324 -                }
  13.325 -            } else if (! firstLine) {
  13.326 -                //The current line does not begin with a '*' so we will indent it.
  13.327 -                for (int i = 1; i < col; i++) {
  13.328 -                    if (docCommentCount == docCommentBuffer.length)
  13.329 -                        expandCommentBuffer();
  13.330 -                    docCommentBuffer[docCommentCount++] = ' ';
  13.331 -                }
  13.332 -            }
  13.333 -
  13.334 -            // The textLoop processes the rest of the characters
  13.335 -            // on the line, adding them to our buffer.
  13.336 -        textLoop:
  13.337 -            while (bp < buflen) {
  13.338 -                switch (ch) {
  13.339 -                case '*':
  13.340 -                    // Is this just a star?  Or is this the
  13.341 -                    // end of a comment?
  13.342 -                    scanDocCommentChar();
  13.343 -                    if (ch == '/') {
  13.344 -                        // This is the end of the comment,
  13.345 -                        // set ch and return our buffer.
  13.346 -                        break outerLoop;
  13.347 -                    }
  13.348 -                    // This is just an ordinary star.  Add it to
  13.349 -                    // the buffer.
  13.350 -                    if (docCommentCount == docCommentBuffer.length)
  13.351 -                        expandCommentBuffer();
  13.352 -                    docCommentBuffer[docCommentCount++] = '*';
  13.353 -                    break;
  13.354 -                case ' ':
  13.355 -                case '\t':
  13.356 -                    if (docCommentCount == docCommentBuffer.length)
  13.357 -                        expandCommentBuffer();
  13.358 -                    docCommentBuffer[docCommentCount++] = ch;
  13.359 -                    scanDocCommentChar();
  13.360 -                    break;
  13.361 -                case FF:
  13.362 -                    scanDocCommentChar();
  13.363 -                    break textLoop; // treat as end of line
  13.364 -                case CR: // (Spec 3.4)
  13.365 -                    scanDocCommentChar();
  13.366 -                    if (ch != LF) {
  13.367 -                        // Canonicalize CR-only line terminator to LF
  13.368 -                        if (docCommentCount == docCommentBuffer.length)
  13.369 -                            expandCommentBuffer();
  13.370 -                        docCommentBuffer[docCommentCount++] = (char)LF;
  13.371 -                        break textLoop;
  13.372 -                    }
  13.373 -                    /* fall through to LF case */
  13.374 -                case LF: // (Spec 3.4)
  13.375 -                    // We've seen a newline.  Add it to our
  13.376 -                    // buffer and break out of this loop,
  13.377 -                    // starting fresh on a new line.
  13.378 -                    if (docCommentCount == docCommentBuffer.length)
  13.379 -                        expandCommentBuffer();
  13.380 -                    docCommentBuffer[docCommentCount++] = ch;
  13.381 -                    scanDocCommentChar();
  13.382 -                    break textLoop;
  13.383 -                default:
  13.384 -                    // Add the character to our buffer.
  13.385 -                    if (docCommentCount == docCommentBuffer.length)
  13.386 -                        expandCommentBuffer();
  13.387 -                    docCommentBuffer[docCommentCount++] = ch;
  13.388 -                    scanDocCommentChar();
  13.389 -                }
  13.390 -            } // end textLoop
  13.391 -            firstLine = false;
  13.392 -        } // end outerLoop
  13.393 -
  13.394 -        if (docCommentCount > 0) {
  13.395 -            int i = docCommentCount - 1;
  13.396 -        trailLoop:
  13.397 -            while (i > -1) {
  13.398 -                switch (docCommentBuffer[i]) {
  13.399 -                case '*':
  13.400 -                    i--;
  13.401 -                    break;
  13.402 -                default:
  13.403 -                    break trailLoop;
  13.404 -                }
  13.405 -            }
  13.406 -            docCommentCount = i + 1;
  13.407 -
  13.408 -            // Store the text of the doc comment
  13.409 -            docComment = new String(docCommentBuffer, 0 , docCommentCount);
  13.410 -        } else {
  13.411 -            docComment = "";
  13.412 -        }
  13.413 -    }
  13.414 -
  13.415 -    /** Build a map for translating between line numbers and
  13.416 -     * positions in the input.
  13.417 -     *
  13.418 -     * @return a LineMap */
  13.419 -    public Position.LineMap getLineMap() {
  13.420 -        char[] buf = getRawCharacters();
  13.421 -        return Position.makeLineMap(buf, buf.length, true);
  13.422 -    }
  13.423 -}
    14.1 --- a/src/share/classes/com/sun/tools/javac/parser/EndPosParser.java	Thu Oct 27 13:54:50 2011 -0700
    14.2 +++ b/src/share/classes/com/sun/tools/javac/parser/EndPosParser.java	Fri Oct 28 17:49:36 2011 -0700
    14.3 @@ -67,14 +67,14 @@
    14.4      /** {@inheritDoc} */
    14.5      @Override
    14.6      protected <T extends JCTree> T to(T t) {
    14.7 -        storeEnd(t, S.endPos());
    14.8 +        storeEnd(t, token.endPos);
    14.9          return t;
   14.10      }
   14.11  
   14.12      /** {@inheritDoc} */
   14.13      @Override
   14.14      protected <T extends JCTree> T toP(T t) {
   14.15 -        storeEnd(t, S.prevEndPos());
   14.16 +        storeEnd(t, S.prevToken().endPos);
   14.17          return t;
   14.18      }
   14.19  
   14.20 @@ -88,7 +88,7 @@
   14.21      /** {@inheritDoc} */
   14.22      @Override
   14.23      JCExpression parExpression() {
   14.24 -        int pos = S.pos();
   14.25 +        int pos = token.pos;
   14.26          JCExpression t = super.parExpression();
   14.27          return toP(F.at(pos).Parens(t));
   14.28      }
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java	Fri Oct 28 17:49:36 2011 -0700
    15.3 @@ -0,0 +1,896 @@
    15.4 +/*
    15.5 + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
    15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    15.7 + *
    15.8 + * This code is free software; you can redistribute it and/or modify it
    15.9 + * under the terms of the GNU General Public License version 2 only, as
   15.10 + * published by the Free Software Foundation.  Oracle designates this
   15.11 + * particular file as subject to the "Classpath" exception as provided
   15.12 + * by Oracle in the LICENSE file that accompanied this code.
   15.13 + *
   15.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   15.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   15.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   15.17 + * version 2 for more details (a copy is included in the LICENSE file that
   15.18 + * accompanied this code).
   15.19 + *
   15.20 + * You should have received a copy of the GNU General Public License version
   15.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   15.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   15.23 + *
   15.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   15.25 + * or visit www.oracle.com if you need additional information or have any
   15.26 + * questions.
   15.27 + */
   15.28 +
   15.29 +package com.sun.tools.javac.parser;
   15.30 +
   15.31 +import java.nio.CharBuffer;
   15.32 +import com.sun.tools.javac.code.Source;
   15.33 +import com.sun.tools.javac.util.*;
   15.34 +
   15.35 +
   15.36 +import static com.sun.tools.javac.parser.Tokens.*;
   15.37 +import static com.sun.tools.javac.util.LayoutCharacters.*;
   15.38 +
   15.39 +/** The lexical analyzer maps an input stream consisting of
   15.40 + *  ASCII characters and Unicode escapes into a token sequence.
   15.41 + *
   15.42 + *  <p><b>This is NOT part of any supported API.
   15.43 + *  If you write code that depends on this, you do so at your own risk.
   15.44 + *  This code and its internal interfaces are subject to change or
   15.45 + *  deletion without notice.</b>
   15.46 + */
   15.47 +public class JavaTokenizer {
   15.48 +
   15.49 +    private static boolean scannerDebug = false;
   15.50 +
   15.51 +    /** Allow hex floating-point literals.
   15.52 +     */
   15.53 +    private boolean allowHexFloats;
   15.54 +
   15.55 +    /** Allow binary literals.
   15.56 +     */
   15.57 +    private boolean allowBinaryLiterals;
   15.58 +
   15.59 +    /** Allow underscores in literals.
   15.60 +     */
   15.61 +    private boolean allowUnderscoresInLiterals;
   15.62 +
   15.63 +    /** The source language setting.
   15.64 +     */
   15.65 +    private Source source;
   15.66 +
   15.67 +    /** The log to be used for error reporting.
   15.68 +     */
   15.69 +    private final Log log;
   15.70 +
   15.71 +    /** The name table. */
   15.72 +    private final Names names;
   15.73 +
   15.74 +    /** The token factory. */
   15.75 +    private final Tokens tokens;
   15.76 +
   15.77 +    /** The token kind, set by nextToken().
   15.78 +     */
   15.79 +    protected TokenKind tk;
   15.80 +
   15.81 +    /** The token's radix, set by nextToken().
   15.82 +     */
   15.83 +    protected int radix;
   15.84 +
   15.85 +    /** The token's name, set by nextToken().
   15.86 +     */
   15.87 +    protected Name name;
   15.88 +
   15.89 +    /** The position where a lexical error occurred;
   15.90 +     */
   15.91 +    protected int errPos = Position.NOPOS;
   15.92 +
   15.93 +    /** Has a @deprecated been encountered in last doc comment?
   15.94 +     *  this needs to be reset by client.
   15.95 +     */
   15.96 +    protected boolean deprecatedFlag = false;
   15.97 +
   15.98 +    /** A character buffer for saved chars.
   15.99 +     */
  15.100 +    protected char[] sbuf = new char[128];
  15.101 +    protected int sp;
  15.102 +
  15.103 +    protected UnicodeReader reader;
  15.104 +
  15.105 +    private static final boolean hexFloatsWork = hexFloatsWork();
  15.106 +    private static boolean hexFloatsWork() {
  15.107 +        try {
  15.108 +            Float.valueOf("0x1.0p1");
  15.109 +            return true;
  15.110 +        } catch (NumberFormatException ex) {
  15.111 +            return false;
  15.112 +        }
  15.113 +    }
  15.114 +
  15.115 +    /**
  15.116 +     * Create a scanner from the input array.  This method might
  15.117 +     * modify the array.  To avoid copying the input array, ensure
  15.118 +     * that {@code inputLength < input.length} or
  15.119 +     * {@code input[input.length -1]} is a white space character.
  15.120 +     *
  15.121 +     * @param fac the factory which created this Scanner
  15.122 +     * @param input the input, might be modified
  15.123 +     * @param inputLength the size of the input.
  15.124 +     * Must be positive and less than or equal to input.length.
  15.125 +     */
  15.126 +    protected JavaTokenizer(ScannerFactory fac, CharBuffer buf) {
  15.127 +        this(fac, new UnicodeReader(fac, buf));
  15.128 +    }
  15.129 +
  15.130 +    protected JavaTokenizer(ScannerFactory fac, char[] buf, int inputLength) {
  15.131 +        this(fac, new UnicodeReader(fac, buf, inputLength));
  15.132 +    }
  15.133 +
  15.134 +    protected JavaTokenizer(ScannerFactory fac, UnicodeReader reader) {
  15.135 +        log = fac.log;
  15.136 +        names = fac.names;
  15.137 +        tokens = fac.tokens;
  15.138 +        source = fac.source;
  15.139 +        this.reader = reader;
  15.140 +        allowBinaryLiterals = source.allowBinaryLiterals();
  15.141 +        allowHexFloats = source.allowHexFloats();
  15.142 +        allowUnderscoresInLiterals = source.allowUnderscoresInLiterals();
  15.143 +    }
  15.144 +
  15.145 +    /** Report an error at the given position using the provided arguments.
  15.146 +     */
  15.147 +    protected void lexError(int pos, String key, Object... args) {
  15.148 +        log.error(pos, key, args);
  15.149 +        tk = TokenKind.ERROR;
  15.150 +        errPos = pos;
  15.151 +    }
  15.152 +
  15.153 +    /** Read next character in comment, skipping over double '\' characters.
  15.154 +     */
  15.155 +    protected void scanCommentChar() {
  15.156 +        reader.scanChar();
  15.157 +        if (reader.ch == '\\') {
  15.158 +            if (reader.peekChar() == '\\' && !reader.isUnicode()) {
  15.159 +                reader.skipChar();
  15.160 +            } else {
  15.161 +                reader.convertUnicode();
  15.162 +            }
  15.163 +        }
  15.164 +    }
  15.165 +
  15.166 +    /** Append a character to sbuf.
  15.167 +     */
  15.168 +    private void putChar(char ch) {
  15.169 +        if (sp == sbuf.length) {
  15.170 +            char[] newsbuf = new char[sbuf.length * 2];
  15.171 +            System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length);
  15.172 +            sbuf = newsbuf;
  15.173 +        }
  15.174 +        sbuf[sp++] = ch;
  15.175 +    }
  15.176 +
  15.177 +    /** Read next character in character or string literal and copy into sbuf.
  15.178 +     */
  15.179 +    private void scanLitChar(int pos) {
  15.180 +        if (reader.ch == '\\') {
  15.181 +            if (reader.peekChar() == '\\' && !reader.isUnicode()) {
  15.182 +                reader.skipChar();
  15.183 +                putChar('\\');
  15.184 +                reader.scanChar();
  15.185 +            } else {
  15.186 +                reader.scanChar();
  15.187 +                switch (reader.ch) {
  15.188 +                case '0': case '1': case '2': case '3':
  15.189 +                case '4': case '5': case '6': case '7':
  15.190 +                    char leadch = reader.ch;
  15.191 +                    int oct = reader.digit(pos, 8);
  15.192 +                    reader.scanChar();
  15.193 +                    if ('0' <= reader.ch && reader.ch <= '7') {
  15.194 +                        oct = oct * 8 + reader.digit(pos, 8);
  15.195 +                        reader.scanChar();
  15.196 +                        if (leadch <= '3' && '0' <= reader.ch && reader.ch <= '7') {
  15.197 +                            oct = oct * 8 + reader.digit(pos, 8);
  15.198 +                            reader.scanChar();
  15.199 +                        }
  15.200 +                    }
  15.201 +                    putChar((char)oct);
  15.202 +                    break;
  15.203 +                case 'b':
  15.204 +                    putChar('\b'); reader.scanChar(); break;
  15.205 +                case 't':
  15.206 +                    putChar('\t'); reader.scanChar(); break;
  15.207 +                case 'n':
  15.208 +                    putChar('\n'); reader.scanChar(); break;
  15.209 +                case 'f':
  15.210 +                    putChar('\f'); reader.scanChar(); break;
  15.211 +                case 'r':
  15.212 +                    putChar('\r'); reader.scanChar(); break;
  15.213 +                case '\'':
  15.214 +                    putChar('\''); reader.scanChar(); break;
  15.215 +                case '\"':
  15.216 +                    putChar('\"'); reader.scanChar(); break;
  15.217 +                case '\\':
  15.218 +                    putChar('\\'); reader.scanChar(); break;
  15.219 +                default:
  15.220 +                    lexError(reader.bp, "illegal.esc.char");
  15.221 +                }
  15.222 +            }
  15.223 +        } else if (reader.bp != reader.buflen) {
  15.224 +            putChar(reader.ch); reader.scanChar();
  15.225 +        }
  15.226 +    }
  15.227 +
  15.228 +    private void scanDigits(int pos, int digitRadix) {
  15.229 +        char saveCh;
  15.230 +        int savePos;
  15.231 +        do {
  15.232 +            if (reader.ch != '_') {
  15.233 +                putChar(reader.ch);
  15.234 +            } else {
  15.235 +                if (!allowUnderscoresInLiterals) {
  15.236 +                    lexError(pos, "unsupported.underscore.lit", source.name);
  15.237 +                    allowUnderscoresInLiterals = true;
  15.238 +                }
  15.239 +            }
  15.240 +            saveCh = reader.ch;
  15.241 +            savePos = reader.bp;
  15.242 +            reader.scanChar();
  15.243 +        } while (reader.digit(pos, digitRadix) >= 0 || reader.ch == '_');
  15.244 +        if (saveCh == '_')
  15.245 +            lexError(savePos, "illegal.underscore");
  15.246 +    }
  15.247 +
  15.248 +    /** Read fractional part of hexadecimal floating point number.
  15.249 +     */
  15.250 +    private void scanHexExponentAndSuffix(int pos) {
  15.251 +        if (reader.ch == 'p' || reader.ch == 'P') {
  15.252 +            putChar(reader.ch);
  15.253 +            reader.scanChar();
  15.254 +            skipIllegalUnderscores();
  15.255 +            if (reader.ch == '+' || reader.ch == '-') {
  15.256 +                putChar(reader.ch);
  15.257 +                reader.scanChar();
  15.258 +            }
  15.259 +            skipIllegalUnderscores();
  15.260 +            if ('0' <= reader.ch && reader.ch <= '9') {
  15.261 +                scanDigits(pos, 10);
  15.262 +                if (!allowHexFloats) {
  15.263 +                    lexError(pos, "unsupported.fp.lit", source.name);
  15.264 +                    allowHexFloats = true;
  15.265 +                }
  15.266 +                else if (!hexFloatsWork)
  15.267 +                    lexError(pos, "unsupported.cross.fp.lit");
  15.268 +            } else
  15.269 +                lexError(pos, "malformed.fp.lit");
  15.270 +        } else {
  15.271 +            lexError(pos, "malformed.fp.lit");
  15.272 +        }
  15.273 +        if (reader.ch == 'f' || reader.ch == 'F') {
  15.274 +            putChar(reader.ch);
  15.275 +            reader.scanChar();
  15.276 +            tk = TokenKind.FLOATLITERAL;
  15.277 +            radix = 16;
  15.278 +        } else {
  15.279 +            if (reader.ch == 'd' || reader.ch == 'D') {
  15.280 +                putChar(reader.ch);
  15.281 +                reader.scanChar();
  15.282 +            }
  15.283 +            tk = TokenKind.DOUBLELITERAL;
  15.284 +            radix = 16;
  15.285 +        }
  15.286 +    }
  15.287 +
  15.288 +    /** Read fractional part of floating point number.
  15.289 +     */
  15.290 +    private void scanFraction(int pos) {
  15.291 +        skipIllegalUnderscores();
  15.292 +        if ('0' <= reader.ch && reader.ch <= '9') {
  15.293 +            scanDigits(pos, 10);
  15.294 +        }
  15.295 +        int sp1 = sp;
  15.296 +        if (reader.ch == 'e' || reader.ch == 'E') {
  15.297 +            putChar(reader.ch);
  15.298 +            reader.scanChar();
  15.299 +            skipIllegalUnderscores();
  15.300 +            if (reader.ch == '+' || reader.ch == '-') {
  15.301 +                putChar(reader.ch);
  15.302 +                reader.scanChar();
  15.303 +            }
  15.304 +            skipIllegalUnderscores();
  15.305 +            if ('0' <= reader.ch && reader.ch <= '9') {
  15.306 +                scanDigits(pos, 10);
  15.307 +                return;
  15.308 +            }
  15.309 +            lexError(pos, "malformed.fp.lit");
  15.310 +            sp = sp1;
  15.311 +        }
  15.312 +    }
  15.313 +
  15.314 +    /** Read fractional part and 'd' or 'f' suffix of floating point number.
  15.315 +     */
  15.316 +    private void scanFractionAndSuffix(int pos) {
  15.317 +        radix = 10;
  15.318 +        scanFraction(pos);
  15.319 +        if (reader.ch == 'f' || reader.ch == 'F') {
  15.320 +            putChar(reader.ch);
  15.321 +            reader.scanChar();
  15.322 +            tk = TokenKind.FLOATLITERAL;
  15.323 +        } else {
  15.324 +            if (reader.ch == 'd' || reader.ch == 'D') {
  15.325 +                putChar(reader.ch);
  15.326 +                reader.scanChar();
  15.327 +            }
  15.328 +            tk = TokenKind.DOUBLELITERAL;
  15.329 +        }
  15.330 +    }
  15.331 +
  15.332 +    /** Read fractional part and 'd' or 'f' suffix of floating point number.
  15.333 +     */
  15.334 +    private void scanHexFractionAndSuffix(int pos, boolean seendigit) {
  15.335 +        radix = 16;
  15.336 +        Assert.check(reader.ch == '.');
  15.337 +        putChar(reader.ch);
  15.338 +        reader.scanChar();
  15.339 +        skipIllegalUnderscores();
  15.340 +        if (reader.digit(pos, 16) >= 0) {
  15.341 +            seendigit = true;
  15.342 +            scanDigits(pos, 16);
  15.343 +        }
  15.344 +        if (!seendigit)
  15.345 +            lexError(pos, "invalid.hex.number");
  15.346 +        else
  15.347 +            scanHexExponentAndSuffix(pos);
  15.348 +    }
  15.349 +
  15.350 +    private void skipIllegalUnderscores() {
  15.351 +        if (reader.ch == '_') {
  15.352 +            lexError(reader.bp, "illegal.underscore");
  15.353 +            while (reader.ch == '_')
  15.354 +                reader.scanChar();
  15.355 +        }
  15.356 +    }
  15.357 +
  15.358 +    /** Read a number.
  15.359 +     *  @param radix  The radix of the number; one of 2, j8, 10, 16.
  15.360 +     */
  15.361 +    private void scanNumber(int pos, int radix) {
  15.362 +        // for octal, allow base-10 digit in case it's a float literal
  15.363 +        this.radix = radix;
  15.364 +        int digitRadix = (radix == 8 ? 10 : radix);
  15.365 +        boolean seendigit = false;
  15.366 +        if (reader.digit(pos, digitRadix) >= 0) {
  15.367 +            seendigit = true;
  15.368 +            scanDigits(pos, digitRadix);
  15.369 +        }
  15.370 +        if (radix == 16 && reader.ch == '.') {
  15.371 +            scanHexFractionAndSuffix(pos, seendigit);
  15.372 +        } else if (seendigit && radix == 16 && (reader.ch == 'p' || reader.ch == 'P')) {
  15.373 +            scanHexExponentAndSuffix(pos);
  15.374 +        } else if (digitRadix == 10 && reader.ch == '.') {
  15.375 +            putChar(reader.ch);
  15.376 +            reader.scanChar();
  15.377 +            scanFractionAndSuffix(pos);
  15.378 +        } else if (digitRadix == 10 &&
  15.379 +                   (reader.ch == 'e' || reader.ch == 'E' ||
  15.380 +                    reader.ch == 'f' || reader.ch == 'F' ||
  15.381 +                    reader.ch == 'd' || reader.ch == 'D')) {
  15.382 +            scanFractionAndSuffix(pos);
  15.383 +        } else {
  15.384 +            if (reader.ch == 'l' || reader.ch == 'L') {
  15.385 +                reader.scanChar();
  15.386 +                tk = TokenKind.LONGLITERAL;
  15.387 +            } else {
  15.388 +                tk = TokenKind.INTLITERAL;
  15.389 +            }
  15.390 +        }
  15.391 +    }
  15.392 +
  15.393 +    /** Read an identifier.
  15.394 +     */
  15.395 +    private void scanIdent() {
  15.396 +        boolean isJavaIdentifierPart;
  15.397 +        char high;
  15.398 +        do {
  15.399 +            if (sp == sbuf.length) putChar(reader.ch); else sbuf[sp++] = reader.ch;
  15.400 +            // optimization, was: putChar(reader.ch);
  15.401 +
  15.402 +            reader.scanChar();
  15.403 +            switch (reader.ch) {
  15.404 +            case 'A': case 'B': case 'C': case 'D': case 'E':
  15.405 +            case 'F': case 'G': case 'H': case 'I': case 'J':
  15.406 +            case 'K': case 'L': case 'M': case 'N': case 'O':
  15.407 +            case 'P': case 'Q': case 'R': case 'S': case 'T':
  15.408 +            case 'U': case 'V': case 'W': case 'X': case 'Y':
  15.409 +            case 'Z':
  15.410 +            case 'a': case 'b': case 'c': case 'd': case 'e':
  15.411 +            case 'f': case 'g': case 'h': case 'i': case 'j':
  15.412 +            case 'k': case 'l': case 'm': case 'n': case 'o':
  15.413 +            case 'p': case 'q': case 'r': case 's': case 't':
  15.414 +            case 'u': case 'v': case 'w': case 'x': case 'y':
  15.415 +            case 'z':
  15.416 +            case '$': case '_':
  15.417 +            case '0': case '1': case '2': case '3': case '4':
  15.418 +            case '5': case '6': case '7': case '8': case '9':
  15.419 +            case '\u0000': case '\u0001': case '\u0002': case '\u0003':
  15.420 +            case '\u0004': case '\u0005': case '\u0006': case '\u0007':
  15.421 +            case '\u0008': case '\u000E': case '\u000F': case '\u0010':
  15.422 +            case '\u0011': case '\u0012': case '\u0013': case '\u0014':
  15.423 +            case '\u0015': case '\u0016': case '\u0017':
  15.424 +            case '\u0018': case '\u0019': case '\u001B':
  15.425 +            case '\u007F':
  15.426 +                break;
  15.427 +            case '\u001A': // EOI is also a legal identifier part
  15.428 +                if (reader.bp >= reader.buflen) {
  15.429 +                    name = names.fromChars(sbuf, 0, sp);
  15.430 +                    tk = tokens.lookupKind(name);
  15.431 +                    return;
  15.432 +                }
  15.433 +                break;
  15.434 +            default:
  15.435 +                if (reader.ch < '\u0080') {
  15.436 +                    // all ASCII range chars already handled, above
  15.437 +                    isJavaIdentifierPart = false;
  15.438 +                } else {
  15.439 +                    high = reader.scanSurrogates();
  15.440 +                    if (high != 0) {
  15.441 +                        if (sp == sbuf.length) {
  15.442 +                            putChar(high);
  15.443 +                        } else {
  15.444 +                            sbuf[sp++] = high;
  15.445 +                        }
  15.446 +                        isJavaIdentifierPart = Character.isJavaIdentifierPart(
  15.447 +                            Character.toCodePoint(high, reader.ch));
  15.448 +                    } else {
  15.449 +                        isJavaIdentifierPart = Character.isJavaIdentifierPart(reader.ch);
  15.450 +                    }
  15.451 +                }
  15.452 +                if (!isJavaIdentifierPart) {
  15.453 +                    name = names.fromChars(sbuf, 0, sp);
  15.454 +                    tk = tokens.lookupKind(name);
  15.455 +                    return;
  15.456 +                }
  15.457 +            }
  15.458 +        } while (true);
  15.459 +    }
  15.460 +
  15.461 +    /** Return true if reader.ch can be part of an operator.
  15.462 +     */
  15.463 +    private boolean isSpecial(char ch) {
  15.464 +        switch (ch) {
  15.465 +        case '!': case '%': case '&': case '*': case '?':
  15.466 +        case '+': case '-': case ':': case '<': case '=':
  15.467 +        case '>': case '^': case '|': case '~':
  15.468 +        case '@':
  15.469 +            return true;
  15.470 +        default:
  15.471 +            return false;
  15.472 +        }
  15.473 +    }
  15.474 +
  15.475 +    /** Read longest possible sequence of special characters and convert
  15.476 +     *  to token.
  15.477 +     */
  15.478 +    private void scanOperator() {
  15.479 +        while (true) {
  15.480 +            putChar(reader.ch);
  15.481 +            Name newname = names.fromChars(sbuf, 0, sp);
  15.482 +            TokenKind tk1 = tokens.lookupKind(newname);
  15.483 +            if (tk1 == TokenKind.IDENTIFIER) {
  15.484 +                sp--;
  15.485 +                break;
  15.486 +            }
  15.487 +            tk = tk1;
  15.488 +            reader.scanChar();
  15.489 +            if (!isSpecial(reader.ch)) break;
  15.490 +        }
  15.491 +    }
  15.492 +
  15.493 +    /**
  15.494 +     * Scan a documentation comment; determine if a deprecated tag is present.
  15.495 +     * Called once the initial /, * have been skipped, positioned at the second *
  15.496 +     * (which is treated as the beginning of the first line).
  15.497 +     * Stops positioned at the closing '/'.
  15.498 +     */
  15.499 +    @SuppressWarnings("fallthrough")
  15.500 +    private void scanDocComment() {
  15.501 +        boolean deprecatedPrefix = false;
  15.502 +
  15.503 +        forEachLine:
  15.504 +        while (reader.bp < reader.buflen) {
  15.505 +
  15.506 +            // Skip optional WhiteSpace at beginning of line
  15.507 +            while (reader.bp < reader.buflen && (reader.ch == ' ' || reader.ch == '\t' || reader.ch == FF)) {
  15.508 +                scanCommentChar();
  15.509 +            }
  15.510 +
  15.511 +            // Skip optional consecutive Stars
  15.512 +            while (reader.bp < reader.buflen && reader.ch == '*') {
  15.513 +                scanCommentChar();
  15.514 +                if (reader.ch == '/') {
  15.515 +                    return;
  15.516 +                }
  15.517 +            }
  15.518 +
  15.519 +            // Skip optional WhiteSpace after Stars
  15.520 +            while (reader.bp < reader.buflen && (reader.ch == ' ' || reader.ch == '\t' || reader.ch == FF)) {
  15.521 +                scanCommentChar();
  15.522 +            }
  15.523 +
  15.524 +            deprecatedPrefix = false;
  15.525 +            // At beginning of line in the JavaDoc sense.
  15.526 +            if (reader.bp < reader.buflen && reader.ch == '@' && !deprecatedFlag) {
  15.527 +                scanCommentChar();
  15.528 +                if (reader.bp < reader.buflen && reader.ch == 'd') {
  15.529 +                    scanCommentChar();
  15.530 +                    if (reader.bp < reader.buflen && reader.ch == 'e') {
  15.531 +                        scanCommentChar();
  15.532 +                        if (reader.bp < reader.buflen && reader.ch == 'p') {
  15.533 +                            scanCommentChar();
  15.534 +                            if (reader.bp < reader.buflen && reader.ch == 'r') {
  15.535 +                                scanCommentChar();
  15.536 +                                if (reader.bp < reader.buflen && reader.ch == 'e') {
  15.537 +                                    scanCommentChar();
  15.538 +                                    if (reader.bp < reader.buflen && reader.ch == 'c') {
  15.539 +                                        scanCommentChar();
  15.540 +                                        if (reader.bp < reader.buflen && reader.ch == 'a') {
  15.541 +                                            scanCommentChar();
  15.542 +                                            if (reader.bp < reader.buflen && reader.ch == 't') {
  15.543 +                                                scanCommentChar();
  15.544 +                                                if (reader.bp < reader.buflen && reader.ch == 'e') {
  15.545 +                                                    scanCommentChar();
  15.546 +                                                    if (reader.bp < reader.buflen && reader.ch == 'd') {
  15.547 +                                                        deprecatedPrefix = true;
  15.548 +                                                        scanCommentChar();
  15.549 +                                                    }}}}}}}}}}}
  15.550 +            if (deprecatedPrefix && reader.bp < reader.buflen) {
  15.551 +                if (Character.isWhitespace(reader.ch)) {
  15.552 +                    deprecatedFlag = true;
  15.553 +                } else if (reader.ch == '*') {
  15.554 +                    scanCommentChar();
  15.555 +                    if (reader.ch == '/') {
  15.556 +                        deprecatedFlag = true;
  15.557 +                        return;
  15.558 +                    }
  15.559 +                }
  15.560 +            }
  15.561 +
  15.562 +            // Skip rest of line
  15.563 +            while (reader.bp < reader.buflen) {
  15.564 +                switch (reader.ch) {
  15.565 +                case '*':
  15.566 +                    scanCommentChar();
  15.567 +                    if (reader.ch == '/') {
  15.568 +                        return;
  15.569 +                    }
  15.570 +                    break;
  15.571 +                case CR: // (Spec 3.4)
  15.572 +                    scanCommentChar();
  15.573 +                    if (reader.ch != LF) {
  15.574 +                        continue forEachLine;
  15.575 +                    }
  15.576 +                    /* fall through to LF case */
  15.577 +                case LF: // (Spec 3.4)
  15.578 +                    scanCommentChar();
  15.579 +                    continue forEachLine;
  15.580 +                default:
  15.581 +                    scanCommentChar();
  15.582 +                }
  15.583 +            } // rest of line
  15.584 +        } // forEachLine
  15.585 +        return;
  15.586 +    }
  15.587 +
  15.588 +    /** Read token.
  15.589 +     */
  15.590 +    public Token readToken() {
  15.591 +
  15.592 +        sp = 0;
  15.593 +        name = null;
  15.594 +        deprecatedFlag = false;
  15.595 +        radix = 0;
  15.596 +        int pos = 0;
  15.597 +        int endPos = 0;
  15.598 +
  15.599 +        try {
  15.600 +            loop: while (true) {
  15.601 +                pos = reader.bp;
  15.602 +                switch (reader.ch) {
  15.603 +                case ' ': // (Spec 3.6)
  15.604 +                case '\t': // (Spec 3.6)
  15.605 +                case FF: // (Spec 3.6)
  15.606 +                    do {
  15.607 +                        reader.scanChar();
  15.608 +                    } while (reader.ch == ' ' || reader.ch == '\t' || reader.ch == FF);
  15.609 +                    processWhiteSpace(pos, reader.bp);
  15.610 +                    break;
  15.611 +                case LF: // (Spec 3.4)
  15.612 +                    reader.scanChar();
  15.613 +                    processLineTerminator(pos, reader.bp);
  15.614 +                    break;
  15.615 +                case CR: // (Spec 3.4)
  15.616 +                    reader.scanChar();
  15.617 +                    if (reader.ch == LF) {
  15.618 +                        reader.scanChar();
  15.619 +                    }
  15.620 +                    processLineTerminator(pos, reader.bp);
  15.621 +                    break;
  15.622 +                case 'A': case 'B': case 'C': case 'D': case 'E':
  15.623 +                case 'F': case 'G': case 'H': case 'I': case 'J':
  15.624 +                case 'K': case 'L': case 'M': case 'N': case 'O':
  15.625 +                case 'P': case 'Q': case 'R': case 'S': case 'T':
  15.626 +                case 'U': case 'V': case 'W': case 'X': case 'Y':
  15.627 +                case 'Z':
  15.628 +                case 'a': case 'b': case 'c': case 'd': case 'e':
  15.629 +                case 'f': case 'g': case 'h': case 'i': case 'j':
  15.630 +                case 'k': case 'l': case 'm': case 'n': case 'o':
  15.631 +                case 'p': case 'q': case 'r': case 's': case 't':
  15.632 +                case 'u': case 'v': case 'w': case 'x': case 'y':
  15.633 +                case 'z':
  15.634 +                case '$': case '_':
  15.635 +                    scanIdent();
  15.636 +                    break loop;
  15.637 +                case '0':
  15.638 +                    reader.scanChar();
  15.639 +                    if (reader.ch == 'x' || reader.ch == 'X') {
  15.640 +                        reader.scanChar();
  15.641 +                        skipIllegalUnderscores();
  15.642 +                        if (reader.ch == '.') {
  15.643 +                            scanHexFractionAndSuffix(pos, false);
  15.644 +                        } else if (reader.digit(pos, 16) < 0) {
  15.645 +                            lexError(pos, "invalid.hex.number");
  15.646 +                        } else {
  15.647 +                            scanNumber(pos, 16);
  15.648 +                        }
  15.649 +                    } else if (reader.ch == 'b' || reader.ch == 'B') {
  15.650 +                        if (!allowBinaryLiterals) {
  15.651 +                            lexError(pos, "unsupported.binary.lit", source.name);
  15.652 +                            allowBinaryLiterals = true;
  15.653 +                        }
  15.654 +                        reader.scanChar();
  15.655 +                        skipIllegalUnderscores();
  15.656 +                        if (reader.digit(pos, 2) < 0) {
  15.657 +                            lexError(pos, "invalid.binary.number");
  15.658 +                        } else {
  15.659 +                            scanNumber(pos, 2);
  15.660 +                        }
  15.661 +                    } else {
  15.662 +                        putChar('0');
  15.663 +                        if (reader.ch == '_') {
  15.664 +                            int savePos = reader.bp;
  15.665 +                            do {
  15.666 +                                reader.scanChar();
  15.667 +                            } while (reader.ch == '_');
  15.668 +                            if (reader.digit(pos, 10) < 0) {
  15.669 +                                lexError(savePos, "illegal.underscore");
  15.670 +                            }
  15.671 +                        }
  15.672 +                        scanNumber(pos, 8);
  15.673 +                    }
  15.674 +                    break loop;
  15.675 +                case '1': case '2': case '3': case '4':
  15.676 +                case '5': case '6': case '7': case '8': case '9':
  15.677 +                    scanNumber(pos, 10);
  15.678 +                    break loop;
  15.679 +                case '.':
  15.680 +                    reader.scanChar();
  15.681 +                    if ('0' <= reader.ch && reader.ch <= '9') {
  15.682 +                        putChar('.');
  15.683 +                        scanFractionAndSuffix(pos);
  15.684 +                    } else if (reader.ch == '.') {
  15.685 +                        putChar('.'); putChar('.');
  15.686 +                        reader.scanChar();
  15.687 +                        if (reader.ch == '.') {
  15.688 +                            reader.scanChar();
  15.689 +                            putChar('.');
  15.690 +                            tk = TokenKind.ELLIPSIS;
  15.691 +                        } else {
  15.692 +                            lexError(pos, "malformed.fp.lit");
  15.693 +                        }
  15.694 +                    } else {
  15.695 +                        tk = TokenKind.DOT;
  15.696 +                    }
  15.697 +                    break loop;
  15.698 +                case ',':
  15.699 +                    reader.scanChar(); tk = TokenKind.COMMA; break loop;
  15.700 +                case ';':
  15.701 +                    reader.scanChar(); tk = TokenKind.SEMI; break loop;
  15.702 +                case '(':
  15.703 +                    reader.scanChar(); tk = TokenKind.LPAREN; break loop;
  15.704 +                case ')':
  15.705 +                    reader.scanChar(); tk = TokenKind.RPAREN; break loop;
  15.706 +                case '[':
  15.707 +                    reader.scanChar(); tk = TokenKind.LBRACKET; break loop;
  15.708 +                case ']':
  15.709 +                    reader.scanChar(); tk = TokenKind.RBRACKET; break loop;
  15.710 +                case '{':
  15.711 +                    reader.scanChar(); tk = TokenKind.LBRACE; break loop;
  15.712 +                case '}':
  15.713 +                    reader.scanChar(); tk = TokenKind.RBRACE; break loop;
  15.714 +                case '/':
  15.715 +                    reader.scanChar();
  15.716 +                    if (reader.ch == '/') {
  15.717 +                        do {
  15.718 +                            scanCommentChar();
  15.719 +                        } while (reader.ch != CR && reader.ch != LF && reader.bp < reader.buflen);
  15.720 +                        if (reader.bp < reader.buflen) {
  15.721 +                            processComment(pos, reader.bp, CommentStyle.LINE);
  15.722 +                        }
  15.723 +                        break;
  15.724 +                    } else if (reader.ch == '*') {
  15.725 +                        reader.scanChar();
  15.726 +                        CommentStyle style;
  15.727 +                        if (reader.ch == '*') {
  15.728 +                            style = CommentStyle.JAVADOC;
  15.729 +                            scanDocComment();
  15.730 +                        } else {
  15.731 +                            style = CommentStyle.BLOCK;
  15.732 +                            while (reader.bp < reader.buflen) {
  15.733 +                                if (reader.ch == '*') {
  15.734 +                                    reader.scanChar();
  15.735 +                                    if (reader.ch == '/') break;
  15.736 +                                } else {
  15.737 +                                    scanCommentChar();
  15.738 +                                }
  15.739 +                            }
  15.740 +                        }
  15.741 +                        if (reader.ch == '/') {
  15.742 +                            reader.scanChar();
  15.743 +                            processComment(pos, reader.bp, style);
  15.744 +                            break;
  15.745 +                        } else {
  15.746 +                            lexError(pos, "unclosed.comment");
  15.747 +                            break loop;
  15.748 +                        }
  15.749 +                    } else if (reader.ch == '=') {
  15.750 +                        tk = TokenKind.SLASHEQ;
  15.751 +                        reader.scanChar();
  15.752 +                    } else {
  15.753 +                        tk = TokenKind.SLASH;
  15.754 +                    }
  15.755 +                    break loop;
  15.756 +                case '\'':
  15.757 +                    reader.scanChar();
  15.758 +                    if (reader.ch == '\'') {
  15.759 +                        lexError(pos, "empty.char.lit");
  15.760 +                    } else {
  15.761 +                        if (reader.ch == CR || reader.ch == LF)
  15.762 +                            lexError(pos, "illegal.line.end.in.char.lit");
  15.763 +                        scanLitChar(pos);
  15.764 +                        char ch2 = reader.ch;
  15.765 +                        if (reader.ch == '\'') {
  15.766 +                            reader.scanChar();
  15.767 +                            tk = TokenKind.CHARLITERAL;
  15.768 +                        } else {
  15.769 +                            lexError(pos, "unclosed.char.lit");
  15.770 +                        }
  15.771 +                    }
  15.772 +                    break loop;
  15.773 +                case '\"':
  15.774 +                    reader.scanChar();
  15.775 +                    while (reader.ch != '\"' && reader.ch != CR && reader.ch != LF && reader.bp < reader.buflen)
  15.776 +                        scanLitChar(pos);
  15.777 +                    if (reader.ch == '\"') {
  15.778 +                        tk = TokenKind.STRINGLITERAL;
  15.779 +                        reader.scanChar();
  15.780 +                    } else {
  15.781 +                        lexError(pos, "unclosed.str.lit");
  15.782 +                    }
  15.783 +                    break loop;
  15.784 +                default:
  15.785 +                    if (isSpecial(reader.ch)) {
  15.786 +                        scanOperator();
  15.787 +                    } else {
  15.788 +                        boolean isJavaIdentifierStart;
  15.789 +                        if (reader.ch < '\u0080') {
  15.790 +                            // all ASCII range chars already handled, above
  15.791 +                            isJavaIdentifierStart = false;
  15.792 +                        } else {
  15.793 +                            char high = reader.scanSurrogates();
  15.794 +                            if (high != 0) {
  15.795 +                                if (sp == sbuf.length) {
  15.796 +                                    putChar(high);
  15.797 +                                } else {
  15.798 +                                    sbuf[sp++] = high;
  15.799 +                                }
  15.800 +
  15.801 +                                isJavaIdentifierStart = Character.isJavaIdentifierStart(
  15.802 +                                    Character.toCodePoint(high, reader.ch));
  15.803 +                            } else {
  15.804 +                                isJavaIdentifierStart = Character.isJavaIdentifierStart(reader.ch);
  15.805 +                            }
  15.806 +                        }
  15.807 +                        if (isJavaIdentifierStart) {
  15.808 +                            scanIdent();
  15.809 +                        } else if (reader.bp == reader.buflen || reader.ch == EOI && reader.bp + 1 == reader.buflen) { // JLS 3.5
  15.810 +                            tk = TokenKind.EOF;
  15.811 +                            pos = reader.buflen;
  15.812 +                        } else {
  15.813 +                            lexError(pos, "illegal.char", String.valueOf((int)reader.ch));
  15.814 +                            reader.scanChar();
  15.815 +                        }
  15.816 +                    }
  15.817 +                    break loop;
  15.818 +                }
  15.819 +            }
  15.820 +            endPos = reader.bp;
  15.821 +            switch (tk.tag) {
  15.822 +                case DEFAULT: return new Token(tk, pos, endPos, deprecatedFlag);
  15.823 +                case NAMED: return new NamedToken(tk, pos, endPos, name, deprecatedFlag);
  15.824 +                case STRING: return new StringToken(tk, pos, endPos, new String(sbuf, 0, sp), deprecatedFlag);
  15.825 +                case NUMERIC: return new NumericToken(tk, pos, endPos, new String(sbuf, 0, sp), radix, deprecatedFlag);
  15.826 +                default: throw new AssertionError();
  15.827 +            }
  15.828 +        }
  15.829 +        finally {
  15.830 +            if (scannerDebug) {
  15.831 +                    System.out.println("nextToken(" + pos
  15.832 +                                       + "," + endPos + ")=|" +
  15.833 +                                       new String(reader.getRawCharacters(pos, endPos))
  15.834 +                                       + "|");
  15.835 +            }
  15.836 +        }
  15.837 +    }
  15.838 +
  15.839 +    /** Return the position where a lexical error occurred;
  15.840 +     */
  15.841 +    public int errPos() {
  15.842 +        return errPos;
  15.843 +    }
  15.844 +
  15.845 +    /** Set the position where a lexical error occurred;
  15.846 +     */
  15.847 +    public void errPos(int pos) {
  15.848 +        errPos = pos;
  15.849 +    }
  15.850 +
  15.851 +    public enum CommentStyle {
  15.852 +        LINE,
  15.853 +        BLOCK,
  15.854 +        JAVADOC,
  15.855 +    }
  15.856 +
  15.857 +    /**
  15.858 +     * Called when a complete comment has been scanned. pos and endPos
  15.859 +     * will mark the comment boundary.
  15.860 +     */
  15.861 +    protected void processComment(int pos, int endPos, CommentStyle style) {
  15.862 +        if (scannerDebug)
  15.863 +            System.out.println("processComment(" + pos
  15.864 +                               + "," + endPos + "," + style + ")=|"
  15.865 +                               + new String(reader.getRawCharacters(pos, endPos))
  15.866 +                               + "|");
  15.867 +    }
  15.868 +
  15.869 +    /**
  15.870 +     * Called when a complete whitespace run has been scanned. pos and endPos
  15.871 +     * will mark the whitespace boundary.
  15.872 +     */
  15.873 +    protected void processWhiteSpace(int pos, int endPos) {
  15.874 +        if (scannerDebug)
  15.875 +            System.out.println("processWhitespace(" + pos
  15.876 +                               + "," + endPos + ")=|" +
  15.877 +                               new String(reader.getRawCharacters(pos, endPos))
  15.878 +                               + "|");
  15.879 +    }
  15.880 +
  15.881 +    /**
  15.882 +     * Called when a line terminator has been processed.
  15.883 +     */
  15.884 +    protected void processLineTerminator(int pos, int endPos) {
  15.885 +        if (scannerDebug)
  15.886 +            System.out.println("processTerminator(" + pos
  15.887 +                               + "," + endPos + ")=|" +
  15.888 +                               new String(reader.getRawCharacters(pos, endPos))
  15.889 +                               + "|");
  15.890 +    }
  15.891 +
  15.892 +    /** Build a map for translating between line numbers and
  15.893 +     * positions in the input.
  15.894 +     *
  15.895 +     * @return a LineMap */
  15.896 +    public Position.LineMap getLineMap() {
  15.897 +        return Position.makeLineMap(reader.getRawCharacters(), reader.buflen, false);
  15.898 +    }
  15.899 +}
    16.1 --- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Thu Oct 27 13:54:50 2011 -0700
    16.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Fri Oct 28 17:49:36 2011 -0700
    16.3 @@ -28,6 +28,7 @@
    16.4  import java.util.*;
    16.5  
    16.6  import com.sun.tools.javac.code.*;
    16.7 +import com.sun.tools.javac.parser.Tokens.*;
    16.8  import com.sun.tools.javac.tree.*;
    16.9  import com.sun.tools.javac.tree.JCTree.*;
   16.10  import com.sun.tools.javac.util.*;
   16.11 @@ -36,7 +37,7 @@
   16.12  import com.sun.tools.javac.util.List;
   16.13  
   16.14  import static com.sun.tools.javac.util.ListBuffer.lb;
   16.15 -import static com.sun.tools.javac.parser.Token.*;
   16.16 +import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
   16.17  
   16.18  /** The parser maps a token sequence into an abstract syntax
   16.19   *  tree. It operates by recursive descent, with code derived
   16.20 @@ -67,9 +68,6 @@
   16.21       */
   16.22      private Log log;
   16.23  
   16.24 -    /** The keyword table. */
   16.25 -    private Keywords keywords;
   16.26 -
   16.27      /** The Source language setting. */
   16.28      private Source source;
   16.29  
   16.30 @@ -83,11 +81,10 @@
   16.31                       boolean keepDocComments,
   16.32                       boolean keepLineMap) {
   16.33          this.S = S;
   16.34 -        S.nextToken(); // prime the pump
   16.35 +        nextToken(); // prime the pump
   16.36          this.F = fac.F;
   16.37          this.log = fac.log;
   16.38          this.names = fac.names;
   16.39 -        this.keywords = fac.keywords;
   16.40          this.source = fac.source;
   16.41          this.allowGenerics = source.allowGenerics();
   16.42          this.allowVarargs = source.allowVarargs();
   16.43 @@ -178,7 +175,16 @@
   16.44       */
   16.45      private int lastmode = 0;
   16.46  
   16.47 -/* ---------- error recovery -------------- */
   16.48 +    /* ---------- token management -------------- */
   16.49 +
   16.50 +    protected Token token;
   16.51 +
   16.52 +    protected void nextToken() {
   16.53 +        S.nextToken();
   16.54 +        token = S.token();
   16.55 +    }
   16.56 +
   16.57 +    /* ---------- error recovery -------------- */
   16.58  
   16.59      private JCErroneous errorTree;
   16.60  
   16.61 @@ -186,9 +192,9 @@
   16.62       */
   16.63      private void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) {
   16.64           while (true) {
   16.65 -             switch (S.token()) {
   16.66 +             switch (token.kind) {
   16.67                  case SEMI:
   16.68 -                    S.nextToken();
   16.69 +                    nextToken();
   16.70                      return;
   16.71                  case PUBLIC:
   16.72                  case FINAL:
   16.73 @@ -249,15 +255,15 @@
   16.74                          return;
   16.75                      break;
   16.76              }
   16.77 -            S.nextToken();
   16.78 +            nextToken();
   16.79          }
   16.80      }
   16.81  
   16.82 -    private JCErroneous syntaxError(int pos, String key, Token... args) {
   16.83 +    private JCErroneous syntaxError(int pos, String key, TokenKind... args) {
   16.84          return syntaxError(pos, List.<JCTree>nil(), key, args);
   16.85      }
   16.86  
   16.87 -    private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, Token... args) {
   16.88 +    private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, TokenKind... args) {
   16.89          setErrorEndPos(pos);
   16.90          JCErroneous err = F.at(pos).Erroneous(errs);
   16.91          reportSyntaxError(err, key, (Object[])args);
   16.92 @@ -287,16 +293,16 @@
   16.93      private void reportSyntaxError(JCDiagnostic.DiagnosticPosition diagPos, String key, Object... args) {
   16.94          int pos = diagPos.getPreferredPosition();
   16.95          if (pos > S.errPos() || pos == Position.NOPOS) {
   16.96 -            if (S.token() == EOF) {
   16.97 +            if (token.kind == EOF) {
   16.98                  error(diagPos, "premature.eof");
   16.99              } else {
  16.100                  error(diagPos, key, args);
  16.101              }
  16.102          }
  16.103          S.errPos(pos);
  16.104 -        if (S.pos() == errorPos)
  16.105 -            S.nextToken(); // guarantee progress
  16.106 -        errorPos = S.pos();
  16.107 +        if (token.pos == errorPos)
  16.108 +            nextToken(); // guarantee progress
  16.109 +        errorPos = token.pos;
  16.110      }
  16.111  
  16.112  
  16.113 @@ -304,25 +310,25 @@
  16.114       *  reported at the same position.
  16.115       */
  16.116      private JCErroneous syntaxError(String key) {
  16.117 -        return syntaxError(S.pos(), key);
  16.118 +        return syntaxError(token.pos, key);
  16.119      }
  16.120  
  16.121      /** Generate a syntax error at current position unless one was
  16.122       *  already reported at the same position.
  16.123       */
  16.124 -    private JCErroneous syntaxError(String key, Token arg) {
  16.125 -        return syntaxError(S.pos(), key, arg);
  16.126 +    private JCErroneous syntaxError(String key, TokenKind arg) {
  16.127 +        return syntaxError(token.pos, key, arg);
  16.128      }
  16.129  
  16.130      /** If next input token matches given token, skip it, otherwise report
  16.131       *  an error.
  16.132       */
  16.133 -    public void accept(Token token) {
  16.134 -        if (S.token() == token) {
  16.135 -            S.nextToken();
  16.136 +    public void accept(TokenKind tk) {
  16.137 +        if (token.kind == tk) {
  16.138 +            nextToken();
  16.139          } else {
  16.140 -            setErrorEndPos(S.pos());
  16.141 -            reportSyntaxError(S.prevEndPos(), "expected", token);
  16.142 +            setErrorEndPos(token.pos);
  16.143 +            reportSyntaxError(S.prevToken().endPos, "expected", tk);
  16.144          }
  16.145      }
  16.146  
  16.147 @@ -340,14 +346,14 @@
  16.148      /** Report an illegal start of expression/type error at current position.
  16.149       */
  16.150      JCExpression illegal() {
  16.151 -        return illegal(S.pos());
  16.152 +        return illegal(token.pos);
  16.153      }
  16.154  
  16.155      /** Diagnose a modifier flag from the set, if any. */
  16.156      void checkNoMods(long mods) {
  16.157          if (mods != 0) {
  16.158              long lowestMod = mods & -mods;
  16.159 -            error(S.pos(), "mod.not.allowed.here",
  16.160 +            error(token.pos, "mod.not.allowed.here",
  16.161                        Flags.asFlagSet(lowestMod));
  16.162          }
  16.163      }
  16.164 @@ -435,30 +441,30 @@
  16.165       * Ident = IDENTIFIER
  16.166       */
  16.167      Name ident() {
  16.168 -        if (S.token() == IDENTIFIER) {
  16.169 -            Name name = S.name();
  16.170 -            S.nextToken();
  16.171 +        if (token.kind == IDENTIFIER) {
  16.172 +            Name name = token.name();
  16.173 +            nextToken();
  16.174              return name;
  16.175 -        } else if (S.token() == ASSERT) {
  16.176 +        } else if (token.kind == ASSERT) {
  16.177              if (allowAsserts) {
  16.178 -                error(S.pos(), "assert.as.identifier");
  16.179 -                S.nextToken();
  16.180 +                error(token.pos, "assert.as.identifier");
  16.181 +                nextToken();
  16.182                  return names.error;
  16.183              } else {
  16.184 -                warning(S.pos(), "assert.as.identifier");
  16.185 -                Name name = S.name();
  16.186 -                S.nextToken();
  16.187 +                warning(token.pos, "assert.as.identifier");
  16.188 +                Name name = token.name();
  16.189 +                nextToken();
  16.190                  return name;
  16.191              }
  16.192 -        } else if (S.token() == ENUM) {
  16.193 +        } else if (token.kind == ENUM) {
  16.194              if (allowEnums) {
  16.195 -                error(S.pos(), "enum.as.identifier");
  16.196 -                S.nextToken();
  16.197 +                error(token.pos, "enum.as.identifier");
  16.198 +                nextToken();
  16.199                  return names.error;
  16.200              } else {
  16.201 -                warning(S.pos(), "enum.as.identifier");
  16.202 -                Name name = S.name();
  16.203 -                S.nextToken();
  16.204 +                warning(token.pos, "enum.as.identifier");
  16.205 +                Name name = token.name();
  16.206 +                nextToken();
  16.207                  return name;
  16.208              }
  16.209          } else {
  16.210 @@ -471,17 +477,17 @@
  16.211       * Qualident = Ident { DOT Ident }
  16.212       */
  16.213      public JCExpression qualident() {
  16.214 -        JCExpression t = toP(F.at(S.pos()).Ident(ident()));
  16.215 -        while (S.token() == DOT) {
  16.216 -            int pos = S.pos();
  16.217 -            S.nextToken();
  16.218 +        JCExpression t = toP(F.at(token.pos).Ident(ident()));
  16.219 +        while (token.kind == DOT) {
  16.220 +            int pos = token.pos;
  16.221 +            nextToken();
  16.222              t = toP(F.at(pos).Select(t, ident()));
  16.223          }
  16.224          return t;
  16.225      }
  16.226  
  16.227      JCExpression literal(Name prefix) {
  16.228 -        return literal(prefix, S.pos());
  16.229 +        return literal(prefix, token.pos);
  16.230      }
  16.231  
  16.232      /**
  16.233 @@ -498,27 +504,29 @@
  16.234       */
  16.235      JCExpression literal(Name prefix, int pos) {
  16.236          JCExpression t = errorTree;
  16.237 -        switch (S.token()) {
  16.238 +        switch (token.kind) {
  16.239          case INTLITERAL:
  16.240              try {
  16.241                  t = F.at(pos).Literal(
  16.242                      TypeTags.INT,
  16.243 -                    Convert.string2int(strval(prefix), S.radix()));
  16.244 +                    Convert.string2int(strval(prefix), token.radix()));
  16.245              } catch (NumberFormatException ex) {
  16.246 -                error(S.pos(), "int.number.too.large", strval(prefix));
  16.247 +                error(token.pos, "int.number.too.large", strval(prefix));
  16.248              }
  16.249              break;
  16.250          case LONGLITERAL:
  16.251              try {
  16.252                  t = F.at(pos).Literal(
  16.253                      TypeTags.LONG,
  16.254 -                    new Long(Convert.string2long(strval(prefix), S.radix())));
  16.255 +                    new Long(Convert.string2long(strval(prefix), token.radix())));
  16.256              } catch (NumberFormatException ex) {
  16.257 -                error(S.pos(), "int.number.too.large", strval(prefix));
  16.258 +                error(token.pos, "int.number.too.large", strval(prefix));
  16.259              }
  16.260              break;
  16.261          case FLOATLITERAL: {
  16.262 -            String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal());
  16.263 +            String proper = token.radix() == 16 ?
  16.264 +                    ("0x"+ token.stringVal()) :
  16.265 +                    token.stringVal();
  16.266              Float n;
  16.267              try {
  16.268                  n = Float.valueOf(proper);
  16.269 @@ -527,15 +535,17 @@
  16.270                  n = Float.NaN;
  16.271              }
  16.272              if (n.floatValue() == 0.0f && !isZero(proper))
  16.273 -                error(S.pos(), "fp.number.too.small");
  16.274 +                error(token.pos, "fp.number.too.small");
  16.275              else if (n.floatValue() == Float.POSITIVE_INFINITY)
  16.276 -                error(S.pos(), "fp.number.too.large");
  16.277 +                error(token.pos, "fp.number.too.large");
  16.278              else
  16.279                  t = F.at(pos).Literal(TypeTags.FLOAT, n);
  16.280              break;
  16.281          }
  16.282          case DOUBLELITERAL: {
  16.283 -            String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal());
  16.284 +            String proper = token.radix() == 16 ?
  16.285 +                    ("0x"+ token.stringVal()) :
  16.286 +                    token.stringVal();
  16.287              Double n;
  16.288              try {
  16.289                  n = Double.valueOf(proper);
  16.290 @@ -544,9 +554,9 @@
  16.291                  n = Double.NaN;
  16.292              }
  16.293              if (n.doubleValue() == 0.0d && !isZero(proper))
  16.294 -                error(S.pos(), "fp.number.too.small");
  16.295 +                error(token.pos, "fp.number.too.small");
  16.296              else if (n.doubleValue() == Double.POSITIVE_INFINITY)
  16.297 -                error(S.pos(), "fp.number.too.large");
  16.298 +                error(token.pos, "fp.number.too.large");
  16.299              else
  16.300                  t = F.at(pos).Literal(TypeTags.DOUBLE, n);
  16.301              break;
  16.302 @@ -554,17 +564,17 @@
  16.303          case CHARLITERAL:
  16.304              t = F.at(pos).Literal(
  16.305                  TypeTags.CHAR,
  16.306 -                S.stringVal().charAt(0) + 0);
  16.307 +                token.stringVal().charAt(0) + 0);
  16.308              break;
  16.309          case STRINGLITERAL:
  16.310              t = F.at(pos).Literal(
  16.311                  TypeTags.CLASS,
  16.312 -                S.stringVal());
  16.313 +                token.stringVal());
  16.314              break;
  16.315          case TRUE: case FALSE:
  16.316              t = F.at(pos).Literal(
  16.317                  TypeTags.BOOLEAN,
  16.318 -                (S.token() == TRUE ? 1 : 0));
  16.319 +                (token.kind == TRUE ? 1 : 0));
  16.320              break;
  16.321          case NULL:
  16.322              t = F.at(pos).Literal(
  16.323 @@ -576,8 +586,8 @@
  16.324          }
  16.325          if (t == errorTree)
  16.326              t = F.at(pos).Erroneous();
  16.327 -        storeEnd(t, S.endPos());
  16.328 -        S.nextToken();
  16.329 +        storeEnd(t, token.endPos);
  16.330 +        nextToken();
  16.331          return t;
  16.332      }
  16.333  //where
  16.334 @@ -590,7 +600,7 @@
  16.335          }
  16.336  
  16.337          String strval(Name prefix) {
  16.338 -            String s = S.stringVal();
  16.339 +            String s = token.stringVal();
  16.340              return prefix.isEmpty() ? s : prefix + s;
  16.341          }
  16.342  
  16.343 @@ -627,17 +637,17 @@
  16.344      JCExpression term() {
  16.345          JCExpression t = term1();
  16.346          if ((mode & EXPR) != 0 &&
  16.347 -            S.token() == EQ || PLUSEQ.compareTo(S.token()) <= 0 && S.token().compareTo(GTGTGTEQ) <= 0)
  16.348 +            token.kind == EQ || PLUSEQ.compareTo(token.kind) <= 0 && token.kind.compareTo(GTGTGTEQ) <= 0)
  16.349              return termRest(t);
  16.350          else
  16.351              return t;
  16.352      }
  16.353  
  16.354      JCExpression termRest(JCExpression t) {
  16.355 -        switch (S.token()) {
  16.356 +        switch (token.kind) {
  16.357          case EQ: {
  16.358 -            int pos = S.pos();
  16.359 -            S.nextToken();
  16.360 +            int pos = token.pos;
  16.361 +            nextToken();
  16.362              mode = EXPR;
  16.363              JCExpression t1 = term();
  16.364              return toP(F.at(pos).Assign(t, t1));
  16.365 @@ -653,12 +663,12 @@
  16.366          case LTLTEQ:
  16.367          case GTGTEQ:
  16.368          case GTGTGTEQ:
  16.369 -            int pos = S.pos();
  16.370 -            Token token = S.token();
  16.371 -            S.nextToken();
  16.372 +            int pos = token.pos;
  16.373 +            TokenKind tk = token.kind;
  16.374 +            nextToken();
  16.375              mode = EXPR;
  16.376              JCExpression t1 = term();
  16.377 -            return F.at(pos).Assignop(optag(token), t, t1);
  16.378 +            return F.at(pos).Assignop(optag(tk), t, t1);
  16.379          default:
  16.380              return t;
  16.381          }
  16.382 @@ -670,7 +680,7 @@
  16.383       */
  16.384      JCExpression term1() {
  16.385          JCExpression t = term2();
  16.386 -        if ((mode & EXPR) != 0 && S.token() == QUES) {
  16.387 +        if ((mode & EXPR) != 0 && token.kind == QUES) {
  16.388              mode = EXPR;
  16.389              return term1Rest(t);
  16.390          } else {
  16.391 @@ -681,9 +691,9 @@
  16.392      /** Expression1Rest = ["?" Expression ":" Expression1]
  16.393       */
  16.394      JCExpression term1Rest(JCExpression t) {
  16.395 -        if (S.token() == QUES) {
  16.396 -            int pos = S.pos();
  16.397 -            S.nextToken();
  16.398 +        if (token.kind == QUES) {
  16.399 +            int pos = token.pos;
  16.400 +            nextToken();
  16.401              JCExpression t1 = term();
  16.402              accept(COLON);
  16.403              JCExpression t2 = term1();
  16.404 @@ -699,7 +709,7 @@
  16.405       */
  16.406      JCExpression term2() {
  16.407          JCExpression t = term3();
  16.408 -        if ((mode & EXPR) != 0 && prec(S.token()) >= TreeInfo.orPrec) {
  16.409 +        if ((mode & EXPR) != 0 && prec(token.kind) >= TreeInfo.orPrec) {
  16.410              mode = EXPR;
  16.411              return term2Rest(t, TreeInfo.orPrec);
  16.412          } else {
  16.413 @@ -725,28 +735,23 @@
  16.414          JCExpression[] odStack = newOdStack();
  16.415          List<Token[]> savedOp = opStackSupply.elems;
  16.416          Token[] opStack = newOpStack();
  16.417 -        List<int[]> savedPos = posStackSupply.elems;
  16.418 -        int[] posStack = newPosStack();
  16.419 +
  16.420          // optimization, was odStack = new Tree[...]; opStack = new Tree[...];
  16.421          int top = 0;
  16.422          odStack[0] = t;
  16.423 -        int startPos = S.pos();
  16.424 -        Token topOp = ERROR;
  16.425 -        int topOpPos = Position.NOPOS;
  16.426 -        while (prec(S.token()) >= minprec) {
  16.427 -            posStack[top] = topOpPos;
  16.428 +        int startPos = token.pos;
  16.429 +        Token topOp = Tokens.DUMMY;
  16.430 +        while (prec(token.kind) >= minprec) {
  16.431              opStack[top] = topOp;
  16.432              top++;
  16.433 -            topOp = S.token();
  16.434 -            topOpPos = S.pos();
  16.435 -            S.nextToken();
  16.436 -            odStack[top] = (topOp == INSTANCEOF) ? parseType() : term3();
  16.437 -            while (top > 0 && prec(topOp) >= prec(S.token())) {
  16.438 -                odStack[top-1] = makeOp(topOpPos, topOp, odStack[top-1],
  16.439 +            topOp = token;
  16.440 +            nextToken();
  16.441 +            odStack[top] = (topOp.kind == INSTANCEOF) ? parseType() : term3();
  16.442 +            while (top > 0 && prec(topOp.kind) >= prec(token.kind)) {
  16.443 +                odStack[top-1] = makeOp(topOp.pos, topOp.kind, odStack[top-1],
  16.444                                          odStack[top]);
  16.445                  top--;
  16.446                  topOp = opStack[top];
  16.447 -                topOpPos = posStack[top];
  16.448              }
  16.449          }
  16.450          Assert.check(top == 0);
  16.451 @@ -761,14 +766,13 @@
  16.452  
  16.453          odStackSupply.elems = savedOd; // optimization
  16.454          opStackSupply.elems = savedOp; // optimization
  16.455 -        posStackSupply.elems = savedPos; // optimization
  16.456          return t;
  16.457      }
  16.458  //where
  16.459          /** Construct a binary or type test node.
  16.460           */
  16.461          private JCExpression makeOp(int pos,
  16.462 -                                    Token topOp,
  16.463 +                                    TokenKind topOp,
  16.464                                      JCExpression od1,
  16.465                                      JCExpression od2)
  16.466          {
  16.467 @@ -817,7 +821,6 @@
  16.468           */
  16.469          ListBuffer<JCExpression[]> odStackSupply = new ListBuffer<JCExpression[]>();
  16.470          ListBuffer<Token[]> opStackSupply = new ListBuffer<Token[]>();
  16.471 -        ListBuffer<int[]> posStackSupply = new ListBuffer<int[]>();
  16.472  
  16.473          private JCExpression[] newOdStack() {
  16.474              if (odStackSupply.elems == odStackSupply.last)
  16.475 @@ -835,14 +838,6 @@
  16.476              return opStack;
  16.477          }
  16.478  
  16.479 -        private int[] newPosStack() {
  16.480 -            if (posStackSupply.elems == posStackSupply.last)
  16.481 -                posStackSupply.append(new int[infixPrecedenceLevels + 1]);
  16.482 -            int[] posStack = posStackSupply.elems.head;
  16.483 -            posStackSupply.elems = posStackSupply.elems.tail;
  16.484 -            return posStack;
  16.485 -        }
  16.486 -
  16.487      /** Expression3    = PrefixOp Expression3
  16.488       *                 | "(" Expr | TypeNoParams ")" Expression3
  16.489       *                 | Primary {Selector} {PostfixOp}
  16.490 @@ -871,10 +866,10 @@
  16.491       *  SuperSuffix    = Arguments | "." Ident [Arguments]
  16.492       */
  16.493      protected JCExpression term3() {
  16.494 -        int pos = S.pos();
  16.495 +        int pos = token.pos;
  16.496          JCExpression t;
  16.497          List<JCExpression> typeArgs = typeArgumentsOpt(EXPR);
  16.498 -        switch (S.token()) {
  16.499 +        switch (token.kind) {
  16.500          case QUES:
  16.501              if ((mode & TYPE) != 0 && (mode & (TYPEARG|NOPARAMS)) == TYPEARG) {
  16.502                  mode = TYPE;
  16.503 @@ -883,49 +878,49 @@
  16.504                  return illegal();
  16.505          case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB:
  16.506              if (typeArgs == null && (mode & EXPR) != 0) {
  16.507 -                Token token = S.token();
  16.508 -                S.nextToken();
  16.509 +                TokenKind tk = token.kind;
  16.510 +                nextToken();
  16.511                  mode = EXPR;
  16.512 -                if (token == SUB &&
  16.513 -                    (S.token() == INTLITERAL || S.token() == LONGLITERAL) &&
  16.514 -                    S.radix() == 10) {
  16.515 +                if (tk == SUB &&
  16.516 +                    (token.kind == INTLITERAL || token.kind == LONGLITERAL) &&
  16.517 +                    token.radix() == 10) {
  16.518                      mode = EXPR;
  16.519                      t = literal(names.hyphen, pos);
  16.520                  } else {
  16.521                      t = term3();
  16.522 -                    return F.at(pos).Unary(unoptag(token), t);
  16.523 +                    return F.at(pos).Unary(unoptag(tk), t);
  16.524                  }
  16.525              } else return illegal();
  16.526              break;
  16.527          case LPAREN:
  16.528              if (typeArgs == null && (mode & EXPR) != 0) {
  16.529 -                S.nextToken();
  16.530 +                nextToken();
  16.531                  mode = EXPR | TYPE | NOPARAMS;
  16.532                  t = term3();
  16.533 -                if ((mode & TYPE) != 0 && S.token() == LT) {
  16.534 +                if ((mode & TYPE) != 0 && token.kind == LT) {
  16.535                      // Could be a cast to a parameterized type
  16.536                      int op = JCTree.LT;
  16.537 -                    int pos1 = S.pos();
  16.538 -                    S.nextToken();
  16.539 +                    int pos1 = token.pos;
  16.540 +                    nextToken();
  16.541                      mode &= (EXPR | TYPE);
  16.542                      mode |= TYPEARG;
  16.543                      JCExpression t1 = term3();
  16.544                      if ((mode & TYPE) != 0 &&
  16.545 -                        (S.token() == COMMA || S.token() == GT)) {
  16.546 +                        (token.kind == COMMA || token.kind == GT)) {
  16.547                          mode = TYPE;
  16.548                          ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
  16.549                          args.append(t1);
  16.550 -                        while (S.token() == COMMA) {
  16.551 -                            S.nextToken();
  16.552 +                        while (token.kind == COMMA) {
  16.553 +                            nextToken();
  16.554                              args.append(typeArgument());
  16.555                          }
  16.556                          accept(GT);
  16.557                          t = toP(F.at(pos1).TypeApply(t, args.toList()));
  16.558                          checkGenerics();
  16.559 -                        while (S.token() == DOT) {
  16.560 -                            S.nextToken();
  16.561 +                        while (token.kind == DOT) {
  16.562 +                            nextToken();
  16.563                              mode = TYPE;
  16.564 -                            t = toP(F.at(S.pos()).Select(t, ident()));
  16.565 +                            t = toP(F.at(token.pos).Select(t, ident()));
  16.566                              t = typeArgumentsOpt(t);
  16.567                          }
  16.568                          t = bracketsOpt(toP(t));
  16.569 @@ -948,7 +943,7 @@
  16.570                      JCExpression t1 = term3();
  16.571                      return F.at(pos).TypeCast(t, t1);
  16.572                  } else if ((lastmode & TYPE) != 0) {
  16.573 -                    switch (S.token()) {
  16.574 +                    switch (token.kind) {
  16.575                      /*case PLUSPLUS: case SUBSUB: */
  16.576                      case BANG: case TILDE:
  16.577                      case LPAREN: case THIS: case SUPER:
  16.578 @@ -969,7 +964,7 @@
  16.579              if ((mode & EXPR) != 0) {
  16.580                  mode = EXPR;
  16.581                  t = to(F.at(pos).Ident(names._this));
  16.582 -                S.nextToken();
  16.583 +                nextToken();
  16.584                  if (typeArgs == null)
  16.585                      t = argumentsOpt(null, t);
  16.586                  else
  16.587 @@ -997,22 +992,22 @@
  16.588              if (typeArgs != null) return illegal();
  16.589              if ((mode & EXPR) != 0) {
  16.590                  mode = EXPR;
  16.591 -                S.nextToken();
  16.592 -                if (S.token() == LT) typeArgs = typeArguments(false);
  16.593 +                nextToken();
  16.594 +                if (token.kind == LT) typeArgs = typeArguments(false);
  16.595                  t = creator(pos, typeArgs);
  16.596                  typeArgs = null;
  16.597              } else return illegal();
  16.598              break;
  16.599          case IDENTIFIER: case ASSERT: case ENUM:
  16.600              if (typeArgs != null) return illegal();
  16.601 -            t = toP(F.at(S.pos()).Ident(ident()));
  16.602 +            t = toP(F.at(token.pos).Ident(ident()));
  16.603              loop: while (true) {
  16.604 -                pos = S.pos();
  16.605 -                switch (S.token()) {
  16.606 +                pos = token.pos;
  16.607 +                switch (token.kind) {
  16.608                  case LBRACKET:
  16.609 -                    S.nextToken();
  16.610 -                    if (S.token() == RBRACKET) {
  16.611 -                        S.nextToken();
  16.612 +                    nextToken();
  16.613 +                    if (token.kind == RBRACKET) {
  16.614 +                        nextToken();
  16.615                          t = bracketsOpt(t);
  16.616                          t = toP(F.at(pos).TypeArray(t));
  16.617                          t = bracketsSuffix(t);
  16.618 @@ -1033,24 +1028,24 @@
  16.619                      }
  16.620                      break loop;
  16.621                  case DOT:
  16.622 -                    S.nextToken();
  16.623 +                    nextToken();
  16.624                      int oldmode = mode;
  16.625                      mode &= ~NOPARAMS;
  16.626                      typeArgs = typeArgumentsOpt(EXPR);
  16.627                      mode = oldmode;
  16.628                      if ((mode & EXPR) != 0) {
  16.629 -                        switch (S.token()) {
  16.630 +                        switch (token.kind) {
  16.631                          case CLASS:
  16.632                              if (typeArgs != null) return illegal();
  16.633                              mode = EXPR;
  16.634                              t = to(F.at(pos).Select(t, names._class));
  16.635 -                            S.nextToken();
  16.636 +                            nextToken();
  16.637                              break loop;
  16.638                          case THIS:
  16.639                              if (typeArgs != null) return illegal();
  16.640                              mode = EXPR;
  16.641                              t = to(F.at(pos).Select(t, names._this));
  16.642 -                            S.nextToken();
  16.643 +                            nextToken();
  16.644                              break loop;
  16.645                          case SUPER:
  16.646                              mode = EXPR;
  16.647 @@ -1061,9 +1056,9 @@
  16.648                          case NEW:
  16.649                              if (typeArgs != null) return illegal();
  16.650                              mode = EXPR;
  16.651 -                            int pos1 = S.pos();
  16.652 -                            S.nextToken();
  16.653 -                            if (S.token() == LT) typeArgs = typeArguments(false);
  16.654 +                            int pos1 = token.pos;
  16.655 +                            nextToken();
  16.656 +                            if (token.kind == LT) typeArgs = typeArguments(false);
  16.657                              t = innerCreator(pos1, typeArgs, t);
  16.658                              typeArgs = null;
  16.659                              break loop;
  16.660 @@ -1087,8 +1082,8 @@
  16.661          case VOID:
  16.662              if (typeArgs != null) illegal();
  16.663              if ((mode & EXPR) != 0) {
  16.664 -                S.nextToken();
  16.665 -                if (S.token() == DOT) {
  16.666 +                nextToken();
  16.667 +                if (token.kind == DOT) {
  16.668                      JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTags.VOID));
  16.669                      t = bracketsSuffix(ti);
  16.670                  } else {
  16.671 @@ -1099,7 +1094,7 @@
  16.672                  // a void type (like other primitive types) to the next phase.
  16.673                  // The error will be reported in Attr.attribTypes or Attr.visitApply.
  16.674                  JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTags.VOID));
  16.675 -                S.nextToken();
  16.676 +                nextToken();
  16.677                  return ti;
  16.678                  //return illegal();
  16.679              }
  16.680 @@ -1109,14 +1104,14 @@
  16.681          }
  16.682          if (typeArgs != null) illegal();
  16.683          while (true) {
  16.684 -            int pos1 = S.pos();
  16.685 -            if (S.token() == LBRACKET) {
  16.686 -                S.nextToken();
  16.687 +            int pos1 = token.pos;
  16.688 +            if (token.kind == LBRACKET) {
  16.689 +                nextToken();
  16.690                  if ((mode & TYPE) != 0) {
  16.691                      int oldmode = mode;
  16.692                      mode = TYPE;
  16.693 -                    if (S.token() == RBRACKET) {
  16.694 -                        S.nextToken();
  16.695 +                    if (token.kind == RBRACKET) {
  16.696 +                        nextToken();
  16.697                          t = bracketsOpt(t);
  16.698                          t = toP(F.at(pos1).TypeArray(t));
  16.699                          return t;
  16.700 @@ -1129,21 +1124,21 @@
  16.701                      t = to(F.at(pos1).Indexed(t, t1));
  16.702                  }
  16.703                  accept(RBRACKET);
  16.704 -            } else if (S.token() == DOT) {
  16.705 -                S.nextToken();
  16.706 +            } else if (token.kind == DOT) {
  16.707 +                nextToken();
  16.708                  typeArgs = typeArgumentsOpt(EXPR);
  16.709 -                if (S.token() == SUPER && (mode & EXPR) != 0) {
  16.710 +                if (token.kind == SUPER && (mode & EXPR) != 0) {
  16.711                      mode = EXPR;
  16.712                      t = to(F.at(pos1).Select(t, names._super));
  16.713 -                    S.nextToken();
  16.714 +                    nextToken();
  16.715                      t = arguments(typeArgs, t);
  16.716                      typeArgs = null;
  16.717 -                } else if (S.token() == NEW && (mode & EXPR) != 0) {
  16.718 +                } else if (token.kind == NEW && (mode & EXPR) != 0) {
  16.719                      if (typeArgs != null) return illegal();
  16.720                      mode = EXPR;
  16.721 -                    int pos2 = S.pos();
  16.722 -                    S.nextToken();
  16.723 -                    if (S.token() == LT) typeArgs = typeArguments(false);
  16.724 +                    int pos2 = token.pos;
  16.725 +                    nextToken();
  16.726 +                    if (token.kind == LT) typeArgs = typeArguments(false);
  16.727                      t = innerCreator(pos2, typeArgs, t);
  16.728                      typeArgs = null;
  16.729                  } else {
  16.730 @@ -1155,11 +1150,11 @@
  16.731                  break;
  16.732              }
  16.733          }
  16.734 -        while ((S.token() == PLUSPLUS || S.token() == SUBSUB) && (mode & EXPR) != 0) {
  16.735 +        while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) {
  16.736              mode = EXPR;
  16.737 -            t = to(F.at(S.pos()).Unary(
  16.738 -                  S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t));
  16.739 -            S.nextToken();
  16.740 +            t = to(F.at(token.pos).Unary(
  16.741 +                  token.kind == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t));
  16.742 +            nextToken();
  16.743          }
  16.744          return toP(t);
  16.745      }
  16.746 @@ -1167,13 +1162,13 @@
  16.747      /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
  16.748       */
  16.749      JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
  16.750 -        S.nextToken();
  16.751 -        if (S.token() == LPAREN || typeArgs != null) {
  16.752 +        nextToken();
  16.753 +        if (token.kind == LPAREN || typeArgs != null) {
  16.754              t = arguments(typeArgs, t);
  16.755          } else {
  16.756 -            int pos = S.pos();
  16.757 +            int pos = token.pos;
  16.758              accept(DOT);
  16.759 -            typeArgs = (S.token() == LT) ? typeArguments(false) : null;
  16.760 +            typeArgs = (token.kind == LT) ? typeArguments(false) : null;
  16.761              t = toP(F.at(pos).Select(t, ident()));
  16.762              t = argumentsOpt(typeArgs, t);
  16.763          }
  16.764 @@ -1183,15 +1178,15 @@
  16.765      /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN
  16.766       */
  16.767      JCPrimitiveTypeTree basicType() {
  16.768 -        JCPrimitiveTypeTree t = to(F.at(S.pos()).TypeIdent(typetag(S.token())));
  16.769 -        S.nextToken();
  16.770 +        JCPrimitiveTypeTree t = to(F.at(token.pos).TypeIdent(typetag(token.kind)));
  16.771 +        nextToken();
  16.772          return t;
  16.773      }
  16.774  
  16.775      /** ArgumentsOpt = [ Arguments ]
  16.776       */
  16.777      JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) {
  16.778 -        if ((mode & EXPR) != 0 && S.token() == LPAREN || typeArgs != null) {
  16.779 +        if ((mode & EXPR) != 0 && token.kind == LPAREN || typeArgs != null) {
  16.780              mode = EXPR;
  16.781              return arguments(typeArgs, t);
  16.782          } else {
  16.783 @@ -1203,24 +1198,24 @@
  16.784       */
  16.785      List<JCExpression> arguments() {
  16.786          ListBuffer<JCExpression> args = lb();
  16.787 -        if (S.token() == LPAREN) {
  16.788 -            S.nextToken();
  16.789 -            if (S.token() != RPAREN) {
  16.790 +        if (token.kind == LPAREN) {
  16.791 +            nextToken();
  16.792 +            if (token.kind != RPAREN) {
  16.793                  args.append(parseExpression());
  16.794 -                while (S.token() == COMMA) {
  16.795 -                    S.nextToken();
  16.796 +                while (token.kind == COMMA) {
  16.797 +                    nextToken();
  16.798                      args.append(parseExpression());
  16.799                  }
  16.800              }
  16.801              accept(RPAREN);
  16.802          } else {
  16.803 -            syntaxError(S.pos(), "expected", LPAREN);
  16.804 +            syntaxError(token.pos, "expected", LPAREN);
  16.805          }
  16.806          return args.toList();
  16.807      }
  16.808  
  16.809      JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) {
  16.810 -        int pos = S.pos();
  16.811 +        int pos = token.pos;
  16.812          List<JCExpression> args = arguments();
  16.813          return toP(F.at(pos).Apply(typeArgs, t, args));
  16.814      }
  16.815 @@ -1228,7 +1223,7 @@
  16.816      /**  TypeArgumentsOpt = [ TypeArguments ]
  16.817       */
  16.818      JCExpression typeArgumentsOpt(JCExpression t) {
  16.819 -        if (S.token() == LT &&
  16.820 +        if (token.kind == LT &&
  16.821              (mode & TYPE) != 0 &&
  16.822              (mode & NOPARAMS) == 0) {
  16.823              mode = TYPE;
  16.824 @@ -1243,7 +1238,7 @@
  16.825      }
  16.826  
  16.827      List<JCExpression> typeArgumentsOpt(int useMode) {
  16.828 -        if (S.token() == LT) {
  16.829 +        if (token.kind == LT) {
  16.830              checkGenerics();
  16.831              if ((mode & useMode) == 0 ||
  16.832                  (mode & NOPARAMS) != 0) {
  16.833 @@ -1258,47 +1253,37 @@
  16.834      /**  TypeArguments  = "<" TypeArgument {"," TypeArgument} ">"
  16.835       */
  16.836      List<JCExpression> typeArguments(boolean diamondAllowed) {
  16.837 -        if (S.token() == LT) {
  16.838 -            S.nextToken();
  16.839 -            if (S.token() == GT && diamondAllowed) {
  16.840 +        if (token.kind == LT) {
  16.841 +            nextToken();
  16.842 +            if (token.kind == GT && diamondAllowed) {
  16.843                  checkDiamond();
  16.844                  mode |= DIAMOND;
  16.845 -                S.nextToken();
  16.846 +                nextToken();
  16.847                  return List.nil();
  16.848              } else {
  16.849                  ListBuffer<JCExpression> args = ListBuffer.lb();
  16.850                  args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
  16.851 -                while (S.token() == COMMA) {
  16.852 -                    S.nextToken();
  16.853 +                while (token.kind == COMMA) {
  16.854 +                    nextToken();
  16.855                      args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
  16.856                  }
  16.857 -                switch (S.token()) {
  16.858 -                case GTGTGTEQ:
  16.859 -                    S.token(GTGTEQ);
  16.860 -                    break;
  16.861 -                case GTGTEQ:
  16.862 -                    S.token(GTEQ);
  16.863 -                    break;
  16.864 -                case GTEQ:
  16.865 -                    S.token(EQ);
  16.866 -                    break;
  16.867 -                case GTGTGT:
  16.868 -                    S.token(GTGT);
  16.869 -                    break;
  16.870 -                case GTGT:
  16.871 -                    S.token(GT);
  16.872 +                switch (token.kind) {
  16.873 +
  16.874 +                case GTGTGTEQ: case GTGTEQ: case GTEQ:
  16.875 +                case GTGTGT: case GTGT:
  16.876 +                    token = S.split();
  16.877                      break;
  16.878                  case GT:
  16.879 -                    S.nextToken();
  16.880 +                    nextToken();
  16.881                      break;
  16.882                  default:
  16.883 -                    args.append(syntaxError(S.pos(), "expected", GT));
  16.884 +                    args.append(syntaxError(token.pos, "expected", GT));
  16.885                      break;
  16.886                  }
  16.887                  return args.toList();
  16.888              }
  16.889          } else {
  16.890 -            return List.<JCExpression>of(syntaxError(S.pos(), "expected", LT));
  16.891 +            return List.<JCExpression>of(syntaxError(token.pos, "expected", LT));
  16.892          }
  16.893      }
  16.894  
  16.895 @@ -1308,24 +1293,24 @@
  16.896       *               | "?" SUPER Type
  16.897       */
  16.898      JCExpression typeArgument() {
  16.899 -        if (S.token() != QUES) return parseType();
  16.900 -        int pos = S.pos();
  16.901 -        S.nextToken();
  16.902 -        if (S.token() == EXTENDS) {
  16.903 +        if (token.kind != QUES) return parseType();
  16.904 +        int pos = token.pos;
  16.905 +        nextToken();
  16.906 +        if (token.kind == EXTENDS) {
  16.907              TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.EXTENDS));
  16.908 -            S.nextToken();
  16.909 +            nextToken();
  16.910              JCExpression bound = parseType();
  16.911              return F.at(pos).Wildcard(t, bound);
  16.912 -        } else if (S.token() == SUPER) {
  16.913 +        } else if (token.kind == SUPER) {
  16.914              TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.SUPER));
  16.915 -            S.nextToken();
  16.916 +            nextToken();
  16.917              JCExpression bound = parseType();
  16.918              return F.at(pos).Wildcard(t, bound);
  16.919 -        } else if (S.token() == IDENTIFIER) {
  16.920 +        } else if (token.kind == IDENTIFIER) {
  16.921              //error recovery
  16.922              TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
  16.923              JCExpression wc = toP(F.at(pos).Wildcard(t, null));
  16.924 -            JCIdent id = toP(F.at(S.pos()).Ident(ident()));
  16.925 +            JCIdent id = toP(F.at(token.pos).Ident(ident()));
  16.926              JCErroneous err = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
  16.927              reportSyntaxError(err, "expected3", GT, EXTENDS, SUPER);
  16.928              return err;
  16.929 @@ -1336,7 +1321,7 @@
  16.930      }
  16.931  
  16.932      JCTypeApply typeArguments(JCExpression t, boolean diamondAllowed) {
  16.933 -        int pos = S.pos();
  16.934 +        int pos = token.pos;
  16.935          List<JCExpression> args = typeArguments(diamondAllowed);
  16.936          return toP(F.at(pos).TypeApply(t, args));
  16.937      }
  16.938 @@ -1344,9 +1329,9 @@
  16.939      /** BracketsOpt = {"[" "]"}
  16.940       */
  16.941      private JCExpression bracketsOpt(JCExpression t) {
  16.942 -        if (S.token() == LBRACKET) {
  16.943 -            int pos = S.pos();
  16.944 -            S.nextToken();
  16.945 +        if (token.kind == LBRACKET) {
  16.946 +            int pos = token.pos;
  16.947 +            nextToken();
  16.948              t = bracketsOptCont(t, pos);
  16.949              F.at(pos);
  16.950          }
  16.951 @@ -1363,17 +1348,17 @@
  16.952       *  BracketsSuffixType =
  16.953       */
  16.954      JCExpression bracketsSuffix(JCExpression t) {
  16.955 -        if ((mode & EXPR) != 0 && S.token() == DOT) {
  16.956 +        if ((mode & EXPR) != 0 && token.kind == DOT) {
  16.957              mode = EXPR;
  16.958 -            int pos = S.pos();
  16.959 -            S.nextToken();
  16.960 +            int pos = token.pos;
  16.961 +            nextToken();
  16.962              accept(CLASS);
  16.963 -            if (S.pos() == errorEndPos) {
  16.964 +            if (token.pos == errorEndPos) {
  16.965                  // error recovery
  16.966                  Name name = null;
  16.967 -                if (S.token() == IDENTIFIER) {
  16.968 -                    name = S.name();
  16.969 -                    S.nextToken();
  16.970 +                if (token.kind == IDENTIFIER) {
  16.971 +                    name = token.name();
  16.972 +                    nextToken();
  16.973                  } else {
  16.974                      name = names.error;
  16.975                  }
  16.976 @@ -1384,7 +1369,7 @@
  16.977          } else if ((mode & TYPE) != 0) {
  16.978              mode = TYPE;
  16.979          } else {
  16.980 -            syntaxError(S.pos(), "dot.class.expected");
  16.981 +            syntaxError(token.pos, "dot.class.expected");
  16.982          }
  16.983          return t;
  16.984      }
  16.985 @@ -1392,7 +1377,7 @@
  16.986      /** Creator = Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
  16.987       */
  16.988      JCExpression creator(int newpos, List<JCExpression> typeArgs) {
  16.989 -        switch (S.token()) {
  16.990 +        switch (token.kind) {
  16.991          case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
  16.992          case DOUBLE: case BOOLEAN:
  16.993              if (typeArgs == null)
  16.994 @@ -1405,29 +1390,29 @@
  16.995          mode = TYPE;
  16.996          boolean diamondFound = false;
  16.997          int lastTypeargsPos = -1;
  16.998 -        if (S.token() == LT) {
  16.999 +        if (token.kind == LT) {
 16.1000              checkGenerics();
 16.1001 -            lastTypeargsPos = S.pos();
 16.1002 +            lastTypeargsPos = token.pos;
 16.1003              t = typeArguments(t, true);
 16.1004              diamondFound = (mode & DIAMOND) != 0;
 16.1005          }
 16.1006 -        while (S.token() == DOT) {
 16.1007 +        while (token.kind == DOT) {
 16.1008              if (diamondFound) {
 16.1009                  //cannot select after a diamond
 16.1010                  illegal();
 16.1011              }
 16.1012 -            int pos = S.pos();
 16.1013 -            S.nextToken();
 16.1014 +            int pos = token.pos;
 16.1015 +            nextToken();
 16.1016              t = toP(F.at(pos).Select(t, ident()));
 16.1017 -            if (S.token() == LT) {
 16.1018 -                lastTypeargsPos = S.pos();
 16.1019 +            if (token.kind == LT) {
 16.1020 +                lastTypeargsPos = token.pos;
 16.1021                  checkGenerics();
 16.1022                  t = typeArguments(t, true);
 16.1023                  diamondFound = (mode & DIAMOND) != 0;
 16.1024              }
 16.1025          }
 16.1026          mode = oldmode;
 16.1027 -        if (S.token() == LBRACKET) {
 16.1028 +        if (token.kind == LBRACKET) {
 16.1029              JCExpression e = arrayCreatorRest(newpos, t);
 16.1030              if (diamondFound) {
 16.1031                  reportSyntaxError(lastTypeargsPos, "cannot.create.array.with.diamond");
 16.1032 @@ -1441,17 +1426,17 @@
 16.1033                      // modified to improve error recovery.
 16.1034                      pos = typeArgs.head.pos;
 16.1035                  }
 16.1036 -                setErrorEndPos(S.prevEndPos());
 16.1037 +                setErrorEndPos(S.prevToken().endPos);
 16.1038                  JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
 16.1039                  reportSyntaxError(err, "cannot.create.array.with.type.arguments");
 16.1040                  return toP(err);
 16.1041              }
 16.1042              return e;
 16.1043 -        } else if (S.token() == LPAREN) {
 16.1044 +        } else if (token.kind == LPAREN) {
 16.1045              return classCreatorRest(newpos, null, typeArgs, t);
 16.1046          } else {
 16.1047 -            setErrorEndPos(S.pos());
 16.1048 -            reportSyntaxError(S.pos(), "expected2", LPAREN, LBRACKET);
 16.1049 +            setErrorEndPos(token.pos);
 16.1050 +            reportSyntaxError(token.pos, "expected2", LPAREN, LBRACKET);
 16.1051              t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null));
 16.1052              return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
 16.1053          }
 16.1054 @@ -1460,8 +1445,8 @@
 16.1055      /** InnerCreator = Ident [TypeArguments] ClassCreatorRest
 16.1056       */
 16.1057      JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
 16.1058 -        JCExpression t = toP(F.at(S.pos()).Ident(ident()));
 16.1059 -        if (S.token() == LT) {
 16.1060 +        JCExpression t = toP(F.at(token.pos).Ident(ident()));
 16.1061 +        if (token.kind == LT) {
 16.1062              int oldmode = mode;
 16.1063              checkGenerics();
 16.1064              t = typeArguments(t, true);
 16.1065 @@ -1475,23 +1460,23 @@
 16.1066       */
 16.1067      JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
 16.1068          accept(LBRACKET);
 16.1069 -        if (S.token() == RBRACKET) {
 16.1070 +        if (token.kind == RBRACKET) {
 16.1071              accept(RBRACKET);
 16.1072              elemtype = bracketsOpt(elemtype);
 16.1073 -            if (S.token() == LBRACE) {
 16.1074 +            if (token.kind == LBRACE) {
 16.1075                  return arrayInitializer(newpos, elemtype);
 16.1076              } else {
 16.1077                  JCExpression t = toP(F.at(newpos).NewArray(elemtype, List.<JCExpression>nil(), null));
 16.1078 -                return syntaxError(S.pos(), List.<JCTree>of(t), "array.dimension.missing");
 16.1079 +                return syntaxError(token.pos, List.<JCTree>of(t), "array.dimension.missing");
 16.1080              }
 16.1081          } else {
 16.1082              ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
 16.1083              dims.append(parseExpression());
 16.1084              accept(RBRACKET);
 16.1085 -            while (S.token() == LBRACKET) {
 16.1086 -                int pos = S.pos();
 16.1087 -                S.nextToken();
 16.1088 -                if (S.token() == RBRACKET) {
 16.1089 +            while (token.kind == LBRACKET) {
 16.1090 +                int pos = token.pos;
 16.1091 +                nextToken();
 16.1092 +                if (token.kind == RBRACKET) {
 16.1093                      elemtype = bracketsOptCont(elemtype, pos);
 16.1094                  } else {
 16.1095                      dims.append(parseExpression());
 16.1096 @@ -1511,8 +1496,8 @@
 16.1097      {
 16.1098          List<JCExpression> args = arguments();
 16.1099          JCClassDecl body = null;
 16.1100 -        if (S.token() == LBRACE) {
 16.1101 -            int pos = S.pos();
 16.1102 +        if (token.kind == LBRACE) {
 16.1103 +            int pos = token.pos;
 16.1104              List<JCTree> defs = classOrInterfaceBody(names.empty, false);
 16.1105              JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
 16.1106              body = toP(F.at(pos).AnonymousClassDef(mods, defs));
 16.1107 @@ -1525,13 +1510,13 @@
 16.1108      JCExpression arrayInitializer(int newpos, JCExpression t) {
 16.1109          accept(LBRACE);
 16.1110          ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
 16.1111 -        if (S.token() == COMMA) {
 16.1112 -            S.nextToken();
 16.1113 -        } else if (S.token() != RBRACE) {
 16.1114 +        if (token.kind == COMMA) {
 16.1115 +            nextToken();
 16.1116 +        } else if (token.kind != RBRACE) {
 16.1117              elems.append(variableInitializer());
 16.1118 -            while (S.token() == COMMA) {
 16.1119 -                S.nextToken();
 16.1120 -                if (S.token() == RBRACE) break;
 16.1121 +            while (token.kind == COMMA) {
 16.1122 +                nextToken();
 16.1123 +                if (token.kind == RBRACE) break;
 16.1124                  elems.append(variableInitializer());
 16.1125              }
 16.1126          }
 16.1127 @@ -1542,7 +1527,7 @@
 16.1128      /** VariableInitializer = ArrayInitializer | Expression
 16.1129       */
 16.1130      public JCExpression variableInitializer() {
 16.1131 -        return S.token() == LBRACE ? arrayInitializer(S.pos(), null) : parseExpression();
 16.1132 +        return token.kind == LBRACE ? arrayInitializer(token.pos, null) : parseExpression();
 16.1133      }
 16.1134  
 16.1135      /** ParExpression = "(" Expression ")"
 16.1136 @@ -1560,19 +1545,19 @@
 16.1137          accept(LBRACE);
 16.1138          List<JCStatement> stats = blockStatements();
 16.1139          JCBlock t = F.at(pos).Block(flags, stats);
 16.1140 -        while (S.token() == CASE || S.token() == DEFAULT) {
 16.1141 -            syntaxError("orphaned", S.token());
 16.1142 +        while (token.kind == CASE || token.kind == DEFAULT) {
 16.1143 +            syntaxError("orphaned", token.kind);
 16.1144              switchBlockStatementGroups();
 16.1145          }
 16.1146          // the Block node has a field "endpos" for first char of last token, which is
 16.1147          // usually but not necessarily the last char of the last token.
 16.1148 -        t.endpos = S.pos();
 16.1149 +        t.endpos = token.pos;
 16.1150          accept(RBRACE);
 16.1151          return toP(t);
 16.1152      }
 16.1153  
 16.1154      public JCBlock block() {
 16.1155 -        return block(S.pos(), 0);
 16.1156 +        return block(token.pos, 0);
 16.1157      }
 16.1158  
 16.1159      /** BlockStatements = { BlockStatement }
 16.1160 @@ -1588,8 +1573,8 @@
 16.1161          int lastErrPos = -1;
 16.1162          ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
 16.1163          while (true) {
 16.1164 -            int pos = S.pos();
 16.1165 -            switch (S.token()) {
 16.1166 +            int pos = token.pos;
 16.1167 +            switch (token.kind) {
 16.1168              case RBRACE: case CASE: case DEFAULT: case EOF:
 16.1169                  return stats.toList();
 16.1170              case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
 16.1171 @@ -1599,64 +1584,63 @@
 16.1172                  break;
 16.1173              case MONKEYS_AT:
 16.1174              case FINAL: {
 16.1175 -                String dc = S.docComment();
 16.1176 +                String dc = token.docComment;
 16.1177                  JCModifiers mods = modifiersOpt();
 16.1178 -                if (S.token() == INTERFACE ||
 16.1179 -                    S.token() == CLASS ||
 16.1180 -                    allowEnums && S.token() == ENUM) {
 16.1181 +                if (token.kind == INTERFACE ||
 16.1182 +                    token.kind == CLASS ||
 16.1183 +                    allowEnums && token.kind == ENUM) {
 16.1184                      stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
 16.1185                  } else {
 16.1186                      JCExpression t = parseType();
 16.1187                      stats.appendList(variableDeclarators(mods, t,
 16.1188                                                           new ListBuffer<JCStatement>()));
 16.1189                      // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
 16.1190 -                    storeEnd(stats.elems.last(), S.endPos());
 16.1191 +                    storeEnd(stats.elems.last(), token.endPos);
 16.1192                      accept(SEMI);
 16.1193                  }
 16.1194                  break;
 16.1195              }
 16.1196              case ABSTRACT: case STRICTFP: {
 16.1197 -                String dc = S.docComment();
 16.1198 +                String dc = token.docComment;
 16.1199                  JCModifiers mods = modifiersOpt();
 16.1200                  stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
 16.1201                  break;
 16.1202              }
 16.1203              case INTERFACE:
 16.1204              case CLASS:
 16.1205 -                stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
 16.1206 -                                                               S.docComment()));
 16.1207 +                String dc = token.docComment;
 16.1208 +                stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
 16.1209                  break;
 16.1210              case ENUM:
 16.1211              case ASSERT:
 16.1212 -                if (allowEnums && S.token() == ENUM) {
 16.1213 -                    error(S.pos(), "local.enum");
 16.1214 -                    stats.
 16.1215 -                        append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
 16.1216 -                                                                 S.docComment()));
 16.1217 +                if (allowEnums && token.kind == ENUM) {
 16.1218 +                    error(token.pos, "local.enum");
 16.1219 +                    dc = token.docComment;
 16.1220 +                    stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
 16.1221                      break;
 16.1222 -                } else if (allowAsserts && S.token() == ASSERT) {
 16.1223 +                } else if (allowAsserts && token.kind == ASSERT) {
 16.1224                      stats.append(parseStatement());
 16.1225                      break;
 16.1226                  }
 16.1227                  /* fall through to default */
 16.1228              default:
 16.1229 -                Name name = S.name();
 16.1230 +                Token prevToken = token;
 16.1231                  JCExpression t = term(EXPR | TYPE);
 16.1232 -                if (S.token() == COLON && t.getTag() == JCTree.IDENT) {
 16.1233 -                    S.nextToken();
 16.1234 +                if (token.kind == COLON && t.getTag() == JCTree.IDENT) {
 16.1235 +                    nextToken();
 16.1236                      JCStatement stat = parseStatement();
 16.1237 -                    stats.append(F.at(pos).Labelled(name, stat));
 16.1238 +                    stats.append(F.at(pos).Labelled(prevToken.name(), stat));
 16.1239                  } else if ((lastmode & TYPE) != 0 &&
 16.1240 -                           (S.token() == IDENTIFIER ||
 16.1241 -                            S.token() == ASSERT ||
 16.1242 -                            S.token() == ENUM)) {
 16.1243 -                    pos = S.pos();
 16.1244 +                           (token.kind == IDENTIFIER ||
 16.1245 +                            token.kind == ASSERT ||
 16.1246 +                            token.kind == ENUM)) {
 16.1247 +                    pos = token.pos;
 16.1248                      JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
 16.1249                      F.at(pos);
 16.1250                      stats.appendList(variableDeclarators(mods, t,
 16.1251                                                           new ListBuffer<JCStatement>()));
 16.1252                      // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
 16.1253 -                    storeEnd(stats.elems.last(), S.endPos());
 16.1254 +                    storeEnd(stats.elems.last(), token.endPos);
 16.1255                      accept(SEMI);
 16.1256                  } else {
 16.1257                      // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
 16.1258 @@ -1666,15 +1650,12 @@
 16.1259              }
 16.1260  
 16.1261              // error recovery
 16.1262 -            if (S.pos() == lastErrPos)
 16.1263 +            if (token.pos == lastErrPos)
 16.1264                  return stats.toList();
 16.1265 -            if (S.pos() <= errorEndPos) {
 16.1266 +            if (token.pos <= errorEndPos) {
 16.1267                  skip(false, true, true, true);
 16.1268 -                lastErrPos = S.pos();
 16.1269 +                lastErrPos = token.pos;
 16.1270              }
 16.1271 -
 16.1272 -            // ensure no dangling /** @deprecated */ active
 16.1273 -            S.resetDeprecatedFlag();
 16.1274          }
 16.1275      }
 16.1276  
 16.1277 @@ -1700,29 +1681,29 @@
 16.1278       */
 16.1279      @SuppressWarnings("fallthrough")
 16.1280      public JCStatement parseStatement() {
 16.1281 -        int pos = S.pos();
 16.1282 -        switch (S.token()) {
 16.1283 +        int pos = token.pos;
 16.1284 +        switch (token.kind) {
 16.1285          case LBRACE:
 16.1286              return block();
 16.1287          case IF: {
 16.1288 -            S.nextToken();
 16.1289 +            nextToken();
 16.1290              JCExpression cond = parExpression();
 16.1291              JCStatement thenpart = parseStatement();
 16.1292              JCStatement elsepart = null;
 16.1293 -            if (S.token() == ELSE) {
 16.1294 -                S.nextToken();
 16.1295 +            if (token.kind == ELSE) {
 16.1296 +                nextToken();
 16.1297                  elsepart = parseStatement();
 16.1298              }
 16.1299              return F.at(pos).If(cond, thenpart, elsepart);
 16.1300          }
 16.1301          case FOR: {
 16.1302 -            S.nextToken();
 16.1303 +            nextToken();
 16.1304              accept(LPAREN);
 16.1305 -            List<JCStatement> inits = S.token() == SEMI ? List.<JCStatement>nil() : forInit();
 16.1306 +            List<JCStatement> inits = token.kind == SEMI ? List.<JCStatement>nil() : forInit();
 16.1307              if (inits.length() == 1 &&
 16.1308                  inits.head.getTag() == JCTree.VARDEF &&
 16.1309                  ((JCVariableDecl) inits.head).init == null &&
 16.1310 -                S.token() == COLON) {
 16.1311 +                token.kind == COLON) {
 16.1312                  checkForeach();
 16.1313                  JCVariableDecl var = (JCVariableDecl)inits.head;
 16.1314                  accept(COLON);
 16.1315 @@ -1732,22 +1713,22 @@
 16.1316                  return F.at(pos).ForeachLoop(var, expr, body);
 16.1317              } else {
 16.1318                  accept(SEMI);
 16.1319 -                JCExpression cond = S.token() == SEMI ? null : parseExpression();
 16.1320 +                JCExpression cond = token.kind == SEMI ? null : parseExpression();
 16.1321                  accept(SEMI);
 16.1322 -                List<JCExpressionStatement> steps = S.token() == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
 16.1323 +                List<JCExpressionStatement> steps = token.kind == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
 16.1324                  accept(RPAREN);
 16.1325                  JCStatement body = parseStatement();
 16.1326                  return F.at(pos).ForLoop(inits, cond, steps, body);
 16.1327              }
 16.1328          }
 16.1329          case WHILE: {
 16.1330 -            S.nextToken();
 16.1331 +            nextToken();
 16.1332              JCExpression cond = parExpression();
 16.1333              JCStatement body = parseStatement();
 16.1334              return F.at(pos).WhileLoop(cond, body);
 16.1335          }
 16.1336          case DO: {
 16.1337 -            S.nextToken();
 16.1338 +            nextToken();
 16.1339              JCStatement body = parseStatement();
 16.1340              accept(WHILE);
 16.1341              JCExpression cond = parExpression();
 16.1342 @@ -1756,21 +1737,21 @@
 16.1343              return t;
 16.1344          }
 16.1345          case TRY: {
 16.1346 -            S.nextToken();
 16.1347 +            nextToken();
 16.1348              List<JCTree> resources = List.<JCTree>nil();
 16.1349 -            if (S.token() == LPAREN) {
 16.1350 +            if (token.kind == LPAREN) {
 16.1351                  checkTryWithResources();
 16.1352 -                S.nextToken();
 16.1353 +                nextToken();
 16.1354                  resources = resources();
 16.1355                  accept(RPAREN);
 16.1356              }
 16.1357              JCBlock body = block();
 16.1358              ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
 16.1359              JCBlock finalizer = null;
 16.1360 -            if (S.token() == CATCH || S.token() == FINALLY) {
 16.1361 -                while (S.token() == CATCH) catchers.append(catchClause());
 16.1362 -                if (S.token() == FINALLY) {
 16.1363 -                    S.nextToken();
 16.1364 +            if (token.kind == CATCH || token.kind == FINALLY) {
 16.1365 +                while (token.kind == CATCH) catchers.append(catchClause());
 16.1366 +                if (token.kind == FINALLY) {
 16.1367 +                    nextToken();
 16.1368                      finalizer = block();
 16.1369                  }
 16.1370              } else {
 16.1371 @@ -1783,7 +1764,7 @@
 16.1372              return F.at(pos).Try(resources, body, catchers.toList(), finalizer);
 16.1373          }
 16.1374          case SWITCH: {
 16.1375 -            S.nextToken();
 16.1376 +            nextToken();
 16.1377              JCExpression selector = parExpression();
 16.1378              accept(LBRACE);
 16.1379              List<JCCase> cases = switchBlockStatementGroups();
 16.1380 @@ -1792,41 +1773,41 @@
 16.1381              return t;
 16.1382          }
 16.1383          case SYNCHRONIZED: {
 16.1384 -            S.nextToken();
 16.1385 +            nextToken();
 16.1386              JCExpression lock = parExpression();
 16.1387              JCBlock body = block();
 16.1388              return F.at(pos).Synchronized(lock, body);
 16.1389          }
 16.1390          case RETURN: {
 16.1391 -            S.nextToken();
 16.1392 -            JCExpression result = S.token() == SEMI ? null : parseExpression();
 16.1393 +            nextToken();
 16.1394 +            JCExpression result = token.kind == SEMI ? null : parseExpression();
 16.1395              JCReturn t = to(F.at(pos).Return(result));
 16.1396              accept(SEMI);
 16.1397              return t;
 16.1398          }
 16.1399          case THROW: {
 16.1400 -            S.nextToken();
 16.1401 +            nextToken();
 16.1402              JCExpression exc = parseExpression();
 16.1403              JCThrow t = to(F.at(pos).Throw(exc));
 16.1404              accept(SEMI);
 16.1405              return t;
 16.1406          }
 16.1407          case BREAK: {
 16.1408 -            S.nextToken();
 16.1409 -            Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
 16.1410 +            nextToken();
 16.1411 +            Name label = (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM) ? ident() : null;
 16.1412              JCBreak t = to(F.at(pos).Break(label));
 16.1413              accept(SEMI);
 16.1414              return t;
 16.1415          }
 16.1416          case CONTINUE: {
 16.1417 -            S.nextToken();
 16.1418 -            Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
 16.1419 +            nextToken();
 16.1420 +            Name label = (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM) ? ident() : null;
 16.1421              JCContinue t =  to(F.at(pos).Continue(label));
 16.1422              accept(SEMI);
 16.1423              return t;
 16.1424          }
 16.1425          case SEMI:
 16.1426 -            S.nextToken();
 16.1427 +            nextToken();
 16.1428              return toP(F.at(pos).Skip());
 16.1429          case ELSE:
 16.1430              return toP(F.Exec(syntaxError("else.without.if")));
 16.1431 @@ -1835,12 +1816,12 @@
 16.1432          case CATCH:
 16.1433              return toP(F.Exec(syntaxError("catch.without.try")));
 16.1434          case ASSERT: {
 16.1435 -            if (allowAsserts && S.token() == ASSERT) {
 16.1436 -                S.nextToken();
 16.1437 +            if (allowAsserts && token.kind == ASSERT) {
 16.1438 +                nextToken();
 16.1439                  JCExpression assertion = parseExpression();
 16.1440                  JCExpression message = null;
 16.1441 -                if (S.token() == COLON) {
 16.1442 -                    S.nextToken();
 16.1443 +                if (token.kind == COLON) {
 16.1444 +                    nextToken();
 16.1445                      message = parseExpression();
 16.1446                  }
 16.1447                  JCAssert t = to(F.at(pos).Assert(assertion, message));
 16.1448 @@ -1851,12 +1832,12 @@
 16.1449          }
 16.1450          case ENUM:
 16.1451          default:
 16.1452 -            Name name = S.name();
 16.1453 +            Token prevToken = token;
 16.1454              JCExpression expr = parseExpression();
 16.1455 -            if (S.token() == COLON && expr.getTag() == JCTree.IDENT) {
 16.1456 -                S.nextToken();
 16.1457 +            if (token.kind == COLON && expr.getTag() == JCTree.IDENT) {
 16.1458 +                nextToken();
 16.1459                  JCStatement stat = parseStatement();
 16.1460 -                return F.at(pos).Labelled(name, stat);
 16.1461 +                return F.at(pos).Labelled(prevToken.name(), stat);
 16.1462              } else {
 16.1463                  // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
 16.1464                  JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr)));
 16.1465 @@ -1869,7 +1850,7 @@
 16.1466      /** CatchClause     = CATCH "(" FormalParameter ")" Block
 16.1467       */
 16.1468      protected JCCatch catchClause() {
 16.1469 -        int pos = S.pos();
 16.1470 +        int pos = token.pos;
 16.1471          accept(CATCH);
 16.1472          accept(LPAREN);
 16.1473          JCModifiers mods = optFinal(Flags.PARAMETER);
 16.1474 @@ -1886,9 +1867,9 @@
 16.1475      List<JCExpression> catchTypes() {
 16.1476          ListBuffer<JCExpression> catchTypes = ListBuffer.lb();
 16.1477          catchTypes.add(parseType());
 16.1478 -        while (S.token() == BAR) {
 16.1479 +        while (token.kind == BAR) {
 16.1480              checkMulticatch();
 16.1481 -            S.nextToken();
 16.1482 +            nextToken();
 16.1483              catchTypes.add(qualident());
 16.1484          }
 16.1485          return catchTypes.toList();
 16.1486 @@ -1901,33 +1882,33 @@
 16.1487      List<JCCase> switchBlockStatementGroups() {
 16.1488          ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
 16.1489          while (true) {
 16.1490 -            int pos = S.pos();
 16.1491 -            switch (S.token()) {
 16.1492 +            int pos = token.pos;
 16.1493 +            switch (token.kind) {
 16.1494              case CASE: {
 16.1495 -                S.nextToken();
 16.1496 +                nextToken();
 16.1497                  JCExpression pat = parseExpression();
 16.1498                  accept(COLON);
 16.1499                  List<JCStatement> stats = blockStatements();
 16.1500                  JCCase c = F.at(pos).Case(pat, stats);
 16.1501                  if (stats.isEmpty())
 16.1502 -                    storeEnd(c, S.prevEndPos());
 16.1503 +                    storeEnd(c, S.prevToken().endPos);
 16.1504                  cases.append(c);
 16.1505                  break;
 16.1506              }
 16.1507              case DEFAULT: {
 16.1508 -                S.nextToken();
 16.1509 +                nextToken();
 16.1510                  accept(COLON);
 16.1511                  List<JCStatement> stats = blockStatements();
 16.1512                  JCCase c = F.at(pos).Case(null, stats);
 16.1513                  if (stats.isEmpty())
 16.1514 -                    storeEnd(c, S.prevEndPos());
 16.1515 +                    storeEnd(c, S.prevToken().endPos);
 16.1516                  cases.append(c);
 16.1517                  break;
 16.1518              }
 16.1519              case RBRACE: case EOF:
 16.1520                  return cases.toList();
 16.1521              default:
 16.1522 -                S.nextToken(); // to ensure progress
 16.1523 +                nextToken(); // to ensure progress
 16.1524                  syntaxError(pos, "expected3",
 16.1525                      CASE, DEFAULT, RBRACE);
 16.1526              }
 16.1527 @@ -1941,9 +1922,9 @@
 16.1528                                                                      T stats) {
 16.1529          // This Exec is a "StatementExpression"; it subsumes no terminating token
 16.1530          stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
 16.1531 -        while (S.token() == COMMA) {
 16.1532 -            S.nextToken();
 16.1533 -            pos = S.pos();
 16.1534 +        while (token.kind == COMMA) {
 16.1535 +            nextToken();
 16.1536 +            pos = token.pos;
 16.1537              JCExpression t = parseExpression();
 16.1538              // This Exec is a "StatementExpression"; it subsumes no terminating token
 16.1539              stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
 16.1540 @@ -1956,13 +1937,13 @@
 16.1541       */
 16.1542      List<JCStatement> forInit() {
 16.1543          ListBuffer<JCStatement> stats = lb();
 16.1544 -        int pos = S.pos();
 16.1545 -        if (S.token() == FINAL || S.token() == MONKEYS_AT) {
 16.1546 +        int pos = token.pos;
 16.1547 +        if (token.kind == FINAL || token.kind == MONKEYS_AT) {
 16.1548              return variableDeclarators(optFinal(0), parseType(), stats).toList();
 16.1549          } else {
 16.1550              JCExpression t = term(EXPR | TYPE);
 16.1551              if ((lastmode & TYPE) != 0 &&
 16.1552 -                (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM))
 16.1553 +                (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM))
 16.1554                  return variableDeclarators(modifiersOpt(), t, stats).toList();
 16.1555              else
 16.1556                  return moreStatementExpressions(pos, t, stats).toList();
 16.1557 @@ -1972,7 +1953,7 @@
 16.1558      /** ForUpdate = StatementExpression MoreStatementExpressions
 16.1559       */
 16.1560      List<JCExpressionStatement> forUpdate() {
 16.1561 -        return moreStatementExpressions(S.pos(),
 16.1562 +        return moreStatementExpressions(token.pos,
 16.1563                                          parseExpression(),
 16.1564                                          new ListBuffer<JCExpressionStatement>()).toList();
 16.1565      }
 16.1566 @@ -1980,11 +1961,11 @@
 16.1567      /** AnnotationsOpt = { '@' Annotation }
 16.1568       */
 16.1569      List<JCAnnotation> annotationsOpt() {
 16.1570 -        if (S.token() != MONKEYS_AT) return List.nil(); // optimization
 16.1571 +        if (token.kind != MONKEYS_AT) return List.nil(); // optimization
 16.1572          ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
 16.1573 -        while (S.token() == MONKEYS_AT) {
 16.1574 -            int pos = S.pos();
 16.1575 -            S.nextToken();
 16.1576 +        while (token.kind == MONKEYS_AT) {
 16.1577 +            int pos = token.pos;
 16.1578 +            nextToken();
 16.1579              buf.append(annotation(pos));
 16.1580          }
 16.1581          return buf.toList();
 16.1582 @@ -2004,21 +1985,20 @@
 16.1583          int pos;
 16.1584          if (partial == null) {
 16.1585              flags = 0;
 16.1586 -            pos = S.pos();
 16.1587 +            pos = token.pos;
 16.1588          } else {
 16.1589              flags = partial.flags;
 16.1590              annotations.appendList(partial.annotations);
 16.1591              pos = partial.pos;
 16.1592          }
 16.1593 -        if (S.deprecatedFlag()) {
 16.1594 +        if (token.deprecatedFlag) {
 16.1595              flags |= Flags.DEPRECATED;
 16.1596 -            S.resetDeprecatedFlag();
 16.1597          }
 16.1598          int lastPos = Position.NOPOS;
 16.1599      loop:
 16.1600          while (true) {
 16.1601              long flag;
 16.1602 -            switch (S.token()) {
 16.1603 +            switch (token.kind) {
 16.1604              case PRIVATE     : flag = Flags.PRIVATE; break;
 16.1605              case PROTECTED   : flag = Flags.PROTECTED; break;
 16.1606              case PUBLIC      : flag = Flags.PUBLIC; break;
 16.1607 @@ -2031,15 +2011,15 @@
 16.1608              case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
 16.1609              case STRICTFP    : flag = Flags.STRICTFP; break;
 16.1610              case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
 16.1611 -            case ERROR       : flag = 0; S.nextToken(); break;
 16.1612 +            case ERROR       : flag = 0; nextToken(); break;
 16.1613              default: break loop;
 16.1614              }
 16.1615 -            if ((flags & flag) != 0) error(S.pos(), "repeated.modifier");
 16.1616 -            lastPos = S.pos();
 16.1617 -            S.nextToken();
 16.1618 +            if ((flags & flag) != 0) error(token.pos, "repeated.modifier");
 16.1619 +            lastPos = token.pos;
 16.1620 +            nextToken();
 16.1621              if (flag == Flags.ANNOTATION) {
 16.1622                  checkAnnotations();
 16.1623 -                if (S.token() != INTERFACE) {
 16.1624 +                if (token.kind != INTERFACE) {
 16.1625                      JCAnnotation ann = annotation(lastPos);
 16.1626                      // if first modifier is an annotation, set pos to annotation's.
 16.1627                      if (flags == 0 && annotations.isEmpty())
 16.1628 @@ -2051,7 +2031,7 @@
 16.1629              }
 16.1630              flags |= flag;
 16.1631          }
 16.1632 -        switch (S.token()) {
 16.1633 +        switch (token.kind) {
 16.1634          case ENUM: flags |= Flags.ENUM; break;
 16.1635          case INTERFACE: flags |= Flags.INTERFACE; break;
 16.1636          default: break;
 16.1637 @@ -2064,7 +2044,7 @@
 16.1638  
 16.1639          JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
 16.1640          if (pos != Position.NOPOS)
 16.1641 -            storeEnd(mods, S.prevEndPos());
 16.1642 +            storeEnd(mods, S.prevToken().endPos);
 16.1643          return mods;
 16.1644      }
 16.1645  
 16.1646 @@ -2077,22 +2057,22 @@
 16.1647          JCTree ident = qualident();
 16.1648          List<JCExpression> fieldValues = annotationFieldValuesOpt();
 16.1649          JCAnnotation ann = F.at(pos).Annotation(ident, fieldValues);
 16.1650 -        storeEnd(ann, S.prevEndPos());
 16.1651 +        storeEnd(ann, S.prevToken().endPos);
 16.1652          return ann;
 16.1653      }
 16.1654  
 16.1655      List<JCExpression> annotationFieldValuesOpt() {
 16.1656 -        return (S.token() == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil();
 16.1657 +        return (token.kind == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil();
 16.1658      }
 16.1659  
 16.1660      /** AnnotationFieldValues   = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
 16.1661      List<JCExpression> annotationFieldValues() {
 16.1662          accept(LPAREN);
 16.1663          ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
 16.1664 -        if (S.token() != RPAREN) {
 16.1665 +        if (token.kind != RPAREN) {
 16.1666              buf.append(annotationFieldValue());
 16.1667 -            while (S.token() == COMMA) {
 16.1668 -                S.nextToken();
 16.1669 +            while (token.kind == COMMA) {
 16.1670 +                nextToken();
 16.1671                  buf.append(annotationFieldValue());
 16.1672              }
 16.1673          }
 16.1674 @@ -2104,11 +2084,11 @@
 16.1675       *                          | Identifier "=" AnnotationValue
 16.1676       */
 16.1677      JCExpression annotationFieldValue() {
 16.1678 -        if (S.token() == IDENTIFIER) {
 16.1679 +        if (token.kind == IDENTIFIER) {
 16.1680              mode = EXPR;
 16.1681              JCExpression t1 = term1();
 16.1682 -            if (t1.getTag() == JCTree.IDENT && S.token() == EQ) {
 16.1683 -                int pos = S.pos();
 16.1684 +            if (t1.getTag() == JCTree.IDENT && token.kind == EQ) {
 16.1685 +                int pos = token.pos;
 16.1686                  accept(EQ);
 16.1687                  JCExpression v = annotationValue();
 16.1688                  return toP(F.at(pos).Assign(t1, v));
 16.1689 @@ -2125,20 +2105,20 @@
 16.1690       */
 16.1691      JCExpression annotationValue() {
 16.1692          int pos;
 16.1693 -        switch (S.token()) {
 16.1694 +        switch (token.kind) {
 16.1695          case MONKEYS_AT:
 16.1696 -            pos = S.pos();
 16.1697 -            S.nextToken();
 16.1698 +            pos = token.pos;
 16.1699 +            nextToken();
 16.1700              return annotation(pos);
 16.1701          case LBRACE:
 16.1702 -            pos = S.pos();
 16.1703 +            pos = token.pos;
 16.1704              accept(LBRACE);
 16.1705              ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
 16.1706 -            if (S.token() != RBRACE) {
 16.1707 +            if (token.kind != RBRACE) {
 16.1708                  buf.append(annotationValue());
 16.1709 -                while (S.token() == COMMA) {
 16.1710 -                    S.nextToken();
 16.1711 -                    if (S.token() == RBRACE) break;
 16.1712 +                while (token.kind == COMMA) {
 16.1713 +                    nextToken();
 16.1714 +                    if (token.kind == RBRACE) break;
 16.1715                      buf.append(annotationValue());
 16.1716                  }
 16.1717              }
 16.1718 @@ -2156,7 +2136,7 @@
 16.1719                                                                           JCExpression type,
 16.1720                                                                           T vdefs)
 16.1721      {
 16.1722 -        return variableDeclaratorsRest(S.pos(), mods, type, ident(), false, null, vdefs);
 16.1723 +        return variableDeclaratorsRest(token.pos, mods, type, ident(), false, null, vdefs);
 16.1724      }
 16.1725  
 16.1726      /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
 16.1727 @@ -2174,10 +2154,10 @@
 16.1728                                                                       T vdefs)
 16.1729      {
 16.1730          vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc));
 16.1731 -        while (S.token() == COMMA) {
 16.1732 +        while (token.kind == COMMA) {
 16.1733              // All but last of multiple declarators subsume a comma
 16.1734 -            storeEnd((JCTree)vdefs.elems.last(), S.endPos());
 16.1735 -            S.nextToken();
 16.1736 +            storeEnd((JCTree)vdefs.elems.last(), token.endPos);
 16.1737 +            nextToken();
 16.1738              vdefs.append(variableDeclarator(mods, type, reqInit, dc));
 16.1739          }
 16.1740          return vdefs;
 16.1741 @@ -2187,7 +2167,7 @@
 16.1742       *  ConstantDeclarator = Ident ConstantDeclaratorRest
 16.1743       */
 16.1744      JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, String dc) {
 16.1745 -        return variableDeclaratorRest(S.pos(), mods, type, ident(), reqInit, dc);
 16.1746 +        return variableDeclaratorRest(token.pos, mods, type, ident(), reqInit, dc);
 16.1747      }
 16.1748  
 16.1749      /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
 16.1750 @@ -2200,11 +2180,11 @@
 16.1751                                    boolean reqInit, String dc) {
 16.1752          type = bracketsOpt(type);
 16.1753          JCExpression init = null;
 16.1754 -        if (S.token() == EQ) {
 16.1755 -            S.nextToken();
 16.1756 +        if (token.kind == EQ) {
 16.1757 +            nextToken();
 16.1758              init = variableInitializer();
 16.1759          }
 16.1760 -        else if (reqInit) syntaxError(S.pos(), "expected", EQ);
 16.1761 +        else if (reqInit) syntaxError(token.pos, "expected", EQ);
 16.1762          JCVariableDecl result =
 16.1763              toP(F.at(pos).VarDef(mods, name, type, init));
 16.1764          attach(result, dc);
 16.1765 @@ -2214,11 +2194,11 @@
 16.1766      /** VariableDeclaratorId = Ident BracketsOpt
 16.1767       */
 16.1768      JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
 16.1769 -        int pos = S.pos();
 16.1770 +        int pos = token.pos;
 16.1771          Name name = ident();
 16.1772          if ((mods.flags & Flags.VARARGS) != 0 &&
 16.1773 -                S.token() == LBRACKET) {
 16.1774 -            log.error(S.pos(), "varargs.and.old.array.syntax");
 16.1775 +                token.kind == LBRACKET) {
 16.1776 +            log.error(token.pos, "varargs.and.old.array.syntax");
 16.1777          }
 16.1778          type = bracketsOpt(type);
 16.1779          return toP(F.at(pos).VarDef(mods, name, type, null));
 16.1780 @@ -2229,12 +2209,12 @@
 16.1781      List<JCTree> resources() {
 16.1782          ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
 16.1783          defs.append(resource());
 16.1784 -        while (S.token() == SEMI) {
 16.1785 +        while (token.kind == SEMI) {
 16.1786              // All but last of multiple declarators must subsume a semicolon
 16.1787 -            storeEnd(defs.elems.last(), S.endPos());
 16.1788 -            int semiColonPos = S.pos();
 16.1789 -            S.nextToken();
 16.1790 -            if (S.token() == RPAREN) { // Optional trailing semicolon
 16.1791 +            storeEnd(defs.elems.last(), token.endPos);
 16.1792 +            int semiColonPos = token.pos;
 16.1793 +            nextToken();
 16.1794 +            if (token.kind == RPAREN) { // Optional trailing semicolon
 16.1795                                         // after last resource
 16.1796                  break;
 16.1797              }
 16.1798 @@ -2248,7 +2228,7 @@
 16.1799      protected JCTree resource() {
 16.1800          JCModifiers optFinal = optFinal(Flags.FINAL);
 16.1801          JCExpression type = parseType();
 16.1802 -        int pos = S.pos();
 16.1803 +        int pos = token.pos;
 16.1804          Name ident = ident();
 16.1805          return variableDeclaratorRest(pos, optFinal, type, ident, true, null);
 16.1806      }
 16.1807 @@ -2256,54 +2236,61 @@
 16.1808      /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
 16.1809       */
 16.1810      public JCTree.JCCompilationUnit parseCompilationUnit() {
 16.1811 -        int pos = S.pos();
 16.1812 +        Token firstToken = token;
 16.1813          JCExpression pid = null;
 16.1814 -        String dc = S.docComment();
 16.1815          JCModifiers mods = null;
 16.1816 +        boolean consumedToplevelDoc = false;
 16.1817 +        boolean seenImport = false;
 16.1818 +        boolean seenPackage = false;
 16.1819          List<JCAnnotation> packageAnnotations = List.nil();
 16.1820 -        if (S.token() == MONKEYS_AT)
 16.1821 +        if (token.kind == MONKEYS_AT)
 16.1822              mods = modifiersOpt();
 16.1823  
 16.1824 -        if (S.token() == PACKAGE) {
 16.1825 +        if (token.kind == PACKAGE) {
 16.1826 +            seenPackage = true;
 16.1827              if (mods != null) {
 16.1828                  checkNoMods(mods.flags);
 16.1829                  packageAnnotations = mods.annotations;
 16.1830                  mods = null;
 16.1831              }
 16.1832 -            S.nextToken();
 16.1833 +            nextToken();
 16.1834              pid = qualident();
 16.1835              accept(SEMI);
 16.1836          }
 16.1837          ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
 16.1838          boolean checkForImports = true;
 16.1839 -        while (S.token() != EOF) {
 16.1840 -            if (S.pos() <= errorEndPos) {
 16.1841 +        boolean firstTypeDecl = true;
 16.1842 +        while (token.kind != EOF) {
 16.1843 +            if (token.pos <= errorEndPos) {
 16.1844                  // error recovery
 16.1845                  skip(checkForImports, false, false, false);
 16.1846 -                if (S.token() == EOF)
 16.1847 +                if (token.kind == EOF)
 16.1848                      break;
 16.1849              }
 16.1850 -            if (checkForImports && mods == null && S.token() == IMPORT) {
 16.1851 +            if (checkForImports && mods == null && token.kind == IMPORT) {
 16.1852 +                seenImport = true;
 16.1853                  defs.append(importDeclaration());
 16.1854              } else {
 16.1855 -                JCTree def = typeDeclaration(mods);
 16.1856 -                if (keepDocComments && dc != null && docComments.get(def) == dc) {
 16.1857 -                    // If the first type declaration has consumed the first doc
 16.1858 -                    // comment, then don't use it for the top level comment as well.
 16.1859 -                    dc = null;
 16.1860 +                String docComment = token.docComment;
 16.1861 +                if (firstTypeDecl && !seenImport && !seenPackage) {
 16.1862 +                    docComment = firstToken.docComment;
 16.1863 +                    consumedToplevelDoc = true;
 16.1864                  }
 16.1865 +                JCTree def = typeDeclaration(mods, docComment);
 16.1866                  if (def instanceof JCExpressionStatement)
 16.1867                      def = ((JCExpressionStatement)def).expr;
 16.1868                  defs.append(def);
 16.1869                  if (def instanceof JCClassDecl)
 16.1870                      checkForImports = false;
 16.1871                  mods = null;
 16.1872 +                firstTypeDecl = false;
 16.1873              }
 16.1874          }
 16.1875 -        JCTree.JCCompilationUnit toplevel = F.at(pos).TopLevel(packageAnnotations, pid, defs.toList());
 16.1876 -        attach(toplevel, dc);
 16.1877 +        JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(packageAnnotations, pid, defs.toList());
 16.1878 +        if (!consumedToplevelDoc)
 16.1879 +            attach(toplevel, firstToken.docComment);
 16.1880          if (defs.elems.isEmpty())
 16.1881 -            storeEnd(toplevel, S.prevEndPos());
 16.1882 +            storeEnd(toplevel, S.prevToken().endPos);
 16.1883          if (keepDocComments)
 16.1884              toplevel.docComments = docComments;
 16.1885          if (keepLineMap)
 16.1886 @@ -2314,26 +2301,26 @@
 16.1887      /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
 16.1888       */
 16.1889      JCTree importDeclaration() {
 16.1890 -        int pos = S.pos();
 16.1891 -        S.nextToken();
 16.1892 +        int pos = token.pos;
 16.1893 +        nextToken();
 16.1894          boolean importStatic = false;
 16.1895 -        if (S.token() == STATIC) {
 16.1896 +        if (token.kind == STATIC) {
 16.1897              checkStaticImports();
 16.1898              importStatic = true;
 16.1899 -            S.nextToken();
 16.1900 +            nextToken();
 16.1901          }
 16.1902 -        JCExpression pid = toP(F.at(S.pos()).Ident(ident()));
 16.1903 +        JCExpression pid = toP(F.at(token.pos).Ident(ident()));
 16.1904          do {
 16.1905 -            int pos1 = S.pos();
 16.1906 +            int pos1 = token.pos;
 16.1907              accept(DOT);
 16.1908 -            if (S.token() == STAR) {
 16.1909 +            if (token.kind == STAR) {
 16.1910                  pid = to(F.at(pos1).Select(pid, names.asterisk));
 16.1911 -                S.nextToken();
 16.1912 +                nextToken();
 16.1913                  break;
 16.1914              } else {
 16.1915                  pid = toP(F.at(pos1).Select(pid, ident()));
 16.1916              }
 16.1917 -        } while (S.token() == DOT);
 16.1918 +        } while (token.kind == DOT);
 16.1919          accept(SEMI);
 16.1920          return toP(F.at(pos).Import(pid, importStatic));
 16.1921      }
 16.1922 @@ -2341,14 +2328,13 @@
 16.1923      /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
 16.1924       *                  | ";"
 16.1925       */
 16.1926 -    JCTree typeDeclaration(JCModifiers mods) {
 16.1927 -        int pos = S.pos();
 16.1928 -        if (mods == null && S.token() == SEMI) {
 16.1929 -            S.nextToken();
 16.1930 +    JCTree typeDeclaration(JCModifiers mods, String docComment) {
 16.1931 +        int pos = token.pos;
 16.1932 +        if (mods == null && token.kind == SEMI) {
 16.1933 +            nextToken();
 16.1934              return toP(F.at(pos).Skip());
 16.1935          } else {
 16.1936 -            String dc = S.docComment();
 16.1937 -            return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), dc);
 16.1938 +            return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), docComment);
 16.1939          }
 16.1940      }
 16.1941  
 16.1942 @@ -2358,19 +2344,19 @@
 16.1943       *  @param dc       The documentation comment for the class, or null.
 16.1944       */
 16.1945      JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, String dc) {
 16.1946 -        if (S.token() == CLASS) {
 16.1947 +        if (token.kind == CLASS) {
 16.1948              return classDeclaration(mods, dc);
 16.1949 -        } else if (S.token() == INTERFACE) {
 16.1950 +        } else if (token.kind == INTERFACE) {
 16.1951              return interfaceDeclaration(mods, dc);
 16.1952          } else if (allowEnums) {
 16.1953 -            if (S.token() == ENUM) {
 16.1954 +            if (token.kind == ENUM) {
 16.1955                  return enumDeclaration(mods, dc);
 16.1956              } else {
 16.1957 -                int pos = S.pos();
 16.1958 +                int pos = token.pos;
 16.1959                  List<JCTree> errs;
 16.1960 -                if (S.token() == IDENTIFIER) {
 16.1961 +                if (token.kind == IDENTIFIER) {
 16.1962                      errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
 16.1963 -                    setErrorEndPos(S.pos());
 16.1964 +                    setErrorEndPos(token.pos);
 16.1965                  } else {
 16.1966                      errs = List.<JCTree>of(mods);
 16.1967                  }
 16.1968 @@ -2378,16 +2364,16 @@
 16.1969                                                CLASS, INTERFACE, ENUM)));
 16.1970              }
 16.1971          } else {
 16.1972 -            if (S.token() == ENUM) {
 16.1973 -                error(S.pos(), "enums.not.supported.in.source", source.name);
 16.1974 +            if (token.kind == ENUM) {
 16.1975 +                error(token.pos, "enums.not.supported.in.source", source.name);
 16.1976                  allowEnums = true;
 16.1977                  return enumDeclaration(mods, dc);
 16.1978              }
 16.1979 -            int pos = S.pos();
 16.1980 +            int pos = token.pos;
 16.1981              List<JCTree> errs;
 16.1982 -            if (S.token() == IDENTIFIER) {
 16.1983 +            if (token.kind == IDENTIFIER) {
 16.1984                  errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
 16.1985 -                setErrorEndPos(S.pos());
 16.1986 +                setErrorEndPos(token.pos);
 16.1987              } else {
 16.1988                  errs = List.<JCTree>of(mods);
 16.1989              }
 16.1990 @@ -2402,20 +2388,20 @@
 16.1991       *  @param dc       The documentation comment for the class, or null.
 16.1992       */
 16.1993      JCClassDecl classDeclaration(JCModifiers mods, String dc) {
 16.1994 -        int pos = S.pos();
 16.1995 +        int pos = token.pos;
 16.1996          accept(CLASS);
 16.1997          Name name = ident();
 16.1998  
 16.1999          List<JCTypeParameter> typarams = typeParametersOpt();
 16.2000  
 16.2001          JCExpression extending = null;
 16.2002 -        if (S.token() == EXTENDS) {
 16.2003 -            S.nextToken();
 16.2004 +        if (token.kind == EXTENDS) {
 16.2005 +            nextToken();
 16.2006              extending = parseType();
 16.2007          }
 16.2008          List<JCExpression> implementing = List.nil();
 16.2009 -        if (S.token() == IMPLEMENTS) {
 16.2010 -            S.nextToken();
 16.2011 +        if (token.kind == IMPLEMENTS) {
 16.2012 +            nextToken();
 16.2013              implementing = typeList();
 16.2014          }
 16.2015          List<JCTree> defs = classOrInterfaceBody(name, false);
 16.2016 @@ -2431,15 +2417,15 @@
 16.2017       *  @param dc       The documentation comment for the interface, or null.
 16.2018       */
 16.2019      JCClassDecl interfaceDeclaration(JCModifiers mods, String dc) {
 16.2020 -        int pos = S.pos();
 16.2021 +        int pos = token.pos;
 16.2022          accept(INTERFACE);
 16.2023          Name name = ident();
 16.2024  
 16.2025          List<JCTypeParameter> typarams = typeParametersOpt();
 16.2026  
 16.2027          List<JCExpression> extending = List.nil();
 16.2028 -        if (S.token() == EXTENDS) {
 16.2029 -            S.nextToken();
 16.2030 +        if (token.kind == EXTENDS) {
 16.2031 +            nextToken();
 16.2032              extending = typeList();
 16.2033          }
 16.2034          List<JCTree> defs = classOrInterfaceBody(name, true);
 16.2035 @@ -2454,13 +2440,13 @@
 16.2036       *  @param dc       The documentation comment for the enum, or null.
 16.2037       */
 16.2038      JCClassDecl enumDeclaration(JCModifiers mods, String dc) {
 16.2039 -        int pos = S.pos();
 16.2040 +        int pos = token.pos;
 16.2041          accept(ENUM);
 16.2042          Name name = ident();
 16.2043  
 16.2044          List<JCExpression> implementing = List.nil();
 16.2045 -        if (S.token() == IMPLEMENTS) {
 16.2046 -            S.nextToken();
 16.2047 +        if (token.kind == IMPLEMENTS) {
 16.2048 +            nextToken();
 16.2049              implementing = typeList();
 16.2050          }
 16.2051  
 16.2052 @@ -2479,27 +2465,27 @@
 16.2053      List<JCTree> enumBody(Name enumName) {
 16.2054          accept(LBRACE);
 16.2055          ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
 16.2056 -        if (S.token() == COMMA) {
 16.2057 -            S.nextToken();
 16.2058 -        } else if (S.token() != RBRACE && S.token() != SEMI) {
 16.2059 +        if (token.kind == COMMA) {
 16.2060 +            nextToken();
 16.2061 +        } else if (token.kind != RBRACE && token.kind != SEMI) {
 16.2062              defs.append(enumeratorDeclaration(enumName));
 16.2063 -            while (S.token() == COMMA) {
 16.2064 -                S.nextToken();
 16.2065 -                if (S.token() == RBRACE || S.token() == SEMI) break;
 16.2066 +            while (token.kind == COMMA) {
 16.2067 +                nextToken();
 16.2068 +                if (token.kind == RBRACE || token.kind == SEMI) break;
 16.2069                  defs.append(enumeratorDeclaration(enumName));
 16.2070              }
 16.2071 -            if (S.token() != SEMI && S.token() != RBRACE) {
 16.2072 -                defs.append(syntaxError(S.pos(), "expected3",
 16.2073 +            if (token.kind != SEMI && token.kind != RBRACE) {
 16.2074 +                defs.append(syntaxError(token.pos, "expected3",
 16.2075                                  COMMA, RBRACE, SEMI));
 16.2076 -                S.nextToken();
 16.2077 +                nextToken();
 16.2078              }
 16.2079          }
 16.2080 -        if (S.token() == SEMI) {
 16.2081 -            S.nextToken();
 16.2082 -            while (S.token() != RBRACE && S.token() != EOF) {
 16.2083 +        if (token.kind == SEMI) {
 16.2084 +            nextToken();
 16.2085 +            while (token.kind != RBRACE && token.kind != EOF) {
 16.2086                  defs.appendList(classOrInterfaceBodyDeclaration(enumName,
 16.2087                                                                  false));
 16.2088 -                if (S.pos() <= errorEndPos) {
 16.2089 +                if (token.pos <= errorEndPos) {
 16.2090                      // error recovery
 16.2091                     skip(false, true, true, false);
 16.2092                  }
 16.2093 @@ -2512,23 +2498,22 @@
 16.2094      /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
 16.2095       */
 16.2096      JCTree enumeratorDeclaration(Name enumName) {
 16.2097 -        String dc = S.docComment();
 16.2098 +        String dc = token.docComment;
 16.2099          int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
 16.2100 -        if (S.deprecatedFlag()) {
 16.2101 +        if (token.deprecatedFlag) {
 16.2102              flags |= Flags.DEPRECATED;
 16.2103 -            S.resetDeprecatedFlag();
 16.2104          }
 16.2105 -        int pos = S.pos();
 16.2106 +        int pos = token.pos;
 16.2107          List<JCAnnotation> annotations = annotationsOpt();
 16.2108          JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
 16.2109          List<JCExpression> typeArgs = typeArgumentsOpt();
 16.2110 -        int identPos = S.pos();
 16.2111 +        int identPos = token.pos;
 16.2112          Name name = ident();
 16.2113 -        int createPos = S.pos();
 16.2114 -        List<JCExpression> args = (S.token() == LPAREN)
 16.2115 +        int createPos = token.pos;
 16.2116 +        List<JCExpression> args = (token.kind == LPAREN)
 16.2117              ? arguments() : List.<JCExpression>nil();
 16.2118          JCClassDecl body = null;
 16.2119 -        if (S.token() == LBRACE) {
 16.2120 +        if (token.kind == LBRACE) {
 16.2121              JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC);
 16.2122              List<JCTree> defs = classOrInterfaceBody(names.empty, false);
 16.2123              body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
 16.2124 @@ -2538,7 +2523,7 @@
 16.2125          JCIdent ident = F.at(identPos).Ident(enumName);
 16.2126          JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
 16.2127          if (createPos != identPos)
 16.2128 -            storeEnd(create, S.prevEndPos());
 16.2129 +            storeEnd(create, S.prevToken().endPos);
 16.2130          ident = F.at(identPos).Ident(enumName);
 16.2131          JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
 16.2132          attach(result, dc);
 16.2133 @@ -2550,8 +2535,8 @@
 16.2134      List<JCExpression> typeList() {
 16.2135          ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
 16.2136          ts.append(parseType());
 16.2137 -        while (S.token() == COMMA) {
 16.2138 -            S.nextToken();
 16.2139 +        while (token.kind == COMMA) {
 16.2140 +            nextToken();
 16.2141              ts.append(parseType());
 16.2142          }
 16.2143          return ts.toList();
 16.2144 @@ -2562,16 +2547,16 @@
 16.2145       */
 16.2146      List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
 16.2147          accept(LBRACE);
 16.2148 -        if (S.pos() <= errorEndPos) {
 16.2149 +        if (token.pos <= errorEndPos) {
 16.2150              // error recovery
 16.2151              skip(false, true, false, false);
 16.2152 -            if (S.token() == LBRACE)
 16.2153 -                S.nextToken();
 16.2154 +            if (token.kind == LBRACE)
 16.2155 +                nextToken();
 16.2156          }
 16.2157          ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
 16.2158 -        while (S.token() != RBRACE && S.token() != EOF) {
 16.2159 +        while (token.kind != RBRACE && token.kind != EOF) {
 16.2160              defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
 16.2161 -            if (S.pos() <= errorEndPos) {
 16.2162 +            if (token.pos <= errorEndPos) {
 16.2163                 // error recovery
 16.2164                 skip(false, true, true, false);
 16.2165             }
 16.2166 @@ -2598,23 +2583,23 @@
 16.2167       *      ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" )
 16.2168       */
 16.2169      protected List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
 16.2170 -        if (S.token() == SEMI) {
 16.2171 -            S.nextToken();
 16.2172 +        if (token.kind == SEMI) {
 16.2173 +            nextToken();
 16.2174              return List.<JCTree>nil();
 16.2175          } else {
 16.2176 -            String dc = S.docComment();
 16.2177 -            int pos = S.pos();
 16.2178 +            String dc = token.docComment;
 16.2179 +            int pos = token.pos;
 16.2180              JCModifiers mods = modifiersOpt();
 16.2181 -            if (S.token() == CLASS ||
 16.2182 -                S.token() == INTERFACE ||
 16.2183 -                allowEnums && S.token() == ENUM) {
 16.2184 +            if (token.kind == CLASS ||
 16.2185 +                token.kind == INTERFACE ||
 16.2186 +                allowEnums && token.kind == ENUM) {
 16.2187                  return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc));
 16.2188 -            } else if (S.token() == LBRACE && !isInterface &&
 16.2189 +            } else if (token.kind == LBRACE && !isInterface &&
 16.2190                         (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
 16.2191                         mods.annotations.isEmpty()) {
 16.2192                  return List.<JCTree>of(block(pos, mods.flags));
 16.2193              } else {
 16.2194 -                pos = S.pos();
 16.2195 +                pos = token.pos;
 16.2196                  List<JCTypeParameter> typarams = typeParametersOpt();
 16.2197                  // if there are type parameters but no modifiers, save the start
 16.2198                  // position of the method in the modifiers.
 16.2199 @@ -2622,26 +2607,26 @@
 16.2200                      mods.pos = pos;
 16.2201                      storeEnd(mods, pos);
 16.2202                  }
 16.2203 -                Name name = S.name();
 16.2204 -                pos = S.pos();
 16.2205 +                Token tk = token;
 16.2206 +                pos = token.pos;
 16.2207                  JCExpression type;
 16.2208 -                boolean isVoid = S.token() == VOID;
 16.2209 +                boolean isVoid = token.kind == VOID;
 16.2210                  if (isVoid) {
 16.2211                      type = to(F.at(pos).TypeIdent(TypeTags.VOID));
 16.2212 -                    S.nextToken();
 16.2213 +                    nextToken();
 16.2214                  } else {
 16.2215                      type = parseType();
 16.2216                  }
 16.2217 -                if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) {
 16.2218 -                    if (isInterface || name != className)
 16.2219 +                if (token.kind == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) {
 16.2220 +                    if (isInterface || tk.name() != className)
 16.2221                          error(pos, "invalid.meth.decl.ret.type.req");
 16.2222                      return List.of(methodDeclaratorRest(
 16.2223                          pos, mods, null, names.init, typarams,
 16.2224                          isInterface, true, dc));
 16.2225                  } else {
 16.2226 -                    pos = S.pos();
 16.2227 -                    name = ident();
 16.2228 -                    if (S.token() == LPAREN) {
 16.2229 +                    pos = token.pos;
 16.2230 +                    Name name = ident();
 16.2231 +                    if (token.kind == LPAREN) {
 16.2232                          return List.of(methodDeclaratorRest(
 16.2233                              pos, mods, type, name, typarams,
 16.2234                              isInterface, isVoid, dc));
 16.2235 @@ -2649,16 +2634,16 @@
 16.2236                          List<JCTree> defs =
 16.2237                              variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
 16.2238                                                      new ListBuffer<JCTree>()).toList();
 16.2239 -                        storeEnd(defs.last(), S.endPos());
 16.2240 +                        storeEnd(defs.last(), token.endPos);
 16.2241                          accept(SEMI);
 16.2242                          return defs;
 16.2243                      } else {
 16.2244 -                        pos = S.pos();
 16.2245 +                        pos = token.pos;
 16.2246                          List<JCTree> err = isVoid
 16.2247                              ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams,
 16.2248                                  List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null)))
 16.2249                              : null;
 16.2250 -                        return List.<JCTree>of(syntaxError(S.pos(), err, "expected", LPAREN));
 16.2251 +                        return List.<JCTree>of(syntaxError(token.pos, err, "expected", LPAREN));
 16.2252                      }
 16.2253                  }
 16.2254              }
 16.2255 @@ -2686,27 +2671,27 @@
 16.2256          List<JCVariableDecl> params = formalParameters();
 16.2257          if (!isVoid) type = bracketsOpt(type);
 16.2258          List<JCExpression> thrown = List.nil();
 16.2259 -        if (S.token() == THROWS) {
 16.2260 -            S.nextToken();
 16.2261 +        if (token.kind == THROWS) {
 16.2262 +            nextToken();
 16.2263              thrown = qualidentList();
 16.2264          }
 16.2265          JCBlock body = null;
 16.2266          JCExpression defaultValue;
 16.2267 -        if (S.token() == LBRACE) {
 16.2268 +        if (token.kind == LBRACE) {
 16.2269              body = block();
 16.2270              defaultValue = null;
 16.2271          } else {
 16.2272 -            if (S.token() == DEFAULT) {
 16.2273 +            if (token.kind == DEFAULT) {
 16.2274                  accept(DEFAULT);
 16.2275                  defaultValue = annotationValue();
 16.2276              } else {
 16.2277                  defaultValue = null;
 16.2278              }
 16.2279              accept(SEMI);
 16.2280 -            if (S.pos() <= errorEndPos) {
 16.2281 +            if (token.pos <= errorEndPos) {
 16.2282                  // error recovery
 16.2283                  skip(false, true, false, false);
 16.2284 -                if (S.token() == LBRACE) {
 16.2285 +                if (token.kind == LBRACE) {
 16.2286                      body = block();
 16.2287                  }
 16.2288              }
 16.2289 @@ -2725,8 +2710,8 @@
 16.2290      List<JCExpression> qualidentList() {
 16.2291          ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
 16.2292          ts.append(qualident());
 16.2293 -        while (S.token() == COMMA) {
 16.2294 -            S.nextToken();
 16.2295 +        while (token.kind == COMMA) {
 16.2296 +            nextToken();
 16.2297              ts.append(qualident());
 16.2298          }
 16.2299          return ts.toList();
 16.2300 @@ -2735,13 +2720,13 @@
 16.2301      /** TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
 16.2302       */
 16.2303      List<JCTypeParameter> typeParametersOpt() {
 16.2304 -        if (S.token() == LT) {
 16.2305 +        if (token.kind == LT) {
 16.2306              checkGenerics();
 16.2307              ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>();
 16.2308 -            S.nextToken();
 16.2309 +            nextToken();
 16.2310              typarams.append(typeParameter());
 16.2311 -            while (S.token() == COMMA) {
 16.2312 -                S.nextToken();
 16.2313 +            while (token.kind == COMMA) {
 16.2314 +                nextToken();
 16.2315                  typarams.append(typeParameter());
 16.2316              }
 16.2317              accept(GT);
 16.2318 @@ -2756,14 +2741,14 @@
 16.2319       *  TypeVariable = Ident
 16.2320       */
 16.2321      JCTypeParameter typeParameter() {
 16.2322 -        int pos = S.pos();
 16.2323 +        int pos = token.pos;
 16.2324          Name name = ident();
 16.2325          ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
 16.2326 -        if (S.token() == EXTENDS) {
 16.2327 -            S.nextToken();
 16.2328 +        if (token.kind == EXTENDS) {
 16.2329 +            nextToken();
 16.2330              bounds.append(parseType());
 16.2331 -            while (S.token() == AMP) {
 16.2332 -                S.nextToken();
 16.2333 +            while (token.kind == AMP) {
 16.2334 +                nextToken();
 16.2335                  bounds.append(parseType());
 16.2336              }
 16.2337          }
 16.2338 @@ -2778,10 +2763,10 @@
 16.2339          ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
 16.2340          JCVariableDecl lastParam = null;
 16.2341          accept(LPAREN);
 16.2342 -        if (S.token() != RPAREN) {
 16.2343 +        if (token.kind != RPAREN) {
 16.2344              params.append(lastParam = formalParameter());
 16.2345 -            while ((lastParam.mods.flags & Flags.VARARGS) == 0 && S.token() == COMMA) {
 16.2346 -                S.nextToken();
 16.2347 +            while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) {
 16.2348 +                nextToken();
 16.2349                  params.append(lastParam = formalParameter());
 16.2350              }
 16.2351          }
 16.2352 @@ -2802,11 +2787,11 @@
 16.2353      protected JCVariableDecl formalParameter() {
 16.2354          JCModifiers mods = optFinal(Flags.PARAMETER);
 16.2355          JCExpression type = parseType();
 16.2356 -        if (S.token() == ELLIPSIS) {
 16.2357 +        if (token.kind == ELLIPSIS) {
 16.2358              checkVarargs();
 16.2359              mods.flags |= Flags.VARARGS;
 16.2360 -            type = to(F.at(S.pos()).TypeArray(type));
 16.2361 -            S.nextToken();
 16.2362 +            type = to(F.at(token.pos).TypeArray(type));
 16.2363 +            nextToken();
 16.2364          }
 16.2365          return variableDeclaratorId(mods, type);
 16.2366      }
 16.2367 @@ -2849,7 +2834,7 @@
 16.2368      /** Return precedence of operator represented by token,
 16.2369       *  -1 if token is not a binary operator. @see TreeInfo.opPrec
 16.2370       */
 16.2371 -    static int prec(Token token) {
 16.2372 +    static int prec(TokenKind token) {
 16.2373          int oc = optag(token);
 16.2374          return (oc >= 0) ? TreeInfo.opPrec(oc) : -1;
 16.2375      }
 16.2376 @@ -2869,7 +2854,7 @@
 16.2377      /** Return operation tag of binary operator represented by token,
 16.2378       *  -1 if token is not a binary operator.
 16.2379       */
 16.2380 -    static int optag(Token token) {
 16.2381 +    static int optag(TokenKind token) {
 16.2382          switch (token) {
 16.2383          case BARBAR:
 16.2384              return JCTree.OR;
 16.2385 @@ -2941,7 +2926,7 @@
 16.2386      /** Return operation tag of unary operator represented by token,
 16.2387       *  -1 if token is not a binary operator.
 16.2388       */
 16.2389 -    static int unoptag(Token token) {
 16.2390 +    static int unoptag(TokenKind token) {
 16.2391          switch (token) {
 16.2392          case PLUS:
 16.2393              return JCTree.POS;
 16.2394 @@ -2963,7 +2948,7 @@
 16.2395      /** Return type tag of basic type represented by token,
 16.2396       *  -1 if token is not a basic type identifier.
 16.2397       */
 16.2398 -    static int typetag(Token token) {
 16.2399 +    static int typetag(TokenKind token) {
 16.2400          switch (token) {
 16.2401          case BYTE:
 16.2402              return TypeTags.BYTE;
 16.2403 @@ -2988,49 +2973,49 @@
 16.2404  
 16.2405      void checkGenerics() {
 16.2406          if (!allowGenerics) {
 16.2407 -            error(S.pos(), "generics.not.supported.in.source", source.name);
 16.2408 +            error(token.pos, "generics.not.supported.in.source", source.name);
 16.2409              allowGenerics = true;
 16.2410          }
 16.2411      }
 16.2412      void checkVarargs() {
 16.2413          if (!allowVarargs) {
 16.2414 -            error(S.pos(), "varargs.not.supported.in.source", source.name);
 16.2415 +            error(token.pos, "varargs.not.supported.in.source", source.name);
 16.2416              allowVarargs = true;
 16.2417          }
 16.2418      }
 16.2419      void checkForeach() {
 16.2420          if (!allowForeach) {
 16.2421 -            error(S.pos(), "foreach.not.supported.in.source", source.name);
 16.2422 +            error(token.pos, "foreach.not.supported.in.source", source.name);
 16.2423              allowForeach = true;
 16.2424          }
 16.2425      }
 16.2426      void checkStaticImports() {
 16.2427          if (!allowStaticImport) {
 16.2428 -            error(S.pos(), "static.import.not.supported.in.source", source.name);
 16.2429 +            error(token.pos, "static.import.not.supported.in.source", source.name);
 16.2430              allowStaticImport = true;
 16.2431          }
 16.2432      }
 16.2433      void checkAnnotations() {
 16.2434          if (!allowAnnotations) {
 16.2435 -            error(S.pos(), "annotations.not.supported.in.source", source.name);
 16.2436 +            error(token.pos, "annotations.not.supported.in.source", source.name);
 16.2437              allowAnnotations = true;
 16.2438          }
 16.2439      }
 16.2440      void checkDiamond() {
 16.2441          if (!allowDiamond) {
 16.2442 -            error(S.pos(), "diamond.not.supported.in.source", source.name);
 16.2443 +            error(token.pos, "diamond.not.supported.in.source", source.name);
 16.2444              allowDiamond = true;
 16.2445          }
 16.2446      }
 16.2447      void checkMulticatch() {
 16.2448          if (!allowMulticatch) {
 16.2449 -            error(S.pos(), "multicatch.not.supported.in.source", source.name);
 16.2450 +            error(token.pos, "multicatch.not.supported.in.source", source.name);
 16.2451              allowMulticatch = true;
 16.2452          }
 16.2453      }
 16.2454      void checkTryWithResources() {
 16.2455          if (!allowTWR) {
 16.2456 -            error(S.pos(), "try.with.resources.not.supported.in.source", source.name);
 16.2457 +            error(token.pos, "try.with.resources.not.supported.in.source", source.name);
 16.2458              allowTWR = true;
 16.2459          }
 16.2460      }
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavadocTokenizer.java	Fri Oct 28 17:49:36 2011 -0700
    17.3 @@ -0,0 +1,412 @@
    17.4 +/*
    17.5 + * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
    17.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    17.7 + *
    17.8 + * This code is free software; you can redistribute it and/or modify it
    17.9 + * under the terms of the GNU General Public License version 2 only, as
   17.10 + * published by the Free Software Foundation.  Oracle designates this
   17.11 + * particular file as subject to the "Classpath" exception as provided
   17.12 + * by Oracle in the LICENSE file that accompanied this code.
   17.13 + *
   17.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   17.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   17.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   17.17 + * version 2 for more details (a copy is included in the LICENSE file that
   17.18 + * accompanied this code).
   17.19 + *
   17.20 + * You should have received a copy of the GNU General Public License version
   17.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   17.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   17.23 + *
   17.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   17.25 + * or visit www.oracle.com if you need additional information or have any
   17.26 + * questions.
   17.27 + */
   17.28 +
   17.29 +package com.sun.tools.javac.parser;
   17.30 +
   17.31 +import com.sun.tools.javac.file.JavacFileManager;
   17.32 +import com.sun.tools.javac.parser.Tokens.Token;
   17.33 +import com.sun.tools.javac.util.*;
   17.34 +
   17.35 +import java.nio.*;
   17.36 +
   17.37 +import static com.sun.tools.javac.util.LayoutCharacters.*;
   17.38 +
   17.39 +/** An extension to the base lexical analyzer that captures
   17.40 + *  and processes the contents of doc comments.  It does so by
   17.41 + *  translating Unicode escape sequences and by stripping the
   17.42 + *  leading whitespace and starts from each line of the comment.
   17.43 + *
   17.44 + *  <p><b>This is NOT part of any supported API.
   17.45 + *  If you write code that depends on this, you do so at your own risk.
   17.46 + *  This code and its internal interfaces are subject to change or
   17.47 + *  deletion without notice.</b>
   17.48 + */
   17.49 +public class JavadocTokenizer extends JavaTokenizer {
   17.50 +
   17.51 +    /** Create a scanner from the input buffer.  buffer must implement
   17.52 +     *  array() and compact(), and remaining() must be less than limit().
   17.53 +     */
   17.54 +    protected JavadocTokenizer(ScannerFactory fac, CharBuffer buffer) {
   17.55 +        super(fac, buffer);
   17.56 +    }
   17.57 +
   17.58 +    /** Create a scanner from the input array.  The array must have at
   17.59 +     *  least a single character of extra space.
   17.60 +     */
   17.61 +    protected JavadocTokenizer(ScannerFactory fac, char[] input, int inputLength) {
   17.62 +        super(fac, input, inputLength);
   17.63 +    }
   17.64 +
   17.65 +    /** The comment input buffer, index of next chacter to be read,
   17.66 +     *  index of one past last character in buffer.
   17.67 +     */
   17.68 +    private char[] buf;
   17.69 +    private int bp;
   17.70 +    private int buflen;
   17.71 +
   17.72 +    /** The current character.
   17.73 +     */
   17.74 +    private char ch;
   17.75 +
   17.76 +    /** The column number position of the current character.
   17.77 +     */
   17.78 +    private int col;
   17.79 +
   17.80 +    /** The buffer index of the last converted Unicode character
   17.81 +     */
   17.82 +    private int unicodeConversionBp = 0;
   17.83 +
   17.84 +    /**
   17.85 +     * Buffer for doc comment.
   17.86 +     */
   17.87 +    private char[] docCommentBuffer = new char[1024];
   17.88 +
   17.89 +    /**
   17.90 +     * Number of characters in doc comment buffer.
   17.91 +     */
   17.92 +    private int docCommentCount;
   17.93 +
   17.94 +    /**
   17.95 +     * Translated and stripped contents of doc comment
   17.96 +     */
   17.97 +    private String docComment = null;
   17.98 +
   17.99 +
  17.100 +    /** Unconditionally expand the comment buffer.
  17.101 +     */
  17.102 +    private void expandCommentBuffer() {
  17.103 +        char[] newBuffer = new char[docCommentBuffer.length * 2];
  17.104 +        System.arraycopy(docCommentBuffer, 0, newBuffer,
  17.105 +                         0, docCommentBuffer.length);
  17.106 +        docCommentBuffer = newBuffer;
  17.107 +    }
  17.108 +
  17.109 +    /** Convert an ASCII digit from its base (8, 10, or 16)
  17.110 +     *  to its value.
  17.111 +     */
  17.112 +    private int digit(int base) {
  17.113 +        char c = ch;
  17.114 +        int result = Character.digit(c, base);
  17.115 +        if (result >= 0 && c > 0x7f) {
  17.116 +            ch = "0123456789abcdef".charAt(result);
  17.117 +        }
  17.118 +        return result;
  17.119 +    }
  17.120 +
  17.121 +    /** Convert Unicode escape; bp points to initial '\' character
  17.122 +     *  (Spec 3.3).
  17.123 +     */
  17.124 +    private void convertUnicode() {
  17.125 +        if (ch == '\\' && unicodeConversionBp != bp) {
  17.126 +            bp++; ch = buf[bp]; col++;
  17.127 +            if (ch == 'u') {
  17.128 +                do {
  17.129 +                    bp++; ch = buf[bp]; col++;
  17.130 +                } while (ch == 'u');
  17.131 +                int limit = bp + 3;
  17.132 +                if (limit < buflen) {
  17.133 +                    int d = digit(16);
  17.134 +                    int code = d;
  17.135 +                    while (bp < limit && d >= 0) {
  17.136 +                        bp++; ch = buf[bp]; col++;
  17.137 +                        d = digit(16);
  17.138 +                        code = (code << 4) + d;
  17.139 +                    }
  17.140 +                    if (d >= 0) {
  17.141 +                        ch = (char)code;
  17.142 +                        unicodeConversionBp = bp;
  17.143 +                        return;
  17.144 +                    }
  17.145 +                }
  17.146 +                // "illegal.Unicode.esc", reported by base scanner
  17.147 +            } else {
  17.148 +                bp--;
  17.149 +                ch = '\\';
  17.150 +                col--;
  17.151 +            }
  17.152 +        }
  17.153 +    }
  17.154 +
  17.155 +
  17.156 +    /** Read next character.
  17.157 +     */
  17.158 +    private void scanChar() {
  17.159 +        bp++;
  17.160 +        ch = buf[bp];
  17.161 +        switch (ch) {
  17.162 +        case '\r': // return
  17.163 +            col = 0;
  17.164 +            break;
  17.165 +        case '\n': // newline
  17.166 +            if (bp == 0 || buf[bp-1] != '\r') {
  17.167 +                col = 0;
  17.168 +            }
  17.169 +            break;
  17.170 +        case '\t': // tab
  17.171 +            col = (col / TabInc * TabInc) + TabInc;
  17.172 +            break;
  17.173 +        case '\\': // possible Unicode
  17.174 +            col++;
  17.175 +            convertUnicode();
  17.176 +            break;
  17.177 +        default:
  17.178 +            col++;
  17.179 +            break;
  17.180 +        }
  17.181 +    }
  17.182 +
  17.183 +    @Override
  17.184 +    public Token readToken() {
  17.185 +        docComment = null;
  17.186 +        Token tk = super.readToken();
  17.187 +        tk.docComment = docComment;
  17.188 +        return tk;
  17.189 +    }
  17.190 +
  17.191 +    /**
  17.192 +     * Read next character in doc comment, skipping over double '\' characters.
  17.193 +     * If a double '\' is skipped, put in the buffer and update buffer count.
  17.194 +     */
  17.195 +    private void scanDocCommentChar() {
  17.196 +        scanChar();
  17.197 +        if (ch == '\\') {
  17.198 +            if (buf[bp+1] == '\\' && unicodeConversionBp != bp) {
  17.199 +                if (docCommentCount == docCommentBuffer.length)
  17.200 +                    expandCommentBuffer();
  17.201 +                docCommentBuffer[docCommentCount++] = ch;
  17.202 +                bp++; col++;
  17.203 +            } else {
  17.204 +                convertUnicode();
  17.205 +            }
  17.206 +        }
  17.207 +    }
  17.208 +
  17.209 +    /**
  17.210 +     * Process a doc comment and make the string content available.
  17.211 +     * Strips leading whitespace and stars.
  17.212 +     */
  17.213 +    @SuppressWarnings("fallthrough")
  17.214 +    protected void processComment(int pos, int endPos, CommentStyle style) {
  17.215 +        if (style != CommentStyle.JAVADOC) {
  17.216 +            return;
  17.217 +        }
  17.218 +
  17.219 +        buf = reader.getRawCharacters(pos, endPos);
  17.220 +        buflen = buf.length;
  17.221 +        bp = 0;
  17.222 +        col = 0;
  17.223 +
  17.224 +        docCommentCount = 0;
  17.225 +
  17.226 +        boolean firstLine = true;
  17.227 +
  17.228 +        // Skip over first slash
  17.229 +        scanDocCommentChar();
  17.230 +        // Skip over first star
  17.231 +        scanDocCommentChar();
  17.232 +
  17.233 +        // consume any number of stars
  17.234 +        while (bp < buflen && ch == '*') {
  17.235 +            scanDocCommentChar();
  17.236 +        }
  17.237 +        // is the comment in the form /**/, /***/, /****/, etc. ?
  17.238 +        if (bp < buflen && ch == '/') {
  17.239 +            docComment = "";
  17.240 +            return;
  17.241 +        }
  17.242 +
  17.243 +        // skip a newline on the first line of the comment.
  17.244 +        if (bp < buflen) {
  17.245 +            if (ch == LF) {
  17.246 +                scanDocCommentChar();
  17.247 +                firstLine = false;
  17.248 +            } else if (ch == CR) {
  17.249 +                scanDocCommentChar();
  17.250 +                if (ch == LF) {
  17.251 +                    scanDocCommentChar();
  17.252 +                    firstLine = false;
  17.253 +                }
  17.254 +            }
  17.255 +        }
  17.256 +
  17.257 +    outerLoop:
  17.258 +
  17.259 +        // The outerLoop processes the doc comment, looping once
  17.260 +        // for each line.  For each line, it first strips off
  17.261 +        // whitespace, then it consumes any stars, then it
  17.262 +        // puts the rest of the line into our buffer.
  17.263 +        while (bp < buflen) {
  17.264 +
  17.265 +            // The wsLoop consumes whitespace from the beginning
  17.266 +            // of each line.
  17.267 +        wsLoop:
  17.268 +
  17.269 +            while (bp < buflen) {
  17.270 +                switch(ch) {
  17.271 +                case ' ':
  17.272 +                    scanDocCommentChar();
  17.273 +                    break;
  17.274 +                case '\t':
  17.275 +                    col = ((col - 1) / TabInc * TabInc) + TabInc;
  17.276 +                    scanDocCommentChar();
  17.277 +                    break;
  17.278 +                case FF:
  17.279 +                    col = 0;
  17.280 +                    scanDocCommentChar();
  17.281 +                    break;
  17.282 +// Treat newline at beginning of line (blank line, no star)
  17.283 +// as comment text.  Old Javadoc compatibility requires this.
  17.284 +/*---------------------------------*
  17.285 +                case CR: // (Spec 3.4)
  17.286 +                    scanDocCommentChar();
  17.287 +                    if (ch == LF) {
  17.288 +                        col = 0;
  17.289 +                        scanDocCommentChar();
  17.290 +                    }
  17.291 +                    break;
  17.292 +                case LF: // (Spec 3.4)
  17.293 +                    scanDocCommentChar();
  17.294 +                    break;
  17.295 +*---------------------------------*/
  17.296 +                default:
  17.297 +                    // we've seen something that isn't whitespace;
  17.298 +                    // jump out.
  17.299 +                    break wsLoop;
  17.300 +                }
  17.301 +            }
  17.302 +
  17.303 +            // Are there stars here?  If so, consume them all
  17.304 +            // and check for the end of comment.
  17.305 +            if (ch == '*') {
  17.306 +                // skip all of the stars
  17.307 +                do {
  17.308 +                    scanDocCommentChar();
  17.309 +                } while (ch == '*');
  17.310 +
  17.311 +                // check for the closing slash.
  17.312 +                if (ch == '/') {
  17.313 +                    // We're done with the doc comment
  17.314 +                    // scanChar() and breakout.
  17.315 +                    break outerLoop;
  17.316 +                }
  17.317 +            } else if (! firstLine) {
  17.318 +                //The current line does not begin with a '*' so we will indent it.
  17.319 +                for (int i = 1; i < col; i++) {
  17.320 +                    if (docCommentCount == docCommentBuffer.length)
  17.321 +                        expandCommentBuffer();
  17.322 +                    docCommentBuffer[docCommentCount++] = ' ';
  17.323 +                }
  17.324 +            }
  17.325 +
  17.326 +            // The textLoop processes the rest of the characters
  17.327 +            // on the line, adding them to our buffer.
  17.328 +        textLoop:
  17.329 +            while (bp < buflen) {
  17.330 +                switch (ch) {
  17.331 +                case '*':
  17.332 +                    // Is this just a star?  Or is this the
  17.333 +                    // end of a comment?
  17.334 +                    scanDocCommentChar();
  17.335 +                    if (ch == '/') {
  17.336 +                        // This is the end of the comment,
  17.337 +                        // set ch and return our buffer.
  17.338 +                        break outerLoop;
  17.339 +                    }
  17.340 +                    // This is just an ordinary star.  Add it to
  17.341 +                    // the buffer.
  17.342 +                    if (docCommentCount == docCommentBuffer.length)
  17.343 +                        expandCommentBuffer();
  17.344 +                    docCommentBuffer[docCommentCount++] = '*';
  17.345 +                    break;
  17.346 +                case ' ':
  17.347 +                case '\t':
  17.348 +                    if (docCommentCount == docCommentBuffer.length)
  17.349 +                        expandCommentBuffer();
  17.350 +                    docCommentBuffer[docCommentCount++] = ch;
  17.351 +                    scanDocCommentChar();
  17.352 +                    break;
  17.353 +                case FF:
  17.354 +                    scanDocCommentChar();
  17.355 +                    break textLoop; // treat as end of line
  17.356 +                case CR: // (Spec 3.4)
  17.357 +                    scanDocCommentChar();
  17.358 +                    if (ch != LF) {
  17.359 +                        // Canonicalize CR-only line terminator to LF
  17.360 +                        if (docCommentCount == docCommentBuffer.length)
  17.361 +                            expandCommentBuffer();
  17.362 +                        docCommentBuffer[docCommentCount++] = (char)LF;
  17.363 +                        break textLoop;
  17.364 +                    }
  17.365 +                    /* fall through to LF case */
  17.366 +                case LF: // (Spec 3.4)
  17.367 +                    // We've seen a newline.  Add it to our
  17.368 +                    // buffer and break out of this loop,
  17.369 +                    // starting fresh on a new line.
  17.370 +                    if (docCommentCount == docCommentBuffer.length)
  17.371 +                        expandCommentBuffer();
  17.372 +                    docCommentBuffer[docCommentCount++] = ch;
  17.373 +                    scanDocCommentChar();
  17.374 +                    break textLoop;
  17.375 +                default:
  17.376 +                    // Add the character to our buffer.
  17.377 +                    if (docCommentCount == docCommentBuffer.length)
  17.378 +                        expandCommentBuffer();
  17.379 +                    docCommentBuffer[docCommentCount++] = ch;
  17.380 +                    scanDocCommentChar();
  17.381 +                }
  17.382 +            } // end textLoop
  17.383 +            firstLine = false;
  17.384 +        } // end outerLoop
  17.385 +
  17.386 +        if (docCommentCount > 0) {
  17.387 +            int i = docCommentCount - 1;
  17.388 +        trailLoop:
  17.389 +            while (i > -1) {
  17.390 +                switch (docCommentBuffer[i]) {
  17.391 +                case '*':
  17.392 +                    i--;
  17.393 +                    break;
  17.394 +                default:
  17.395 +                    break trailLoop;
  17.396 +                }
  17.397 +            }
  17.398 +            docCommentCount = i + 1;
  17.399 +
  17.400 +            // Store the text of the doc comment
  17.401 +            docComment = new String(docCommentBuffer, 0 , docCommentCount);
  17.402 +        } else {
  17.403 +            docComment = "";
  17.404 +        }
  17.405 +    }
  17.406 +
  17.407 +    /** Build a map for translating between line numbers and
  17.408 +     * positions in the input.
  17.409 +     *
  17.410 +     * @return a LineMap */
  17.411 +    public Position.LineMap getLineMap() {
  17.412 +        char[] buf = reader.getRawCharacters();
  17.413 +        return Position.makeLineMap(buf, buf.length, true);
  17.414 +    }
  17.415 +}
    18.1 --- a/src/share/classes/com/sun/tools/javac/parser/Keywords.java	Thu Oct 27 13:54:50 2011 -0700
    18.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.3 @@ -1,98 +0,0 @@
    18.4 -/*
    18.5 - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
    18.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    18.7 - *
    18.8 - * This code is free software; you can redistribute it and/or modify it
    18.9 - * under the terms of the GNU General Public License version 2 only, as
   18.10 - * published by the Free Software Foundation.  Oracle designates this
   18.11 - * particular file as subject to the "Classpath" exception as provided
   18.12 - * by Oracle in the LICENSE file that accompanied this code.
   18.13 - *
   18.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
   18.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   18.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   18.17 - * version 2 for more details (a copy is included in the LICENSE file that
   18.18 - * accompanied this code).
   18.19 - *
   18.20 - * You should have received a copy of the GNU General Public License version
   18.21 - * 2 along with this work; if not, write to the Free Software Foundation,
   18.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   18.23 - *
   18.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   18.25 - * or visit www.oracle.com if you need additional information or have any
   18.26 - * questions.
   18.27 - */
   18.28 -
   18.29 -package com.sun.tools.javac.parser;
   18.30 -
   18.31 -import com.sun.tools.javac.util.Context;
   18.32 -import com.sun.tools.javac.util.Log;
   18.33 -import com.sun.tools.javac.util.Name;
   18.34 -import com.sun.tools.javac.util.Names;
   18.35 -
   18.36 -import static com.sun.tools.javac.parser.Token.*;
   18.37 -
   18.38 -/**
   18.39 - * Map from Name to Token and Token to String.
   18.40 - *
   18.41 - * <p><b>This is NOT part of any supported API.
   18.42 - * If you write code that depends on this, you do so at your own risk.
   18.43 - * This code and its internal interfaces are subject to change or
   18.44 - * deletion without notice.</b>
   18.45 - */
   18.46 -public class Keywords {
   18.47 -    public static final Context.Key<Keywords> keywordsKey =
   18.48 -        new Context.Key<Keywords>();
   18.49 -
   18.50 -    public static Keywords instance(Context context) {
   18.51 -        Keywords instance = context.get(keywordsKey);
   18.52 -        if (instance == null)
   18.53 -            instance = new Keywords(context);
   18.54 -        return instance;
   18.55 -    }
   18.56 -
   18.57 -    private final Names names;
   18.58 -
   18.59 -    protected Keywords(Context context) {
   18.60 -        context.put(keywordsKey, this);
   18.61 -        names = Names.instance(context);
   18.62 -
   18.63 -        for (Token t : Token.values()) {
   18.64 -            if (t.name != null)
   18.65 -                enterKeyword(t.name, t);
   18.66 -            else
   18.67 -                tokenName[t.ordinal()] = null;
   18.68 -        }
   18.69 -
   18.70 -        key = new Token[maxKey+1];
   18.71 -        for (int i = 0; i <= maxKey; i++) key[i] = IDENTIFIER;
   18.72 -        for (Token t : Token.values()) {
   18.73 -            if (t.name != null)
   18.74 -                key[tokenName[t.ordinal()].getIndex()] = t;
   18.75 -        }
   18.76 -    }
   18.77 -
   18.78 -
   18.79 -    public Token key(Name name) {
   18.80 -        return (name.getIndex() > maxKey) ? IDENTIFIER : key[name.getIndex()];
   18.81 -    }
   18.82 -
   18.83 -    /**
   18.84 -     * Keyword array. Maps name indices to Token.
   18.85 -     */
   18.86 -    private final Token[] key;
   18.87 -
   18.88 -    /**  The number of the last entered keyword.
   18.89 -     */
   18.90 -    private int maxKey = 0;
   18.91 -
   18.92 -    /** The names of all tokens.
   18.93 -     */
   18.94 -    private Name[] tokenName = new Name[Token.values().length];
   18.95 -
   18.96 -    private void enterKeyword(String s, Token token) {
   18.97 -        Name n = names.fromString(s);
   18.98 -        tokenName[token.ordinal()] = n;
   18.99 -        if (n.getIndex() > maxKey) maxKey = n.getIndex();
  18.100 -    }
  18.101 -}
    19.1 --- a/src/share/classes/com/sun/tools/javac/parser/Lexer.java	Thu Oct 27 13:54:50 2011 -0700
    19.2 +++ b/src/share/classes/com/sun/tools/javac/parser/Lexer.java	Fri Oct 28 17:49:36 2011 -0700
    19.3 @@ -25,7 +25,7 @@
    19.4  
    19.5  package com.sun.tools.javac.parser;
    19.6  
    19.7 -import com.sun.tools.javac.util.*;
    19.8 +import com.sun.tools.javac.parser.Tokens.*;
    19.9  import com.sun.tools.javac.util.Position.LineMap;
   19.10  
   19.11  /**
   19.12 @@ -40,22 +40,26 @@
   19.13  public interface Lexer {
   19.14  
   19.15      /**
   19.16 -     * Has a @deprecated been encountered in last doc comment?
   19.17 -     * This needs to be reset by client with resetDeprecatedFlag.
   19.18 +     * Consume the next token.
   19.19       */
   19.20 -    boolean deprecatedFlag();
   19.21 -
   19.22 -    void resetDeprecatedFlag();
   19.23 +    void nextToken();
   19.24  
   19.25      /**
   19.26 -     * Returns the documentation string of the current token.
   19.27 +     * Return current token.
   19.28       */
   19.29 -    String docComment();
   19.30 +    Token token();
   19.31  
   19.32      /**
   19.33 -     * Return the last character position of the current token.
   19.34 +     * Return the last character position of the previous token.
   19.35       */
   19.36 -    int endPos();
   19.37 +    Token prevToken();
   19.38 +
   19.39 +    /**
   19.40 +     * Splits the current token in two and return the first (splitted) token.
   19.41 +     * For instance '<<<' is splitted into two tokens '<' and '<<' respectively,
   19.42 +     * and the latter is returned.
   19.43 +     */
   19.44 +    Token split();
   19.45  
   19.46      /**
   19.47       * Return the position where a lexical error occurred;
   19.48 @@ -74,69 +78,4 @@
   19.49       * @return a LineMap
   19.50       */
   19.51      LineMap getLineMap();
   19.52 -
   19.53 -    /**
   19.54 -     * Returns a copy of the input buffer, up to its inputLength.
   19.55 -     * Unicode escape sequences are not translated.
   19.56 -     */
   19.57 -    char[] getRawCharacters();
   19.58 -
   19.59 -    /**
   19.60 -     * Returns a copy of a character array subset of the input buffer.
   19.61 -     * The returned array begins at the <code>beginIndex</code> and
   19.62 -     * extends to the character at index <code>endIndex - 1</code>.
   19.63 -     * Thus the length of the substring is <code>endIndex-beginIndex</code>.
   19.64 -     * This behavior is like
   19.65 -     * <code>String.substring(beginIndex, endIndex)</code>.
   19.66 -     * Unicode escape sequences are not translated.
   19.67 -     *
   19.68 -     * @param beginIndex the beginning index, inclusive.
   19.69 -     * @param endIndex the ending index, exclusive.
   19.70 -     * @throws IndexOutOfBounds if either offset is outside of the
   19.71 -     *         array bounds
   19.72 -     */
   19.73 -    char[] getRawCharacters(int beginIndex, int endIndex);
   19.74 -
   19.75 -    /**
   19.76 -     * Return the name of an identifier or token for the current token.
   19.77 -     */
   19.78 -    Name name();
   19.79 -
   19.80 -    /**
   19.81 -     * Read token.
   19.82 -     */
   19.83 -    void nextToken();
   19.84 -
   19.85 -    /**
   19.86 -     * Return the current token's position: a 0-based
   19.87 -     *  offset from beginning of the raw input stream
   19.88 -     *  (before unicode translation)
   19.89 -     */
   19.90 -    int pos();
   19.91 -
   19.92 -    /**
   19.93 -     * Return the last character position of the previous token.
   19.94 -     */
   19.95 -    int prevEndPos();
   19.96 -
   19.97 -    /**
   19.98 -     * Return the radix of a numeric literal token.
   19.99 -     */
  19.100 -    int radix();
  19.101 -
  19.102 -    /**
  19.103 -     * The value of a literal token, recorded as a string.
  19.104 -     *  For integers, leading 0x and 'l' suffixes are suppressed.
  19.105 -     */
  19.106 -    String stringVal();
  19.107 -
  19.108 -    /**
  19.109 -     * Return the current token, set by nextToken().
  19.110 -     */
  19.111 -    Token token();
  19.112 -
  19.113 -    /**
  19.114 -     * Sets the current token.
  19.115 -     */
  19.116 -    void token(Token token);
  19.117  }
    20.1 --- a/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java	Thu Oct 27 13:54:50 2011 -0700
    20.2 +++ b/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java	Fri Oct 28 17:49:36 2011 -0700
    20.3 @@ -55,7 +55,7 @@
    20.4  
    20.5      final TreeMaker F;
    20.6      final Log log;
    20.7 -    final Keywords keywords;
    20.8 +    final Tokens tokens;
    20.9      final Source source;
   20.10      final Names names;
   20.11      final Options options;
   20.12 @@ -67,7 +67,7 @@
   20.13          this.F = TreeMaker.instance(context);
   20.14          this.log = Log.instance(context);
   20.15          this.names = Names.instance(context);
   20.16 -        this.keywords = Keywords.instance(context);
   20.17 +        this.tokens = Tokens.instance(context);
   20.18          this.source = Source.instance(context);
   20.19          this.options = Options.instance(context);
   20.20          this.scannerFactory = ScannerFactory.instance(context);
    21.1 --- a/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Thu Oct 27 13:54:50 2011 -0700
    21.2 +++ b/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Fri Oct 28 17:49:36 2011 -0700
    21.3 @@ -27,13 +27,11 @@
    21.4  
    21.5  import java.nio.*;
    21.6  
    21.7 -import com.sun.tools.javac.code.Source;
    21.8 -import com.sun.tools.javac.file.JavacFileManager;
    21.9  import com.sun.tools.javac.util.*;
   21.10 +import com.sun.tools.javac.util.Position.LineMap;
   21.11 +import com.sun.tools.javac.parser.JavaTokenizer.*;
   21.12  
   21.13 -
   21.14 -import static com.sun.tools.javac.parser.Token.*;
   21.15 -import static com.sun.tools.javac.util.LayoutCharacters.*;
   21.16 +import static com.sun.tools.javac.parser.Tokens.*;
   21.17  
   21.18  /** The lexical analyzer maps an input stream consisting of
   21.19   *  ASCII characters and Unicode escapes into a token sequence.
   21.20 @@ -45,119 +43,17 @@
   21.21   */
   21.22  public class Scanner implements Lexer {
   21.23  
   21.24 -    private static boolean scannerDebug = false;
   21.25 -
   21.26 -    /* Output variables; set by nextToken():
   21.27 -     */
   21.28 +    private Tokens tokens;
   21.29  
   21.30      /** The token, set by nextToken().
   21.31       */
   21.32      private Token token;
   21.33  
   21.34 -    /** Allow hex floating-point literals.
   21.35 +    /** The previous token, set by nextToken().
   21.36       */
   21.37 -    private boolean allowHexFloats;
   21.38 +    private Token prevToken;
   21.39  
   21.40 -    /** Allow binary literals.
   21.41 -     */
   21.42 -    private boolean allowBinaryLiterals;
   21.43 -
   21.44 -    /** Allow underscores in literals.
   21.45 -     */
   21.46 -    private boolean allowUnderscoresInLiterals;
   21.47 -
   21.48 -    /** The source language setting.
   21.49 -     */
   21.50 -    private Source source;
   21.51 -
   21.52 -    /** The token's position, 0-based offset from beginning of text.
   21.53 -     */
   21.54 -    private int pos;
   21.55 -
   21.56 -    /** Character position just after the last character of the token.
   21.57 -     */
   21.58 -    private int endPos;
   21.59 -
   21.60 -    /** The last character position of the previous token.
   21.61 -     */
   21.62 -    private int prevEndPos;
   21.63 -
   21.64 -    /** The position where a lexical error occurred;
   21.65 -     */
   21.66 -    private int errPos = Position.NOPOS;
   21.67 -
   21.68 -    /** The name of an identifier or token:
   21.69 -     */
   21.70 -    private Name name;
   21.71 -
   21.72 -    /** The radix of a numeric literal token.
   21.73 -     */
   21.74 -    private int radix;
   21.75 -
   21.76 -    /** Has a @deprecated been encountered in last doc comment?
   21.77 -     *  this needs to be reset by client.
   21.78 -     */
   21.79 -    protected boolean deprecatedFlag = false;
   21.80 -
   21.81 -    /** A character buffer for literals.
   21.82 -     */
   21.83 -    private char[] sbuf = new char[128];
   21.84 -    private int sp;
   21.85 -
   21.86 -    /** The input buffer, index of next chacter to be read,
   21.87 -     *  index of one past last character in buffer.
   21.88 -     */
   21.89 -    private char[] buf;
   21.90 -    private int bp;
   21.91 -    private int buflen;
   21.92 -    private int eofPos;
   21.93 -
   21.94 -    /** The current character.
   21.95 -     */
   21.96 -    private char ch;
   21.97 -
   21.98 -    /** The buffer index of the last converted unicode character
   21.99 -     */
  21.100 -    private int unicodeConversionBp = -1;
  21.101 -
  21.102 -    /** The log to be used for error reporting.
  21.103 -     */
  21.104 -    private final Log log;
  21.105 -
  21.106 -    /** The name table. */
  21.107 -    private final Names names;
  21.108 -
  21.109 -    /** The keyword table. */
  21.110 -    private final Keywords keywords;
  21.111 -
  21.112 -    /** Common code for constructors. */
  21.113 -    private Scanner(ScannerFactory fac) {
  21.114 -        log = fac.log;
  21.115 -        names = fac.names;
  21.116 -        keywords = fac.keywords;
  21.117 -        source = fac.source;
  21.118 -        allowBinaryLiterals = source.allowBinaryLiterals();
  21.119 -        allowHexFloats = source.allowHexFloats();
  21.120 -        allowUnderscoresInLiterals = source.allowUnderscoresInLiterals();
  21.121 -    }
  21.122 -
  21.123 -    private static final boolean hexFloatsWork = hexFloatsWork();
  21.124 -    private static boolean hexFloatsWork() {
  21.125 -        try {
  21.126 -            Float.valueOf("0x1.0p1");
  21.127 -            return true;
  21.128 -        } catch (NumberFormatException ex) {
  21.129 -            return false;
  21.130 -        }
  21.131 -    }
  21.132 -
  21.133 -    /** Create a scanner from the input buffer.  buffer must implement
  21.134 -     *  array() and compact(), and remaining() must be less than limit().
  21.135 -     */
  21.136 -    protected Scanner(ScannerFactory fac, CharBuffer buffer) {
  21.137 -        this(fac, JavacFileManager.toArray(buffer), buffer.limit());
  21.138 -    }
  21.139 -
  21.140 +    private JavaTokenizer tokenizer;
  21.141      /**
  21.142       * Create a scanner from the input array.  This method might
  21.143       * modify the array.  To avoid copying the input array, ensure
  21.144 @@ -169,972 +65,49 @@
  21.145       * @param inputLength the size of the input.
  21.146       * Must be positive and less than or equal to input.length.
  21.147       */
  21.148 -    protected Scanner(ScannerFactory fac, char[] input, int inputLength) {
  21.149 -        this(fac);
  21.150 -        eofPos = inputLength;
  21.151 -        if (inputLength == input.length) {
  21.152 -            if (input.length > 0 && Character.isWhitespace(input[input.length - 1])) {
  21.153 -                inputLength--;
  21.154 -            } else {
  21.155 -                char[] newInput = new char[inputLength + 1];
  21.156 -                System.arraycopy(input, 0, newInput, 0, input.length);
  21.157 -                input = newInput;
  21.158 -            }
  21.159 -        }
  21.160 -        buf = input;
  21.161 -        buflen = inputLength;
  21.162 -        buf[buflen] = EOI;
  21.163 -        bp = -1;
  21.164 -        scanChar();
  21.165 +    protected Scanner(ScannerFactory fac, CharBuffer buf) {
  21.166 +        this(fac, new JavaTokenizer(fac, buf));
  21.167      }
  21.168  
  21.169 -    /** Report an error at the given position using the provided arguments.
  21.170 -     */
  21.171 -    private void lexError(int pos, String key, Object... args) {
  21.172 -        log.error(pos, key, args);
  21.173 -        token = ERROR;
  21.174 -        errPos = pos;
  21.175 +    protected Scanner(ScannerFactory fac, char[] buf, int inputLength) {
  21.176 +        this(fac, new JavaTokenizer(fac, buf, inputLength));
  21.177      }
  21.178  
  21.179 -    /** Report an error at the current token position using the provided
  21.180 -     *  arguments.
  21.181 -     */
  21.182 -    private void lexError(String key, Object... args) {
  21.183 -        lexError(pos, key, args);
  21.184 +    protected Scanner(ScannerFactory fac, JavaTokenizer tokenizer) {
  21.185 +        this.tokenizer = tokenizer;
  21.186 +        tokens = fac.tokens;
  21.187 +        token = prevToken = DUMMY;
  21.188      }
  21.189  
  21.190 -    /** Convert an ASCII digit from its base (8, 10, or 16)
  21.191 -     *  to its value.
  21.192 -     */
  21.193 -    private int digit(int base) {
  21.194 -        char c = ch;
  21.195 -        int result = Character.digit(c, base);
  21.196 -        if (result >= 0 && c > 0x7f) {
  21.197 -            lexError(pos+1, "illegal.nonascii.digit");
  21.198 -            ch = "0123456789abcdef".charAt(result);
  21.199 -        }
  21.200 -        return result;
  21.201 -    }
  21.202 -
  21.203 -    /** Convert unicode escape; bp points to initial '\' character
  21.204 -     *  (Spec 3.3).
  21.205 -     */
  21.206 -    private void convertUnicode() {
  21.207 -        if (ch == '\\' && unicodeConversionBp != bp) {
  21.208 -            bp++; ch = buf[bp];
  21.209 -            if (ch == 'u') {
  21.210 -                do {
  21.211 -                    bp++; ch = buf[bp];
  21.212 -                } while (ch == 'u');
  21.213 -                int limit = bp + 3;
  21.214 -                if (limit < buflen) {
  21.215 -                    int d = digit(16);
  21.216 -                    int code = d;
  21.217 -                    while (bp < limit && d >= 0) {
  21.218 -                        bp++; ch = buf[bp];
  21.219 -                        d = digit(16);
  21.220 -                        code = (code << 4) + d;
  21.221 -                    }
  21.222 -                    if (d >= 0) {
  21.223 -                        ch = (char)code;
  21.224 -                        unicodeConversionBp = bp;
  21.225 -                        return;
  21.226 -                    }
  21.227 -                }
  21.228 -                lexError(bp, "illegal.unicode.esc");
  21.229 -            } else {
  21.230 -                bp--;
  21.231 -                ch = '\\';
  21.232 -            }
  21.233 -        }
  21.234 -    }
  21.235 -
  21.236 -    /** Read next character.
  21.237 -     */
  21.238 -    private void scanChar() {
  21.239 -        ch = buf[++bp];
  21.240 -        if (ch == '\\') {
  21.241 -            convertUnicode();
  21.242 -        }
  21.243 -    }
  21.244 -
  21.245 -    /** Read next character in comment, skipping over double '\' characters.
  21.246 -     */
  21.247 -    private void scanCommentChar() {
  21.248 -        scanChar();
  21.249 -        if (ch == '\\') {
  21.250 -            if (buf[bp+1] == '\\' && unicodeConversionBp != bp) {
  21.251 -                bp++;
  21.252 -            } else {
  21.253 -                convertUnicode();
  21.254 -            }
  21.255 -        }
  21.256 -    }
  21.257 -
  21.258 -    /** Append a character to sbuf.
  21.259 -     */
  21.260 -    private void putChar(char ch) {
  21.261 -        if (sp == sbuf.length) {
  21.262 -            char[] newsbuf = new char[sbuf.length * 2];
  21.263 -            System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length);
  21.264 -            sbuf = newsbuf;
  21.265 -        }
  21.266 -        sbuf[sp++] = ch;
  21.267 -    }
  21.268 -
  21.269 -    /** Read next character in character or string literal and copy into sbuf.
  21.270 -     */
  21.271 -    private void scanLitChar() {
  21.272 -        if (ch == '\\') {
  21.273 -            if (buf[bp+1] == '\\' && unicodeConversionBp != bp) {
  21.274 -                bp++;
  21.275 -                putChar('\\');
  21.276 -                scanChar();
  21.277 -            } else {
  21.278 -                scanChar();
  21.279 -                switch (ch) {
  21.280 -                case '0': case '1': case '2': case '3':
  21.281 -                case '4': case '5': case '6': case '7':
  21.282 -                    char leadch = ch;
  21.283 -                    int oct = digit(8);
  21.284 -                    scanChar();
  21.285 -                    if ('0' <= ch && ch <= '7') {
  21.286 -                        oct = oct * 8 + digit(8);
  21.287 -                        scanChar();
  21.288 -                        if (leadch <= '3' && '0' <= ch && ch <= '7') {
  21.289 -                            oct = oct * 8 + digit(8);
  21.290 -                            scanChar();
  21.291 -                        }
  21.292 -                    }
  21.293 -                    putChar((char)oct);
  21.294 -                    break;
  21.295 -                case 'b':
  21.296 -                    putChar('\b'); scanChar(); break;
  21.297 -                case 't':
  21.298 -                    putChar('\t'); scanChar(); break;
  21.299 -                case 'n':
  21.300 -                    putChar('\n'); scanChar(); break;
  21.301 -                case 'f':
  21.302 -                    putChar('\f'); scanChar(); break;
  21.303 -                case 'r':
  21.304 -                    putChar('\r'); scanChar(); break;
  21.305 -                case '\'':
  21.306 -                    putChar('\''); scanChar(); break;
  21.307 -                case '\"':
  21.308 -                    putChar('\"'); scanChar(); break;
  21.309 -                case '\\':
  21.310 -                    putChar('\\'); scanChar(); break;
  21.311 -                default:
  21.312 -                    lexError(bp, "illegal.esc.char");
  21.313 -                }
  21.314 -            }
  21.315 -        } else if (bp != buflen) {
  21.316 -            putChar(ch); scanChar();
  21.317 -        }
  21.318 -    }
  21.319 -
  21.320 -    private void scanDigits(int digitRadix) {
  21.321 -        char saveCh;
  21.322 -        int savePos;
  21.323 -        do {
  21.324 -            if (ch != '_') {
  21.325 -                putChar(ch);
  21.326 -            } else {
  21.327 -                if (!allowUnderscoresInLiterals) {
  21.328 -                    lexError("unsupported.underscore.lit", source.name);
  21.329 -                    allowUnderscoresInLiterals = true;
  21.330 -                }
  21.331 -            }
  21.332 -            saveCh = ch;
  21.333 -            savePos = bp;
  21.334 -            scanChar();
  21.335 -        } while (digit(digitRadix) >= 0 || ch == '_');
  21.336 -        if (saveCh == '_')
  21.337 -            lexError(savePos, "illegal.underscore");
  21.338 -    }
  21.339 -
  21.340 -    /** Read fractional part of hexadecimal floating point number.
  21.341 -     */
  21.342 -    private void scanHexExponentAndSuffix() {
  21.343 -        if (ch == 'p' || ch == 'P') {
  21.344 -            putChar(ch);
  21.345 -            scanChar();
  21.346 -            skipIllegalUnderscores();
  21.347 -            if (ch == '+' || ch == '-') {
  21.348 -                putChar(ch);
  21.349 -                scanChar();
  21.350 -            }
  21.351 -            skipIllegalUnderscores();
  21.352 -            if ('0' <= ch && ch <= '9') {
  21.353 -                scanDigits(10);
  21.354 -                if (!allowHexFloats) {
  21.355 -                    lexError("unsupported.fp.lit", source.name);
  21.356 -                    allowHexFloats = true;
  21.357 -                }
  21.358 -                else if (!hexFloatsWork)
  21.359 -                    lexError("unsupported.cross.fp.lit");
  21.360 -            } else
  21.361 -                lexError("malformed.fp.lit");
  21.362 -        } else {
  21.363 -            lexError("malformed.fp.lit");
  21.364 -        }
  21.365 -        if (ch == 'f' || ch == 'F') {
  21.366 -            putChar(ch);
  21.367 -            scanChar();
  21.368 -            token = FLOATLITERAL;
  21.369 -        } else {
  21.370 -            if (ch == 'd' || ch == 'D') {
  21.371 -                putChar(ch);
  21.372 -                scanChar();
  21.373 -            }
  21.374 -            token = DOUBLELITERAL;
  21.375 -        }
  21.376 -    }
  21.377 -
  21.378 -    /** Read fractional part of floating point number.
  21.379 -     */
  21.380 -    private void scanFraction() {
  21.381 -        skipIllegalUnderscores();
  21.382 -        if ('0' <= ch && ch <= '9') {
  21.383 -            scanDigits(10);
  21.384 -        }
  21.385 -        int sp1 = sp;
  21.386 -        if (ch == 'e' || ch == 'E') {
  21.387 -            putChar(ch);
  21.388 -            scanChar();
  21.389 -            skipIllegalUnderscores();
  21.390 -            if (ch == '+' || ch == '-') {
  21.391 -                putChar(ch);
  21.392 -                scanChar();
  21.393 -            }
  21.394 -            skipIllegalUnderscores();
  21.395 -            if ('0' <= ch && ch <= '9') {
  21.396 -                scanDigits(10);
  21.397 -                return;
  21.398 -            }
  21.399 -            lexError("malformed.fp.lit");
  21.400 -            sp = sp1;
  21.401 -        }
  21.402 -    }
  21.403 -
  21.404 -    /** Read fractional part and 'd' or 'f' suffix of floating point number.
  21.405 -     */
  21.406 -    private void scanFractionAndSuffix() {
  21.407 -        this.radix = 10;
  21.408 -        scanFraction();
  21.409 -        if (ch == 'f' || ch == 'F') {
  21.410 -            putChar(ch);
  21.411 -            scanChar();
  21.412 -            token = FLOATLITERAL;
  21.413 -        } else {
  21.414 -            if (ch == 'd' || ch == 'D') {
  21.415 -                putChar(ch);
  21.416 -                scanChar();
  21.417 -            }
  21.418 -            token = DOUBLELITERAL;
  21.419 -        }
  21.420 -    }
  21.421 -
  21.422 -    /** Read fractional part and 'd' or 'f' suffix of floating point number.
  21.423 -     */
  21.424 -    private void scanHexFractionAndSuffix(boolean seendigit) {
  21.425 -        this.radix = 16;
  21.426 -        Assert.check(ch == '.');
  21.427 -        putChar(ch);
  21.428 -        scanChar();
  21.429 -        skipIllegalUnderscores();
  21.430 -        if (digit(16) >= 0) {
  21.431 -            seendigit = true;
  21.432 -            scanDigits(16);
  21.433 -        }
  21.434 -        if (!seendigit)
  21.435 -            lexError("invalid.hex.number");
  21.436 -        else
  21.437 -            scanHexExponentAndSuffix();
  21.438 -    }
  21.439 -
  21.440 -    private void skipIllegalUnderscores() {
  21.441 -        if (ch == '_') {
  21.442 -            lexError(bp, "illegal.underscore");
  21.443 -            while (ch == '_')
  21.444 -                scanChar();
  21.445 -        }
  21.446 -    }
  21.447 -
  21.448 -    /** Read a number.
  21.449 -     *  @param radix  The radix of the number; one of 2, j8, 10, 16.
  21.450 -     */
  21.451 -    private void scanNumber(int radix) {
  21.452 -        this.radix = radix;
  21.453 -        // for octal, allow base-10 digit in case it's a float literal
  21.454 -        int digitRadix = (radix == 8 ? 10 : radix);
  21.455 -        boolean seendigit = false;
  21.456 -        if (digit(digitRadix) >= 0) {
  21.457 -            seendigit = true;
  21.458 -            scanDigits(digitRadix);
  21.459 -        }
  21.460 -        if (radix == 16 && ch == '.') {
  21.461 -            scanHexFractionAndSuffix(seendigit);
  21.462 -        } else if (seendigit && radix == 16 && (ch == 'p' || ch == 'P')) {
  21.463 -            scanHexExponentAndSuffix();
  21.464 -        } else if (digitRadix == 10 && ch == '.') {
  21.465 -            putChar(ch);
  21.466 -            scanChar();
  21.467 -            scanFractionAndSuffix();
  21.468 -        } else if (digitRadix == 10 &&
  21.469 -                   (ch == 'e' || ch == 'E' ||
  21.470 -                    ch == 'f' || ch == 'F' ||
  21.471 -                    ch == 'd' || ch == 'D')) {
  21.472 -            scanFractionAndSuffix();
  21.473 -        } else {
  21.474 -            if (ch == 'l' || ch == 'L') {
  21.475 -                scanChar();
  21.476 -                token = LONGLITERAL;
  21.477 -            } else {
  21.478 -                token = INTLITERAL;
  21.479 -            }
  21.480 -        }
  21.481 -    }
  21.482 -
  21.483 -    /** Read an identifier.
  21.484 -     */
  21.485 -    private void scanIdent() {
  21.486 -        boolean isJavaIdentifierPart;
  21.487 -        char high;
  21.488 -        do {
  21.489 -            if (sp == sbuf.length) putChar(ch); else sbuf[sp++] = ch;
  21.490 -            // optimization, was: putChar(ch);
  21.491 -
  21.492 -            scanChar();
  21.493 -            switch (ch) {
  21.494 -            case 'A': case 'B': case 'C': case 'D': case 'E':
  21.495 -            case 'F': case 'G': case 'H': case 'I': case 'J':
  21.496 -            case 'K': case 'L': case 'M': case 'N': case 'O':
  21.497 -            case 'P': case 'Q': case 'R': case 'S': case 'T':
  21.498 -            case 'U': case 'V': case 'W': case 'X': case 'Y':
  21.499 -            case 'Z':
  21.500 -            case 'a': case 'b': case 'c': case 'd': case 'e':
  21.501 -            case 'f': case 'g': case 'h': case 'i': case 'j':
  21.502 -            case 'k': case 'l': case 'm': case 'n': case 'o':
  21.503 -            case 'p': case 'q': case 'r': case 's': case 't':
  21.504 -            case 'u': case 'v': case 'w': case 'x': case 'y':
  21.505 -            case 'z':
  21.506 -            case '$': case '_':
  21.507 -            case '0': case '1': case '2': case '3': case '4':
  21.508 -            case '5': case '6': case '7': case '8': case '9':
  21.509 -            case '\u0000': case '\u0001': case '\u0002': case '\u0003':
  21.510 -            case '\u0004': case '\u0005': case '\u0006': case '\u0007':
  21.511 -            case '\u0008': case '\u000E': case '\u000F': case '\u0010':
  21.512 -            case '\u0011': case '\u0012': case '\u0013': case '\u0014':
  21.513 -            case '\u0015': case '\u0016': case '\u0017':
  21.514 -            case '\u0018': case '\u0019': case '\u001B':
  21.515 -            case '\u007F':
  21.516 -                break;
  21.517 -            case '\u001A': // EOI is also a legal identifier part
  21.518 -                if (bp >= buflen) {
  21.519 -                    name = names.fromChars(sbuf, 0, sp);
  21.520 -                    token = keywords.key(name);
  21.521 -                    return;
  21.522 -                }
  21.523 -                break;
  21.524 -            default:
  21.525 -                if (ch < '\u0080') {
  21.526 -                    // all ASCII range chars already handled, above
  21.527 -                    isJavaIdentifierPart = false;
  21.528 -                } else {
  21.529 -                    high = scanSurrogates();
  21.530 -                    if (high != 0) {
  21.531 -                        if (sp == sbuf.length) {
  21.532 -                            putChar(high);
  21.533 -                        } else {
  21.534 -                            sbuf[sp++] = high;
  21.535 -                        }
  21.536 -                        isJavaIdentifierPart = Character.isJavaIdentifierPart(
  21.537 -                            Character.toCodePoint(high, ch));
  21.538 -                    } else {
  21.539 -                        isJavaIdentifierPart = Character.isJavaIdentifierPart(ch);
  21.540 -                    }
  21.541 -                }
  21.542 -                if (!isJavaIdentifierPart) {
  21.543 -                    name = names.fromChars(sbuf, 0, sp);
  21.544 -                    token = keywords.key(name);
  21.545 -                    return;
  21.546 -                }
  21.547 -            }
  21.548 -        } while (true);
  21.549 -    }
  21.550 -
  21.551 -    /** Are surrogates supported?
  21.552 -     */
  21.553 -    final static boolean surrogatesSupported = surrogatesSupported();
  21.554 -    private static boolean surrogatesSupported() {
  21.555 -        try {
  21.556 -            Character.isHighSurrogate('a');
  21.557 -            return true;
  21.558 -        } catch (NoSuchMethodError ex) {
  21.559 -            return false;
  21.560 -        }
  21.561 -    }
  21.562 -
  21.563 -    /** Scan surrogate pairs.  If 'ch' is a high surrogate and
  21.564 -     *  the next character is a low surrogate, then put the low
  21.565 -     *  surrogate in 'ch', and return the high surrogate.
  21.566 -     *  otherwise, just return 0.
  21.567 -     */
  21.568 -    private char scanSurrogates() {
  21.569 -        if (surrogatesSupported && Character.isHighSurrogate(ch)) {
  21.570 -            char high = ch;
  21.571 -
  21.572 -            scanChar();
  21.573 -
  21.574 -            if (Character.isLowSurrogate(ch)) {
  21.575 -                return high;
  21.576 -            }
  21.577 -
  21.578 -            ch = high;
  21.579 -        }
  21.580 -
  21.581 -        return 0;
  21.582 -    }
  21.583 -
  21.584 -    /** Return true if ch can be part of an operator.
  21.585 -     */
  21.586 -    private boolean isSpecial(char ch) {
  21.587 -        switch (ch) {
  21.588 -        case '!': case '%': case '&': case '*': case '?':
  21.589 -        case '+': case '-': case ':': case '<': case '=':
  21.590 -        case '>': case '^': case '|': case '~':
  21.591 -        case '@':
  21.592 -            return true;
  21.593 -        default:
  21.594 -            return false;
  21.595 -        }
  21.596 -    }
  21.597 -
  21.598 -    /** Read longest possible sequence of special characters and convert
  21.599 -     *  to token.
  21.600 -     */
  21.601 -    private void scanOperator() {
  21.602 -        while (true) {
  21.603 -            putChar(ch);
  21.604 -            Name newname = names.fromChars(sbuf, 0, sp);
  21.605 -            if (keywords.key(newname) == IDENTIFIER) {
  21.606 -                sp--;
  21.607 -                break;
  21.608 -            }
  21.609 -            name = newname;
  21.610 -            token = keywords.key(newname);
  21.611 -            scanChar();
  21.612 -            if (!isSpecial(ch)) break;
  21.613 -        }
  21.614 -    }
  21.615 -
  21.616 -    /**
  21.617 -     * Scan a documention comment; determine if a deprecated tag is present.
  21.618 -     * Called once the initial /, * have been skipped, positioned at the second *
  21.619 -     * (which is treated as the beginning of the first line).
  21.620 -     * Stops positioned at the closing '/'.
  21.621 -     */
  21.622 -    @SuppressWarnings("fallthrough")
  21.623 -    private void scanDocComment() {
  21.624 -        boolean deprecatedPrefix = false;
  21.625 -
  21.626 -        forEachLine:
  21.627 -        while (bp < buflen) {
  21.628 -
  21.629 -            // Skip optional WhiteSpace at beginning of line
  21.630 -            while (bp < buflen && (ch == ' ' || ch == '\t' || ch == FF)) {
  21.631 -                scanCommentChar();
  21.632 -            }
  21.633 -
  21.634 -            // Skip optional consecutive Stars
  21.635 -            while (bp < buflen && ch == '*') {
  21.636 -                scanCommentChar();
  21.637 -                if (ch == '/') {
  21.638 -                    return;
  21.639 -                }
  21.640 -            }
  21.641 -
  21.642 -            // Skip optional WhiteSpace after Stars
  21.643 -            while (bp < buflen && (ch == ' ' || ch == '\t' || ch == FF)) {
  21.644 -                scanCommentChar();
  21.645 -            }
  21.646 -
  21.647 -            deprecatedPrefix = false;
  21.648 -            // At beginning of line in the JavaDoc sense.
  21.649 -            if (bp < buflen && ch == '@' && !deprecatedFlag) {
  21.650 -                scanCommentChar();
  21.651 -                if (bp < buflen && ch == 'd') {
  21.652 -                    scanCommentChar();
  21.653 -                    if (bp < buflen && ch == 'e') {
  21.654 -                        scanCommentChar();
  21.655 -                        if (bp < buflen && ch == 'p') {
  21.656 -                            scanCommentChar();
  21.657 -                            if (bp < buflen && ch == 'r') {
  21.658 -                                scanCommentChar();
  21.659 -                                if (bp < buflen && ch == 'e') {
  21.660 -                                    scanCommentChar();
  21.661 -                                    if (bp < buflen && ch == 'c') {
  21.662 -                                        scanCommentChar();
  21.663 -                                        if (bp < buflen && ch == 'a') {
  21.664 -                                            scanCommentChar();
  21.665 -                                            if (bp < buflen && ch == 't') {
  21.666 -                                                scanCommentChar();
  21.667 -                                                if (bp < buflen && ch == 'e') {
  21.668 -                                                    scanCommentChar();
  21.669 -                                                    if (bp < buflen && ch == 'd') {
  21.670 -                                                        deprecatedPrefix = true;
  21.671 -                                                        scanCommentChar();
  21.672 -                                                    }}}}}}}}}}}
  21.673 -            if (deprecatedPrefix && bp < buflen) {
  21.674 -                if (Character.isWhitespace(ch)) {
  21.675 -                    deprecatedFlag = true;
  21.676 -                } else if (ch == '*') {
  21.677 -                    scanCommentChar();
  21.678 -                    if (ch == '/') {
  21.679 -                        deprecatedFlag = true;
  21.680 -                        return;
  21.681 -                    }
  21.682 -                }
  21.683 -            }
  21.684 -
  21.685 -            // Skip rest of line
  21.686 -            while (bp < buflen) {
  21.687 -                switch (ch) {
  21.688 -                case '*':
  21.689 -                    scanCommentChar();
  21.690 -                    if (ch == '/') {
  21.691 -                        return;
  21.692 -                    }
  21.693 -                    break;
  21.694 -                case CR: // (Spec 3.4)
  21.695 -                    scanCommentChar();
  21.696 -                    if (ch != LF) {
  21.697 -                        continue forEachLine;
  21.698 -                    }
  21.699 -                    /* fall through to LF case */
  21.700 -                case LF: // (Spec 3.4)
  21.701 -                    scanCommentChar();
  21.702 -                    continue forEachLine;
  21.703 -                default:
  21.704 -                    scanCommentChar();
  21.705 -                }
  21.706 -            } // rest of line
  21.707 -        } // forEachLine
  21.708 -        return;
  21.709 -    }
  21.710 -
  21.711 -    /** The value of a literal token, recorded as a string.
  21.712 -     *  For integers, leading 0x and 'l' suffixes are suppressed.
  21.713 -     */
  21.714 -    public String stringVal() {
  21.715 -        return new String(sbuf, 0, sp);
  21.716 -    }
  21.717 -
  21.718 -    /** Read token.
  21.719 -     */
  21.720 -    public void nextToken() {
  21.721 -
  21.722 -        try {
  21.723 -            prevEndPos = endPos;
  21.724 -            sp = 0;
  21.725 -
  21.726 -            while (true) {
  21.727 -                pos = bp;
  21.728 -                switch (ch) {
  21.729 -                case ' ': // (Spec 3.6)
  21.730 -                case '\t': // (Spec 3.6)
  21.731 -                case FF: // (Spec 3.6)
  21.732 -                    do {
  21.733 -                        scanChar();
  21.734 -                    } while (ch == ' ' || ch == '\t' || ch == FF);
  21.735 -                    endPos = bp;
  21.736 -                    processWhiteSpace();
  21.737 -                    break;
  21.738 -                case LF: // (Spec 3.4)
  21.739 -                    scanChar();
  21.740 -                    endPos = bp;
  21.741 -                    processLineTerminator();
  21.742 -                    break;
  21.743 -                case CR: // (Spec 3.4)
  21.744 -                    scanChar();
  21.745 -                    if (ch == LF) {
  21.746 -                        scanChar();
  21.747 -                    }
  21.748 -                    endPos = bp;
  21.749 -                    processLineTerminator();
  21.750 -                    break;
  21.751 -                case 'A': case 'B': case 'C': case 'D': case 'E':
  21.752 -                case 'F': case 'G': case 'H': case 'I': case 'J':
  21.753 -                case 'K': case 'L': case 'M': case 'N': case 'O':
  21.754 -                case 'P': case 'Q': case 'R': case 'S': case 'T':
  21.755 -                case 'U': case 'V': case 'W': case 'X': case 'Y':
  21.756 -                case 'Z':
  21.757 -                case 'a': case 'b': case 'c': case 'd': case 'e':
  21.758 -                case 'f': case 'g': case 'h': case 'i': case 'j':
  21.759 -                case 'k': case 'l': case 'm': case 'n': case 'o':
  21.760 -                case 'p': case 'q': case 'r': case 's': case 't':
  21.761 -                case 'u': case 'v': case 'w': case 'x': case 'y':
  21.762 -                case 'z':
  21.763 -                case '$': case '_':
  21.764 -                    scanIdent();
  21.765 -                    return;
  21.766 -                case '0':
  21.767 -                    scanChar();
  21.768 -                    if (ch == 'x' || ch == 'X') {
  21.769 -                        scanChar();
  21.770 -                        skipIllegalUnderscores();
  21.771 -                        if (ch == '.') {
  21.772 -                            scanHexFractionAndSuffix(false);
  21.773 -                        } else if (digit(16) < 0) {
  21.774 -                            lexError("invalid.hex.number");
  21.775 -                        } else {
  21.776 -                            scanNumber(16);
  21.777 -                        }
  21.778 -                    } else if (ch == 'b' || ch == 'B') {
  21.779 -                        if (!allowBinaryLiterals) {
  21.780 -                            lexError("unsupported.binary.lit", source.name);
  21.781 -                            allowBinaryLiterals = true;
  21.782 -                        }
  21.783 -                        scanChar();
  21.784 -                        skipIllegalUnderscores();
  21.785 -                        if (digit(2) < 0) {
  21.786 -                            lexError("invalid.binary.number");
  21.787 -                        } else {
  21.788 -                            scanNumber(2);
  21.789 -                        }
  21.790 -                    } else {
  21.791 -                        putChar('0');
  21.792 -                        if (ch == '_') {
  21.793 -                            int savePos = bp;
  21.794 -                            do {
  21.795 -                                scanChar();
  21.796 -                            } while (ch == '_');
  21.797 -                            if (digit(10) < 0) {
  21.798 -                                lexError(savePos, "illegal.underscore");
  21.799 -                            }
  21.800 -                        }
  21.801 -                        scanNumber(8);
  21.802 -                    }
  21.803 -                    return;
  21.804 -                case '1': case '2': case '3': case '4':
  21.805 -                case '5': case '6': case '7': case '8': case '9':
  21.806 -                    scanNumber(10);
  21.807 -                    return;
  21.808 -                case '.':
  21.809 -                    scanChar();
  21.810 -                    if ('0' <= ch && ch <= '9') {
  21.811 -                        putChar('.');
  21.812 -                        scanFractionAndSuffix();
  21.813 -                    } else if (ch == '.') {
  21.814 -                        putChar('.'); putChar('.');
  21.815 -                        scanChar();
  21.816 -                        if (ch == '.') {
  21.817 -                            scanChar();
  21.818 -                            putChar('.');
  21.819 -                            token = ELLIPSIS;
  21.820 -                        } else {
  21.821 -                            lexError("malformed.fp.lit");
  21.822 -                        }
  21.823 -                    } else {
  21.824 -                        token = DOT;
  21.825 -                    }
  21.826 -                    return;
  21.827 -                case ',':
  21.828 -                    scanChar(); token = COMMA; return;
  21.829 -                case ';':
  21.830 -                    scanChar(); token = SEMI; return;
  21.831 -                case '(':
  21.832 -                    scanChar(); token = LPAREN; return;
  21.833 -                case ')':
  21.834 -                    scanChar(); token = RPAREN; return;
  21.835 -                case '[':
  21.836 -                    scanChar(); token = LBRACKET; return;
  21.837 -                case ']':
  21.838 -                    scanChar(); token = RBRACKET; return;
  21.839 -                case '{':
  21.840 -                    scanChar(); token = LBRACE; return;
  21.841 -                case '}':
  21.842 -                    scanChar(); token = RBRACE; return;
  21.843 -                case '/':
  21.844 -                    scanChar();
  21.845 -                    if (ch == '/') {
  21.846 -                        do {
  21.847 -                            scanCommentChar();
  21.848 -                        } while (ch != CR && ch != LF && bp < buflen);
  21.849 -                        if (bp < buflen) {
  21.850 -                            endPos = bp;
  21.851 -                            processComment(CommentStyle.LINE);
  21.852 -                        }
  21.853 -                        break;
  21.854 -                    } else if (ch == '*') {
  21.855 -                        scanChar();
  21.856 -                        CommentStyle style;
  21.857 -                        if (ch == '*') {
  21.858 -                            style = CommentStyle.JAVADOC;
  21.859 -                            scanDocComment();
  21.860 -                        } else {
  21.861 -                            style = CommentStyle.BLOCK;
  21.862 -                            while (bp < buflen) {
  21.863 -                                if (ch == '*') {
  21.864 -                                    scanChar();
  21.865 -                                    if (ch == '/') break;
  21.866 -                                } else {
  21.867 -                                    scanCommentChar();
  21.868 -                                }
  21.869 -                            }
  21.870 -                        }
  21.871 -                        if (ch == '/') {
  21.872 -                            scanChar();
  21.873 -                            endPos = bp;
  21.874 -                            processComment(style);
  21.875 -                            break;
  21.876 -                        } else {
  21.877 -                            lexError("unclosed.comment");
  21.878 -                            return;
  21.879 -                        }
  21.880 -                    } else if (ch == '=') {
  21.881 -                        name = names.slashequals;
  21.882 -                        token = SLASHEQ;
  21.883 -                        scanChar();
  21.884 -                    } else {
  21.885 -                        name = names.slash;
  21.886 -                        token = SLASH;
  21.887 -                    }
  21.888 -                    return;
  21.889 -                case '\'':
  21.890 -                    scanChar();
  21.891 -                    if (ch == '\'') {
  21.892 -                        lexError("empty.char.lit");
  21.893 -                    } else {
  21.894 -                        if (ch == CR || ch == LF)
  21.895 -                            lexError(pos, "illegal.line.end.in.char.lit");
  21.896 -                        scanLitChar();
  21.897 -                        if (ch == '\'') {
  21.898 -                            scanChar();
  21.899 -                            token = CHARLITERAL;
  21.900 -                        } else {
  21.901 -                            lexError(pos, "unclosed.char.lit");
  21.902 -                        }
  21.903 -                    }
  21.904 -                    return;
  21.905 -                case '\"':
  21.906 -                    scanChar();
  21.907 -                    while (ch != '\"' && ch != CR && ch != LF && bp < buflen)
  21.908 -                        scanLitChar();
  21.909 -                    if (ch == '\"') {
  21.910 -                        token = STRINGLITERAL;
  21.911 -                        scanChar();
  21.912 -                    } else {
  21.913 -                        lexError(pos, "unclosed.str.lit");
  21.914 -                    }
  21.915 -                    return;
  21.916 -                default:
  21.917 -                    if (isSpecial(ch)) {
  21.918 -                        scanOperator();
  21.919 -                    } else {
  21.920 -                        boolean isJavaIdentifierStart;
  21.921 -                        if (ch < '\u0080') {
  21.922 -                            // all ASCII range chars already handled, above
  21.923 -                            isJavaIdentifierStart = false;
  21.924 -                        } else {
  21.925 -                            char high = scanSurrogates();
  21.926 -                            if (high != 0) {
  21.927 -                                if (sp == sbuf.length) {
  21.928 -                                    putChar(high);
  21.929 -                                } else {
  21.930 -                                    sbuf[sp++] = high;
  21.931 -                                }
  21.932 -
  21.933 -                                isJavaIdentifierStart = Character.isJavaIdentifierStart(
  21.934 -                                    Character.toCodePoint(high, ch));
  21.935 -                            } else {
  21.936 -                                isJavaIdentifierStart = Character.isJavaIdentifierStart(ch);
  21.937 -                            }
  21.938 -                        }
  21.939 -                        if (isJavaIdentifierStart) {
  21.940 -                            scanIdent();
  21.941 -                        } else if (bp == buflen || ch == EOI && bp+1 == buflen) { // JLS 3.5
  21.942 -                            token = EOF;
  21.943 -                            pos = bp = eofPos;
  21.944 -                        } else {
  21.945 -                            lexError("illegal.char", String.valueOf((int)ch));
  21.946 -                            scanChar();
  21.947 -                        }
  21.948 -                    }
  21.949 -                    return;
  21.950 -                }
  21.951 -            }
  21.952 -        } finally {
  21.953 -            endPos = bp;
  21.954 -            if (scannerDebug)
  21.955 -                System.out.println("nextToken(" + pos
  21.956 -                                   + "," + endPos + ")=|" +
  21.957 -                                   new String(getRawCharacters(pos, endPos))
  21.958 -                                   + "|");
  21.959 -        }
  21.960 -    }
  21.961 -
  21.962 -    /** Return the current token, set by nextToken().
  21.963 -     */
  21.964      public Token token() {
  21.965          return token;
  21.966      }
  21.967  
  21.968 -    /** Sets the current token.
  21.969 -     * This method is primarily used to update the token stream when the
  21.970 -     * parser is handling the end of nested type arguments such as
  21.971 -     * {@code List<List<String>>} and needs to disambiguate between
  21.972 -     * repeated use of ">" and relation operators such as ">>" and ">>>". Noting
  21.973 -     * that this does not handle arbitrary tokens containing Unicode escape
  21.974 -     * sequences.
  21.975 -     */
  21.976 -    public void token(Token token) {
  21.977 -        pos += this.token.name.length() - token.name.length();
  21.978 -        prevEndPos = pos;
  21.979 -        this.token = token;
  21.980 +    public Token prevToken() {
  21.981 +        return prevToken;
  21.982      }
  21.983  
  21.984 -    /** Return the current token's position: a 0-based
  21.985 -     *  offset from beginning of the raw input stream
  21.986 -     *  (before unicode translation)
  21.987 -     */
  21.988 -    public int pos() {
  21.989 -        return pos;
  21.990 +    public void nextToken() {
  21.991 +        prevToken = token;
  21.992 +        token = tokenizer.readToken();
  21.993      }
  21.994  
  21.995 -    /** Return the last character position of the current token.
  21.996 -     */
  21.997 -    public int endPos() {
  21.998 -        return endPos;
  21.999 +    public Token split() {
 21.1000 +        Token[] splitTokens = token.split(tokens);
 21.1001 +        prevToken = splitTokens[0];
 21.1002 +        token = splitTokens[1];
 21.1003 +        return token;
 21.1004      }
 21.1005  
 21.1006 -    /** Return the last character position of the previous token.
 21.1007 -     */
 21.1008 -    public int prevEndPos() {
 21.1009 -        return prevEndPos;
 21.1010 +    public LineMap getLineMap() {
 21.1011 +        return tokenizer.getLineMap();
 21.1012      }
 21.1013  
 21.1014 -    /** Return the position where a lexical error occurred;
 21.1015 -     */
 21.1016      public int errPos() {
 21.1017 -        return errPos;
 21.1018 +        return tokenizer.errPos();
 21.1019      }
 21.1020  
 21.1021 -    /** Set the position where a lexical error occurred;
 21.1022 -     */
 21.1023      public void errPos(int pos) {
 21.1024 -        errPos = pos;
 21.1025 +        tokenizer.errPos(pos);
 21.1026      }
 21.1027 -
 21.1028 -    /** Return the name of an identifier or token for the current token.
 21.1029 -     */
 21.1030 -    public Name name() {
 21.1031 -        return name;
 21.1032 -    }
 21.1033 -
 21.1034 -    /** Return the radix of a numeric literal token.
 21.1035 -     */
 21.1036 -    public int radix() {
 21.1037 -        return radix;
 21.1038 -    }
 21.1039 -
 21.1040 -    /** Has a @deprecated been encountered in last doc comment?
 21.1041 -     *  This needs to be reset by client with resetDeprecatedFlag.
 21.1042 -     */
 21.1043 -    public boolean deprecatedFlag() {
 21.1044 -        return deprecatedFlag;
 21.1045 -    }
 21.1046 -
 21.1047 -    public void resetDeprecatedFlag() {
 21.1048 -        deprecatedFlag = false;
 21.1049 -    }
 21.1050 -
 21.1051 -    /**
 21.1052 -     * Returns the documentation string of the current token.
 21.1053 -     */
 21.1054 -    public String docComment() {
 21.1055 -        return null;
 21.1056 -    }
 21.1057 -
 21.1058 -    /**
 21.1059 -     * Returns a copy of the input buffer, up to its inputLength.
 21.1060 -     * Unicode escape sequences are not translated.
 21.1061 -     */
 21.1062 -    public char[] getRawCharacters() {
 21.1063 -        char[] chars = new char[buflen];
 21.1064 -        System.arraycopy(buf, 0, chars, 0, buflen);
 21.1065 -        return chars;
 21.1066 -    }
 21.1067 -
 21.1068 -    /**
 21.1069 -     * Returns a copy of a character array subset of the input buffer.
 21.1070 -     * The returned array begins at the <code>beginIndex</code> and
 21.1071 -     * extends to the character at index <code>endIndex - 1</code>.
 21.1072 -     * Thus the length of the substring is <code>endIndex-beginIndex</code>.
 21.1073 -     * This behavior is like
 21.1074 -     * <code>String.substring(beginIndex, endIndex)</code>.
 21.1075 -     * Unicode escape sequences are not translated.
 21.1076 -     *
 21.1077 -     * @param beginIndex the beginning index, inclusive.
 21.1078 -     * @param endIndex the ending index, exclusive.
 21.1079 -     * @throws IndexOutOfBounds if either offset is outside of the
 21.1080 -     *         array bounds
 21.1081 -     */
 21.1082 -    public char[] getRawCharacters(int beginIndex, int endIndex) {
 21.1083 -        int length = endIndex - beginIndex;
 21.1084 -        char[] chars = new char[length];
 21.1085 -        System.arraycopy(buf, beginIndex, chars, 0, length);
 21.1086 -        return chars;
 21.1087 -    }
 21.1088 -
 21.1089 -    public enum CommentStyle {
 21.1090 -        LINE,
 21.1091 -        BLOCK,
 21.1092 -        JAVADOC,
 21.1093 -    }
 21.1094 -
 21.1095 -    /**
 21.1096 -     * Called when a complete comment has been scanned. pos and endPos
 21.1097 -     * will mark the comment boundary.
 21.1098 -     */
 21.1099 -    protected void processComment(CommentStyle style) {
 21.1100 -        if (scannerDebug)
 21.1101 -            System.out.println("processComment(" + pos
 21.1102 -                               + "," + endPos + "," + style + ")=|"
 21.1103 -                               + new String(getRawCharacters(pos, endPos))
 21.1104 -                               + "|");
 21.1105 -    }
 21.1106 -
 21.1107 -    /**
 21.1108 -     * Called when a complete whitespace run has been scanned. pos and endPos
 21.1109 -     * will mark the whitespace boundary.
 21.1110 -     */
 21.1111 -    protected void processWhiteSpace() {
 21.1112 -        if (scannerDebug)
 21.1113 -            System.out.println("processWhitespace(" + pos
 21.1114 -                               + "," + endPos + ")=|" +
 21.1115 -                               new String(getRawCharacters(pos, endPos))
 21.1116 -                               + "|");
 21.1117 -    }
 21.1118 -
 21.1119 -    /**
 21.1120 -     * Called when a line terminator has been processed.
 21.1121 -     */
 21.1122 -    protected void processLineTerminator() {
 21.1123 -        if (scannerDebug)
 21.1124 -            System.out.println("processTerminator(" + pos
 21.1125 -                               + "," + endPos + ")=|" +
 21.1126 -                               new String(getRawCharacters(pos, endPos))
 21.1127 -                               + "|");
 21.1128 -    }
 21.1129 -
 21.1130 -    /** Build a map for translating between line numbers and
 21.1131 -     * positions in the input.
 21.1132 -     *
 21.1133 -     * @return a LineMap */
 21.1134 -    public Position.LineMap getLineMap() {
 21.1135 -        return Position.makeLineMap(buf, buflen, false);
 21.1136 -    }
 21.1137 -
 21.1138  }
    22.1 --- a/src/share/classes/com/sun/tools/javac/parser/ScannerFactory.java	Thu Oct 27 13:54:50 2011 -0700
    22.2 +++ b/src/share/classes/com/sun/tools/javac/parser/ScannerFactory.java	Fri Oct 28 17:49:36 2011 -0700
    22.3 @@ -57,7 +57,7 @@
    22.4      final Log log;
    22.5      final Names names;
    22.6      final Source source;
    22.7 -    final Keywords keywords;
    22.8 +    final Tokens tokens;
    22.9  
   22.10      /** Create a new scanner factory. */
   22.11      protected ScannerFactory(Context context) {
   22.12 @@ -65,14 +65,14 @@
   22.13          this.log = Log.instance(context);
   22.14          this.names = Names.instance(context);
   22.15          this.source = Source.instance(context);
   22.16 -        this.keywords = Keywords.instance(context);
   22.17 +        this.tokens = Tokens.instance(context);
   22.18      }
   22.19  
   22.20      public Scanner newScanner(CharSequence input, boolean keepDocComments) {
   22.21          if (input instanceof CharBuffer) {
   22.22              CharBuffer buf = (CharBuffer) input;
   22.23              if (keepDocComments)
   22.24 -                return new DocCommentScanner(this, buf);
   22.25 +                return new Scanner(this, new JavadocTokenizer(this, buf));
   22.26              else
   22.27                  return new Scanner(this, buf);
   22.28          } else {
   22.29 @@ -83,7 +83,7 @@
   22.30  
   22.31      public Scanner newScanner(char[] input, int inputLength, boolean keepDocComments) {
   22.32          if (keepDocComments)
   22.33 -            return new DocCommentScanner(this, input, inputLength);
   22.34 +            return new Scanner(this, new JavadocTokenizer(this, input, inputLength));
   22.35          else
   22.36              return new Scanner(this, input, inputLength);
   22.37      }
    23.1 --- a/src/share/classes/com/sun/tools/javac/parser/Token.java	Thu Oct 27 13:54:50 2011 -0700
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,198 +0,0 @@
    23.4 -/*
    23.5 - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
    23.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    23.7 - *
    23.8 - * This code is free software; you can redistribute it and/or modify it
    23.9 - * under the terms of the GNU General Public License version 2 only, as
   23.10 - * published by the Free Software Foundation.  Oracle designates this
   23.11 - * particular file as subject to the "Classpath" exception as provided
   23.12 - * by Oracle in the LICENSE file that accompanied this code.
   23.13 - *
   23.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
   23.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   23.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   23.17 - * version 2 for more details (a copy is included in the LICENSE file that
   23.18 - * accompanied this code).
   23.19 - *
   23.20 - * You should have received a copy of the GNU General Public License version
   23.21 - * 2 along with this work; if not, write to the Free Software Foundation,
   23.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   23.23 - *
   23.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   23.25 - * or visit www.oracle.com if you need additional information or have any
   23.26 - * questions.
   23.27 - */
   23.28 -
   23.29 -package com.sun.tools.javac.parser;
   23.30 -
   23.31 -import java.util.Locale;
   23.32 -
   23.33 -import com.sun.tools.javac.api.Formattable;
   23.34 -import com.sun.tools.javac.api.Messages;
   23.35 -
   23.36 -/** An interface that defines codes for Java source tokens
   23.37 - *  returned from lexical analysis.
   23.38 - *
   23.39 - *  <p><b>This is NOT part of any supported API.
   23.40 - *  If you write code that depends on this, you do so at your own risk.
   23.41 - *  This code and its internal interfaces are subject to change or
   23.42 - *  deletion without notice.</b>
   23.43 - */
   23.44 -public enum Token implements Formattable {
   23.45 -    EOF,
   23.46 -    ERROR,
   23.47 -    IDENTIFIER,
   23.48 -    ABSTRACT("abstract"),
   23.49 -    ASSERT("assert"),
   23.50 -    BOOLEAN("boolean"),
   23.51 -    BREAK("break"),
   23.52 -    BYTE("byte"),
   23.53 -    CASE("case"),
   23.54 -    CATCH("catch"),
   23.55 -    CHAR("char"),
   23.56 -    CLASS("class"),
   23.57 -    CONST("const"),
   23.58 -    CONTINUE("continue"),
   23.59 -    DEFAULT("default"),
   23.60 -    DO("do"),
   23.61 -    DOUBLE("double"),
   23.62 -    ELSE("else"),
   23.63 -    ENUM("enum"),
   23.64 -    EXTENDS("extends"),
   23.65 -    FINAL("final"),
   23.66 -    FINALLY("finally"),
   23.67 -    FLOAT("float"),
   23.68 -    FOR("for"),
   23.69 -    GOTO("goto"),
   23.70 -    IF("if"),
   23.71 -    IMPLEMENTS("implements"),
   23.72 -    IMPORT("import"),
   23.73 -    INSTANCEOF("instanceof"),
   23.74 -    INT("int"),
   23.75 -    INTERFACE("interface"),
   23.76 -    LONG("long"),
   23.77 -    NATIVE("native"),
   23.78 -    NEW("new"),
   23.79 -    PACKAGE("package"),
   23.80 -    PRIVATE("private"),
   23.81 -    PROTECTED("protected"),
   23.82 -    PUBLIC("public"),
   23.83 -    RETURN("return"),
   23.84 -    SHORT("short"),
   23.85 -    STATIC("static"),
   23.86 -    STRICTFP("strictfp"),
   23.87 -    SUPER("super"),
   23.88 -    SWITCH("switch"),
   23.89 -    SYNCHRONIZED("synchronized"),
   23.90 -    THIS("this"),
   23.91 -    THROW("throw"),
   23.92 -    THROWS("throws"),
   23.93 -    TRANSIENT("transient"),
   23.94 -    TRY("try"),
   23.95 -    VOID("void"),
   23.96 -    VOLATILE("volatile"),
   23.97 -    WHILE("while"),
   23.98 -    INTLITERAL,
   23.99 -    LONGLITERAL,
  23.100 -    FLOATLITERAL,
  23.101 -    DOUBLELITERAL,
  23.102 -    CHARLITERAL,
  23.103 -    STRINGLITERAL,
  23.104 -    TRUE("true"),
  23.105 -    FALSE("false"),
  23.106 -    NULL("null"),
  23.107 -    LPAREN("("),
  23.108 -    RPAREN(")"),
  23.109 -    LBRACE("{"),
  23.110 -    RBRACE("}"),
  23.111 -    LBRACKET("["),
  23.112 -    RBRACKET("]"),
  23.113 -    SEMI(";"),
  23.114 -    COMMA(","),
  23.115 -    DOT("."),
  23.116 -    ELLIPSIS("..."),
  23.117 -    EQ("="),
  23.118 -    GT(">"),
  23.119 -    LT("<"),
  23.120 -    BANG("!"),
  23.121 -    TILDE("~"),
  23.122 -    QUES("?"),
  23.123 -    COLON(":"),
  23.124 -    EQEQ("=="),
  23.125 -    LTEQ("<="),
  23.126 -    GTEQ(">="),
  23.127 -    BANGEQ("!="),
  23.128 -    AMPAMP("&&"),
  23.129 -    BARBAR("||"),
  23.130 -    PLUSPLUS("++"),
  23.131 -    SUBSUB("--"),
  23.132 -    PLUS("+"),
  23.133 -    SUB("-"),
  23.134 -    STAR("*"),
  23.135 -    SLASH("/"),
  23.136 -    AMP("&"),
  23.137 -    BAR("|"),
  23.138 -    CARET("^"),
  23.139 -    PERCENT("%"),
  23.140 -    LTLT("<<"),
  23.141 -    GTGT(">>"),
  23.142 -    GTGTGT(">>>"),
  23.143 -    PLUSEQ("+="),
  23.144 -    SUBEQ("-="),
  23.145 -    STAREQ("*="),
  23.146 -    SLASHEQ("/="),
  23.147 -    AMPEQ("&="),
  23.148 -    BAREQ("|="),
  23.149 -    CARETEQ("^="),
  23.150 -    PERCENTEQ("%="),
  23.151 -    LTLTEQ("<<="),
  23.152 -    GTGTEQ(">>="),
  23.153 -    GTGTGTEQ(">>>="),
  23.154 -    MONKEYS_AT("@"),
  23.155 -    CUSTOM;
  23.156 -
  23.157 -    Token() {
  23.158 -        this(null);
  23.159 -    }
  23.160 -    Token(String name) {
  23.161 -        this.name = name;
  23.162 -    }
  23.163 -
  23.164 -    public final String name;
  23.165 -
  23.166 -    public String toString() {
  23.167 -        switch (this) {
  23.168 -        case IDENTIFIER:
  23.169 -            return "token.identifier";
  23.170 -        case CHARLITERAL:
  23.171 -            return "token.character";
  23.172 -        case STRINGLITERAL:
  23.173 -            return "token.string";
  23.174 -        case INTLITERAL:
  23.175 -            return "token.integer";
  23.176 -        case LONGLITERAL:
  23.177 -            return "token.long-integer";
  23.178 -        case FLOATLITERAL:
  23.179 -            return "token.float";
  23.180 -        case DOUBLELITERAL:
  23.181 -            return "token.double";
  23.182 -        case ERROR:
  23.183 -            return "token.bad-symbol";
  23.184 -        case EOF:
  23.185 -            return "token.end-of-input";
  23.186 -        case DOT: case COMMA: case SEMI: case LPAREN: case RPAREN:
  23.187 -        case LBRACKET: case RBRACKET: case LBRACE: case RBRACE:
  23.188 -            return "'" + name + "'";
  23.189 -        default:
  23.190 -            return name;
  23.191 -        }
  23.192 -    }
  23.193 -
  23.194 -    public String getKind() {
  23.195 -        return "Token";
  23.196 -    }
  23.197 -
  23.198 -    public String toString(Locale locale, Messages messages) {
  23.199 -        return name != null ? toString() : messages.getLocalizedString(locale, "compiler.misc." + toString());
  23.200 -    }
  23.201 -}
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/src/share/classes/com/sun/tools/javac/parser/Tokens.java	Fri Oct 28 17:49:36 2011 -0700
    24.3 @@ -0,0 +1,423 @@
    24.4 +/*
    24.5 + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
    24.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    24.7 + *
    24.8 + * This code is free software; you can redistribute it and/or modify it
    24.9 + * under the terms of the GNU General Public License version 2 only, as
   24.10 + * published by the Free Software Foundation.  Oracle designates this
   24.11 + * particular file as subject to the "Classpath" exception as provided
   24.12 + * by Oracle in the LICENSE file that accompanied this code.
   24.13 + *
   24.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   24.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   24.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   24.17 + * version 2 for more details (a copy is included in the LICENSE file that
   24.18 + * accompanied this code).
   24.19 + *
   24.20 + * You should have received a copy of the GNU General Public License version
   24.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   24.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   24.23 + *
   24.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   24.25 + * or visit www.oracle.com if you need additional information or have any
   24.26 + * questions.
   24.27 + */
   24.28 +
   24.29 +package com.sun.tools.javac.parser;
   24.30 +
   24.31 +import java.util.Locale;
   24.32 +
   24.33 +import com.sun.tools.javac.api.Formattable;
   24.34 +import com.sun.tools.javac.api.Messages;
   24.35 +import com.sun.tools.javac.parser.Tokens.Token.Tag;
   24.36 +import com.sun.tools.javac.util.Name;
   24.37 +import com.sun.tools.javac.util.Context;
   24.38 +import com.sun.tools.javac.util.Names;
   24.39 +
   24.40 +/** A class that defines codes/utilities for Java source tokens
   24.41 + *  returned from lexical analysis.
   24.42 + *
   24.43 + *  <p><b>This is NOT part of any supported API.
   24.44 + *  If you write code that depends on this, you do so at your own risk.
   24.45 + *  This code and its internal interfaces are subject to change or
   24.46 + *  deletion without notice.</b>
   24.47 + */
   24.48 +public class Tokens {
   24.49 +
   24.50 +    private final Names names;
   24.51 +
   24.52 +    /**
   24.53 +     * Keyword array. Maps name indices to Token.
   24.54 +     */
   24.55 +    private final TokenKind[] key;
   24.56 +
   24.57 +    /**  The number of the last entered keyword.
   24.58 +     */
   24.59 +    private int maxKey = 0;
   24.60 +
   24.61 +    /** The names of all tokens.
   24.62 +     */
   24.63 +    private Name[] tokenName = new Name[TokenKind.values().length];
   24.64 +
   24.65 +    public static final Context.Key<Tokens> tokensKey =
   24.66 +        new Context.Key<Tokens>();
   24.67 +
   24.68 +    public static Tokens instance(Context context) {
   24.69 +        Tokens instance = context.get(tokensKey);
   24.70 +        if (instance == null)
   24.71 +            instance = new Tokens(context);
   24.72 +        return instance;
   24.73 +    }
   24.74 +
   24.75 +    protected Tokens(Context context) {
   24.76 +        context.put(tokensKey, this);
   24.77 +        names = Names.instance(context);
   24.78 +
   24.79 +        for (TokenKind t : TokenKind.values()) {
   24.80 +            if (t.name != null)
   24.81 +                enterKeyword(t.name, t);
   24.82 +            else
   24.83 +                tokenName[t.ordinal()] = null;
   24.84 +        }
   24.85 +
   24.86 +        key = new TokenKind[maxKey+1];
   24.87 +        for (int i = 0; i <= maxKey; i++) key[i] = TokenKind.IDENTIFIER;
   24.88 +        for (TokenKind t : TokenKind.values()) {
   24.89 +            if (t.name != null)
   24.90 +            key[tokenName[t.ordinal()].getIndex()] = t;
   24.91 +        }
   24.92 +    }
   24.93 +
   24.94 +    private void enterKeyword(String s, TokenKind token) {
   24.95 +        Name n = names.fromString(s);
   24.96 +        tokenName[token.ordinal()] = n;
   24.97 +        if (n.getIndex() > maxKey) maxKey = n.getIndex();
   24.98 +    }
   24.99 +
  24.100 +    /**
  24.101 +     * Create a new token given a name; if the name corresponds to a token name,
  24.102 +     * a new token of the corresponding kind is returned; otherwise, an
  24.103 +     * identifier token is returned.
  24.104 +     */
  24.105 +    TokenKind lookupKind(Name name) {
  24.106 +        return (name.getIndex() > maxKey) ? TokenKind.IDENTIFIER : key[name.getIndex()];
  24.107 +    }
  24.108 +
  24.109 +    TokenKind lookupKind(String name) {
  24.110 +        return lookupKind(names.fromString(name));
  24.111 +    }
  24.112 +
  24.113 +    /**
  24.114 +     * This enum defines all tokens used by the javac scanner. A token is
  24.115 +     * optionally associated with a name.
  24.116 +     */
  24.117 +    public enum TokenKind implements Formattable {
  24.118 +        EOF(),
  24.119 +        ERROR(),
  24.120 +        IDENTIFIER(Tag.NAMED),
  24.121 +        ABSTRACT("abstract"),
  24.122 +        ASSERT("assert", Tag.NAMED),
  24.123 +        BOOLEAN("boolean", Tag.NAMED),
  24.124 +        BREAK("break"),
  24.125 +        BYTE("byte", Tag.NAMED),
  24.126 +        CASE("case"),
  24.127 +        CATCH("catch"),
  24.128 +        CHAR("char", Tag.NAMED),
  24.129 +        CLASS("class"),
  24.130 +        CONST("const"),
  24.131 +        CONTINUE("continue"),
  24.132 +        DEFAULT("default"),
  24.133 +        DO("do"),
  24.134 +        DOUBLE("double", Tag.NAMED),
  24.135 +        ELSE("else"),
  24.136 +        ENUM("enum", Tag.NAMED),
  24.137 +        EXTENDS("extends"),
  24.138 +        FINAL("final"),
  24.139 +        FINALLY("finally"),
  24.140 +        FLOAT("float", Tag.NAMED),
  24.141 +        FOR("for"),
  24.142 +        GOTO("goto"),
  24.143 +        IF("if"),
  24.144 +        IMPLEMENTS("implements"),
  24.145 +        IMPORT("import"),
  24.146 +        INSTANCEOF("instanceof"),
  24.147 +        INT("int", Tag.NAMED),
  24.148 +        INTERFACE("interface"),
  24.149 +        LONG("long", Tag.NAMED),
  24.150 +        NATIVE("native"),
  24.151 +        NEW("new"),
  24.152 +        PACKAGE("package"),
  24.153 +        PRIVATE("private"),
  24.154 +        PROTECTED("protected"),
  24.155 +        PUBLIC("public"),
  24.156 +        RETURN("return"),
  24.157 +        SHORT("short", Tag.NAMED),
  24.158 +        STATIC("static"),
  24.159 +        STRICTFP("strictfp"),
  24.160 +        SUPER("super", Tag.NAMED),
  24.161 +        SWITCH("switch"),
  24.162 +        SYNCHRONIZED("synchronized"),
  24.163 +        THIS("this", Tag.NAMED),
  24.164 +        THROW("throw"),
  24.165 +        THROWS("throws"),
  24.166 +        TRANSIENT("transient"),
  24.167 +        TRY("try"),
  24.168 +        VOID("void", Tag.NAMED),
  24.169 +        VOLATILE("volatile"),
  24.170 +        WHILE("while"),
  24.171 +        INTLITERAL(Tag.NUMERIC),
  24.172 +        LONGLITERAL(Tag.NUMERIC),
  24.173 +        FLOATLITERAL(Tag.NUMERIC),
  24.174 +        DOUBLELITERAL(Tag.NUMERIC),
  24.175 +        CHARLITERAL(Tag.NUMERIC),
  24.176 +        STRINGLITERAL(Tag.STRING),
  24.177 +        TRUE("true", Tag.NAMED),
  24.178 +        FALSE("false", Tag.NAMED),
  24.179 +        NULL("null", Tag.NAMED),
  24.180 +        LPAREN("("),
  24.181 +        RPAREN(")"),
  24.182 +        LBRACE("{"),
  24.183 +        RBRACE("}"),
  24.184 +        LBRACKET("["),
  24.185 +        RBRACKET("]"),
  24.186 +        SEMI(";"),
  24.187 +        COMMA(","),
  24.188 +        DOT("."),
  24.189 +        ELLIPSIS("..."),
  24.190 +        EQ("="),
  24.191 +        GT(">"),
  24.192 +        LT("<"),
  24.193 +        BANG("!"),
  24.194 +        TILDE("~"),
  24.195 +        QUES("?"),
  24.196 +        COLON(":"),
  24.197 +        EQEQ("=="),
  24.198 +        LTEQ("<="),
  24.199 +        GTEQ(">="),
  24.200 +        BANGEQ("!="),
  24.201 +        AMPAMP("&&"),
  24.202 +        BARBAR("||"),
  24.203 +        PLUSPLUS("++"),
  24.204 +        SUBSUB("--"),
  24.205 +        PLUS("+"),
  24.206 +        SUB("-"),
  24.207 +        STAR("*"),
  24.208 +        SLASH("/"),
  24.209 +        AMP("&"),
  24.210 +        BAR("|"),
  24.211 +        CARET("^"),
  24.212 +        PERCENT("%"),
  24.213 +        LTLT("<<"),
  24.214 +        GTGT(">>"),
  24.215 +        GTGTGT(">>>"),
  24.216 +        PLUSEQ("+="),
  24.217 +        SUBEQ("-="),
  24.218 +        STAREQ("*="),
  24.219 +        SLASHEQ("/="),
  24.220 +        AMPEQ("&="),
  24.221 +        BAREQ("|="),
  24.222 +        CARETEQ("^="),
  24.223 +        PERCENTEQ("%="),
  24.224 +        LTLTEQ("<<="),
  24.225 +        GTGTEQ(">>="),
  24.226 +        GTGTGTEQ(">>>="),
  24.227 +        MONKEYS_AT("@"),
  24.228 +        CUSTOM;
  24.229 +
  24.230 +        public final String name;
  24.231 +        public final Tag tag;
  24.232 +
  24.233 +        TokenKind() {
  24.234 +            this(null, Tag.DEFAULT);
  24.235 +        }
  24.236 +
  24.237 +        TokenKind(String name) {
  24.238 +            this(name, Tag.DEFAULT);
  24.239 +        }
  24.240 +
  24.241 +        TokenKind(Tag tag) {
  24.242 +            this(null, tag);
  24.243 +        }
  24.244 +
  24.245 +        TokenKind(String name, Tag tag) {
  24.246 +            this.name = name;
  24.247 +            this.tag = tag;
  24.248 +        }
  24.249 +
  24.250 +        public String toString() {
  24.251 +            switch (this) {
  24.252 +            case IDENTIFIER:
  24.253 +                return "token.identifier";
  24.254 +            case CHARLITERAL:
  24.255 +                return "token.character";
  24.256 +            case STRINGLITERAL:
  24.257 +                return "token.string";
  24.258 +            case INTLITERAL:
  24.259 +                return "token.integer";
  24.260 +            case LONGLITERAL:
  24.261 +                return "token.long-integer";
  24.262 +            case FLOATLITERAL:
  24.263 +                return "token.float";
  24.264 +            case DOUBLELITERAL:
  24.265 +                return "token.double";
  24.266 +            case ERROR:
  24.267 +                return "token.bad-symbol";
  24.268 +            case EOF:
  24.269 +                return "token.end-of-input";
  24.270 +            case DOT: case COMMA: case SEMI: case LPAREN: case RPAREN:
  24.271 +            case LBRACKET: case RBRACKET: case LBRACE: case RBRACE:
  24.272 +                return "'" + name + "'";
  24.273 +            default:
  24.274 +                return name;
  24.275 +            }
  24.276 +        }
  24.277 +
  24.278 +        public String getKind() {
  24.279 +            return "Token";
  24.280 +        }
  24.281 +
  24.282 +        public String toString(Locale locale, Messages messages) {
  24.283 +            return name != null ? toString() : messages.getLocalizedString(locale, "compiler.misc." + toString());
  24.284 +        }
  24.285 +    }
  24.286 +
  24.287 +    /**
  24.288 +     * This is the class representing a javac token. Each token has several fields
  24.289 +     * that are set by the javac lexer (i.e. start/end position, string value, etc).
  24.290 +     */
  24.291 +    public static class Token {
  24.292 +
  24.293 +        /** tags constants **/
  24.294 +        enum Tag {
  24.295 +            DEFAULT,
  24.296 +            NAMED,
  24.297 +            STRING,
  24.298 +            NUMERIC;
  24.299 +        }
  24.300 +
  24.301 +        /** The token kind */
  24.302 +        public final TokenKind kind;
  24.303 +
  24.304 +        /** The start position of this token */
  24.305 +        public final int pos;
  24.306 +
  24.307 +        /** The end position of this token */
  24.308 +        public final int endPos;
  24.309 +
  24.310 +        /** Is this token preceeded by a deprecated comment? */
  24.311 +        public final boolean deprecatedFlag;
  24.312 +
  24.313 +        /** Is this token preceeded by a deprecated comment? */
  24.314 +        public String docComment;
  24.315 +
  24.316 +        Token(TokenKind kind, int pos, int endPos,
  24.317 +                boolean deprecatedFlag) {
  24.318 +            this.kind = kind;
  24.319 +            this.pos = pos;
  24.320 +            this.endPos = endPos;
  24.321 +            this.deprecatedFlag = deprecatedFlag;
  24.322 +            checkKind();
  24.323 +        }
  24.324 +
  24.325 +        Token[] split(Tokens tokens) {
  24.326 +            if (kind.name.length() < 2 || kind.tag != Tag.DEFAULT) {
  24.327 +                throw new AssertionError("Cant split" + kind);
  24.328 +            }
  24.329 +
  24.330 +            TokenKind t1 = tokens.lookupKind(kind.name.substring(0, 1));
  24.331 +            TokenKind t2 = tokens.lookupKind(kind.name.substring(1));
  24.332 +
  24.333 +            if (t1 == null || t2 == null) {
  24.334 +                throw new AssertionError("Cant split - bad subtokens");
  24.335 +            }
  24.336 +            return new Token[] {
  24.337 +                new Token(t1, pos, pos + t1.name.length(), deprecatedFlag),
  24.338 +                new Token(t2, pos + t1.name.length(), endPos, false)
  24.339 +            };
  24.340 +        }
  24.341 +
  24.342 +        protected void checkKind() {
  24.343 +            if (kind.tag != Tag.DEFAULT) {
  24.344 +                throw new AssertionError("Bad token kind - expected " + Tag.STRING);
  24.345 +            }
  24.346 +        }
  24.347 +
  24.348 +        public Name name() {
  24.349 +            throw new UnsupportedOperationException();
  24.350 +        }
  24.351 +
  24.352 +        public String stringVal() {
  24.353 +            throw new UnsupportedOperationException();
  24.354 +        }
  24.355 +
  24.356 +        public int radix() {
  24.357 +            throw new UnsupportedOperationException();
  24.358 +        }
  24.359 +    }
  24.360 +
  24.361 +    final static class NamedToken extends Token {
  24.362 +        /** The name of this token */
  24.363 +        public final Name name;
  24.364 +
  24.365 +        public NamedToken(TokenKind kind, int pos, int endPos, Name name, boolean deprecatedFlag) {
  24.366 +            super(kind, pos, endPos, deprecatedFlag);
  24.367 +            this.name = name;
  24.368 +        }
  24.369 +
  24.370 +        protected void checkKind() {
  24.371 +            if (kind.tag != Tag.NAMED) {
  24.372 +                throw new AssertionError("Bad token kind - expected " + Tag.NAMED);
  24.373 +            }
  24.374 +        }
  24.375 +
  24.376 +        @Override
  24.377 +        public Name name() {
  24.378 +            return name;
  24.379 +        }
  24.380 +    }
  24.381 +
  24.382 +    static class StringToken extends Token {
  24.383 +        /** The string value of this token */
  24.384 +        public final String stringVal;
  24.385 +
  24.386 +        public StringToken(TokenKind kind, int pos, int endPos, String stringVal, boolean deprecatedFlag) {
  24.387 +            super(kind, pos, endPos, deprecatedFlag);
  24.388 +            this.stringVal = stringVal;
  24.389 +        }
  24.390 +
  24.391 +        protected void checkKind() {
  24.392 +            if (kind.tag != Tag.STRING) {
  24.393 +                throw new AssertionError("Bad token kind - expected " + Tag.STRING);
  24.394 +            }
  24.395 +        }
  24.396 +
  24.397 +        @Override
  24.398 +        public String stringVal() {
  24.399 +            return stringVal;
  24.400 +        }
  24.401 +    }
  24.402 +
  24.403 +    final static class NumericToken extends StringToken {
  24.404 +        /** The 'radix' value of this token */
  24.405 +        public final int radix;
  24.406 +
  24.407 +        public NumericToken(TokenKind kind, int pos, int endPos, String stringVal, int radix, boolean deprecatedFlag) {
  24.408 +            super(kind, pos, endPos, stringVal, deprecatedFlag);
  24.409 +            this.radix = radix;
  24.410 +        }
  24.411 +
  24.412 +        protected void checkKind() {
  24.413 +            if (kind.tag != Tag.NUMERIC) {
  24.414 +                throw new AssertionError("Bad token kind - expected " + Tag.NUMERIC);
  24.415 +            }
  24.416 +        }
  24.417 +
  24.418 +        @Override
  24.419 +        public int radix() {
  24.420 +            return radix;
  24.421 +        }
  24.422 +    }
  24.423 +
  24.424 +    public static final Token DUMMY =
  24.425 +                new Token(TokenKind.ERROR, 0, 0, false);
  24.426 +}
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/src/share/classes/com/sun/tools/javac/parser/UnicodeReader.java	Fri Oct 28 17:49:36 2011 -0700
    25.3 @@ -0,0 +1,227 @@
    25.4 +/*
    25.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    25.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    25.7 + *
    25.8 + * This code is free software; you can redistribute it and/or modify it
    25.9 + * under the terms of the GNU General Public License version 2 only, as
   25.10 + * published by the Free Software Foundation.  Oracle designates this
   25.11 + * particular file as subject to the "Classpath" exception as provided
   25.12 + * by Oracle in the LICENSE file that accompanied this code.
   25.13 + *
   25.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   25.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   25.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   25.17 + * version 2 for more details (a copy is included in the LICENSE file that
   25.18 + * accompanied this code).
   25.19 + *
   25.20 + * You should have received a copy of the GNU General Public License version
   25.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   25.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   25.23 + *
   25.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   25.25 + * or visit www.oracle.com if you need additional information or have any
   25.26 + * questions.
   25.27 + */
   25.28 +
   25.29 +package com.sun.tools.javac.parser;
   25.30 +
   25.31 +import com.sun.tools.javac.file.JavacFileManager;
   25.32 +import java.nio.CharBuffer;
   25.33 +import com.sun.tools.javac.util.Log;
   25.34 +import static com.sun.tools.javac.util.LayoutCharacters.*;
   25.35 +
   25.36 +/** The char reader used by the javac lexer/tokenizer. Returns the sequence of
   25.37 + * characters contained in the input stream, handling unicode escape accordingly.
   25.38 + * Additionally, it provide features for saving chars into a buffer and to retrieve
   25.39 + * them at a later stage.
   25.40 + *
   25.41 + *  <p><b>This is NOT part of any supported API.
   25.42 + *  If you write code that depends on this, you do so at your own risk.
   25.43 + *  This code and its internal interfaces are subject to change or
   25.44 + *  deletion without notice.</b>
   25.45 + */
   25.46 +public class UnicodeReader {
   25.47 +
   25.48 +    /** The input buffer, index of next character to be read,
   25.49 +     *  index of one past last character in buffer.
   25.50 +     */
   25.51 +    protected char[] buf;
   25.52 +    protected int bp;
   25.53 +    protected final int buflen;
   25.54 +
   25.55 +    /** The current character.
   25.56 +     */
   25.57 +    protected char ch;
   25.58 +
   25.59 +    /** The buffer index of the last converted unicode character
   25.60 +     */
   25.61 +    protected int unicodeConversionBp = -1;
   25.62 +
   25.63 +    protected Log log;
   25.64 +
   25.65 +    /**
   25.66 +     * Create a scanner from the input array.  This method might
   25.67 +     * modify the array.  To avoid copying the input array, ensure
   25.68 +     * that {@code inputLength < input.length} or
   25.69 +     * {@code input[input.length -1]} is a white space character.
   25.70 +     *
   25.71 +     * @param fac the factory which created this Scanner
   25.72 +     * @param input the input, might be modified
   25.73 +     * @param inputLength the size of the input.
   25.74 +     * Must be positive and less than or equal to input.length.
   25.75 +     */
   25.76 +    protected UnicodeReader(ScannerFactory sf, CharBuffer buffer) {
   25.77 +        this(sf, JavacFileManager.toArray(buffer), buffer.limit());
   25.78 +    }
   25.79 +
   25.80 +    protected UnicodeReader(ScannerFactory sf, char[] input, int inputLength) {
   25.81 +        log = sf.log;
   25.82 +        if (inputLength == input.length) {
   25.83 +            if (input.length > 0 && Character.isWhitespace(input[input.length - 1])) {
   25.84 +                inputLength--;
   25.85 +            } else {
   25.86 +                char[] newInput = new char[inputLength + 1];
   25.87 +                System.arraycopy(input, 0, newInput, 0, input.length);
   25.88 +                input = newInput;
   25.89 +            }
   25.90 +        }
   25.91 +        buf = input;
   25.92 +        buflen = inputLength;
   25.93 +        buf[buflen] = EOI;
   25.94 +        bp = -1;
   25.95 +        scanChar();
   25.96 +    }
   25.97 +
   25.98 +    /** Read next character.
   25.99 +     */
  25.100 +    protected void scanChar() {
  25.101 +        if (bp < buflen) {
  25.102 +            ch = buf[++bp];
  25.103 +            if (ch == '\\') {
  25.104 +                convertUnicode();
  25.105 +            }
  25.106 +        }
  25.107 +    }
  25.108 +
  25.109 +    /** Convert unicode escape; bp points to initial '\' character
  25.110 +     *  (Spec 3.3).
  25.111 +     */
  25.112 +    protected void convertUnicode() {
  25.113 +        if (ch == '\\' && unicodeConversionBp != bp) {
  25.114 +            bp++; ch = buf[bp];
  25.115 +            if (ch == 'u') {
  25.116 +                do {
  25.117 +                    bp++; ch = buf[bp];
  25.118 +                } while (ch == 'u');
  25.119 +                int limit = bp + 3;
  25.120 +                if (limit < buflen) {
  25.121 +                    int d = digit(bp, 16);
  25.122 +                    int code = d;
  25.123 +                    while (bp < limit && d >= 0) {
  25.124 +                        bp++; ch = buf[bp];
  25.125 +                        d = digit(bp, 16);
  25.126 +                        code = (code << 4) + d;
  25.127 +                    }
  25.128 +                    if (d >= 0) {
  25.129 +                        ch = (char)code;
  25.130 +                        unicodeConversionBp = bp;
  25.131 +                        return;
  25.132 +                    }
  25.133 +                }
  25.134 +                log.error(bp, "illegal.unicode.esc");
  25.135 +            } else {
  25.136 +                bp--;
  25.137 +                ch = '\\';
  25.138 +            }
  25.139 +        }
  25.140 +    }
  25.141 +
  25.142 +    /** Are surrogates supported?
  25.143 +     */
  25.144 +    final static boolean surrogatesSupported = surrogatesSupported();
  25.145 +    private static boolean surrogatesSupported() {
  25.146 +        try {
  25.147 +            Character.isHighSurrogate('a');
  25.148 +            return true;
  25.149 +        } catch (NoSuchMethodError ex) {
  25.150 +            return false;
  25.151 +        }
  25.152 +    }
  25.153 +
  25.154 +    /** Scan surrogate pairs.  If 'ch' is a high surrogate and
  25.155 +     *  the next character is a low surrogate, then put the low
  25.156 +     *  surrogate in 'ch', and return the high surrogate.
  25.157 +     *  otherwise, just return 0.
  25.158 +     */
  25.159 +    protected char scanSurrogates() {
  25.160 +        if (surrogatesSupported && Character.isHighSurrogate(ch)) {
  25.161 +            char high = ch;
  25.162 +
  25.163 +            scanChar();
  25.164 +
  25.165 +            if (Character.isLowSurrogate(ch)) {
  25.166 +                return high;
  25.167 +            }
  25.168 +
  25.169 +            ch = high;
  25.170 +        }
  25.171 +
  25.172 +        return 0;
  25.173 +    }
  25.174 +
  25.175 +    /** Convert an ASCII digit from its base (8, 10, or 16)
  25.176 +     *  to its value.
  25.177 +     */
  25.178 +    protected int digit(int pos, int base) {
  25.179 +        char c = ch;
  25.180 +        int result = Character.digit(c, base);
  25.181 +        if (result >= 0 && c > 0x7f) {
  25.182 +            log.error(pos + 1, "illegal.nonascii.digit");
  25.183 +            ch = "0123456789abcdef".charAt(result);
  25.184 +        }
  25.185 +        return result;
  25.186 +    }
  25.187 +
  25.188 +    protected boolean isUnicode() {
  25.189 +        return unicodeConversionBp == bp;
  25.190 +    }
  25.191 +
  25.192 +    protected void skipChar() {
  25.193 +        bp++;
  25.194 +    }
  25.195 +
  25.196 +    protected char peekChar() {
  25.197 +        return buf[bp + 1];
  25.198 +    }
  25.199 +
  25.200 +    /**
  25.201 +     * Returns a copy of the input buffer, up to its inputLength.
  25.202 +     * Unicode escape sequences are not translated.
  25.203 +     */
  25.204 +    public char[] getRawCharacters() {
  25.205 +        char[] chars = new char[buflen];
  25.206 +        System.arraycopy(buf, 0, chars, 0, buflen);
  25.207 +        return chars;
  25.208 +    }
  25.209 +
  25.210 +    /**
  25.211 +     * Returns a copy of a character array subset of the input buffer.
  25.212 +     * The returned array begins at the <code>beginIndex</code> and
  25.213 +     * extends to the character at index <code>endIndex - 1</code>.
  25.214 +     * Thus the length of the substring is <code>endIndex-beginIndex</code>.
  25.215 +     * This behavior is like
  25.216 +     * <code>String.substring(beginIndex, endIndex)</code>.
  25.217 +     * Unicode escape sequences are not translated.
  25.218 +     *
  25.219 +     * @param beginIndex the beginning index, inclusive.
  25.220 +     * @param endIndex the ending index, exclusive.
  25.221 +     * @throws IndexOutOfBounds if either offset is outside of the
  25.222 +     *         array bounds
  25.223 +     */
  25.224 +    public char[] getRawCharacters(int beginIndex, int endIndex) {
  25.225 +        int length = endIndex - beginIndex;
  25.226 +        char[] chars = new char[length];
  25.227 +        System.arraycopy(buf, beginIndex, chars, 0, length);
  25.228 +        return chars;
  25.229 +    }
  25.230 +}
    26.1 --- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Thu Oct 27 13:54:50 2011 -0700
    26.2 +++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Fri Oct 28 17:49:36 2011 -0700
    26.3 @@ -1072,9 +1072,9 @@
    26.4              Assert.checkNonNull(names);
    26.5              next.put(Names.namesKey, names);
    26.6  
    26.7 -            Keywords keywords = Keywords.instance(context);
    26.8 -            Assert.checkNonNull(keywords);
    26.9 -            next.put(Keywords.keywordsKey, keywords);
   26.10 +            Tokens tokens = Tokens.instance(context);
   26.11 +            Assert.checkNonNull(tokens);
   26.12 +            next.put(Tokens.tokensKey, tokens);
   26.13  
   26.14              JavaCompiler oldCompiler = JavaCompiler.instance(context);
   26.15              JavaCompiler nextCompiler = JavaCompiler.instance(next);
    27.1 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Oct 27 13:54:50 2011 -0700
    27.2 +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Oct 28 17:49:36 2011 -0700
    27.3 @@ -1944,6 +1944,55 @@
    27.4      (use -source 7 or higher to enable strings in switch)
    27.5  
    27.6  ########################################
    27.7 +# Diagnostics for verbose resolution
    27.8 +# used by Resolve (debug only)
    27.9 +########################################
   27.10 +
   27.11 +# 0: number, 1: symbol, 2: unused
   27.12 +compiler.misc.applicable.method.found=\
   27.13 +    #{0} applicable method found: {1}
   27.14 +
   27.15 +# 0: number, 1: symbol, 2: message segment
   27.16 +compiler.misc.applicable.method.found.1=\
   27.17 +    #{0} applicable method found: {1}\n\
   27.18 +    ({2})
   27.19 +
   27.20 +# 0: number, 1: symbol, 2: message segment
   27.21 +compiler.misc.not.applicable.method.found=\
   27.22 +    #{0} not applicable method found: {1}\n\
   27.23 +    ({2})
   27.24 +
   27.25 +# 0: type
   27.26 +compiler.misc.full.inst.sig=\
   27.27 +    fully instantiated to: {0}
   27.28 +
   27.29 +# 0: type
   27.30 +compiler.misc.partial.inst.sig=\
   27.31 +    partially instantiated to: {0}
   27.32 +
   27.33 +# 0: name, 1: symbol, 2: number, 3: MethodResolutionPhase, 4: list of type or message segment, 5: list of type or message segment
   27.34 +compiler.note.verbose.resolve.multi=\
   27.35 +    resolving method {0} in type {1} to candidate {2}\n\
   27.36 +    phase: {3}\n\
   27.37 +    with actuals: {4}\n\
   27.38 +    with type-args: {5}\n\
   27.39 +    candidates:
   27.40 +
   27.41 +# 0: name, 1: symbol, 2: unused, 3: MethodResolutionPhase, 4: list of type or message segment, 5: list of type or message segment
   27.42 +compiler.note.verbose.resolve.multi.1=\
   27.43 +    erroneous resolution for method {0} in type {1}\n\
   27.44 +    phase: {3}\n\
   27.45 +    with actuals: {4}\n\
   27.46 +    with type-args: {5}\n\
   27.47 +    candidates:
   27.48 +
   27.49 +# 0: symbol, 1: type, 2: type
   27.50 +compiler.note.deferred.method.inst=\
   27.51 +    Deferred instantiation of method {0}\n\
   27.52 +    instantiated signature: {1}\n\
   27.53 +    target-type: {2}
   27.54 +
   27.55 +########################################
   27.56  # Diagnostics for where clause implementation
   27.57  # used by the RichDiagnosticFormatter.
   27.58  ########################################
    28.1 --- a/src/share/classes/com/sun/tools/javac/util/BaseFileManager.java	Thu Oct 27 13:54:50 2011 -0700
    28.2 +++ b/src/share/classes/com/sun/tools/javac/util/BaseFileManager.java	Fri Oct 28 17:49:36 2011 -0700
    28.3 @@ -25,11 +25,6 @@
    28.4  
    28.5  package com.sun.tools.javac.util;
    28.6  
    28.7 -import com.sun.tools.javac.code.Source;
    28.8 -import com.sun.tools.javac.main.JavacOption;
    28.9 -import com.sun.tools.javac.main.OptionName;
   28.10 -import com.sun.tools.javac.main.RecognizedOptions;
   28.11 -import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
   28.12  import java.io.ByteArrayOutputStream;
   28.13  import java.io.Closeable;
   28.14  import java.io.IOException;
   28.15 @@ -54,6 +49,15 @@
   28.16  import javax.tools.JavaFileObject;
   28.17  import javax.tools.JavaFileObject.Kind;
   28.18  
   28.19 +import com.sun.tools.javac.code.Lint;
   28.20 +import com.sun.tools.javac.code.Source;
   28.21 +import com.sun.tools.javac.file.FSInfo;
   28.22 +import com.sun.tools.javac.file.Locations;
   28.23 +import com.sun.tools.javac.main.JavacOption;
   28.24 +import com.sun.tools.javac.main.OptionName;
   28.25 +import com.sun.tools.javac.main.RecognizedOptions;
   28.26 +import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
   28.27 +
   28.28  /**
   28.29   * Utility methods for building a filemanager.
   28.30   * There are no references here to file-system specific objects such as
   28.31 @@ -63,15 +67,21 @@
   28.32      protected BaseFileManager(Charset charset) {
   28.33          this.charset = charset;
   28.34          byteBufferCache = new ByteBufferCache();
   28.35 +        locations = createLocations();
   28.36      }
   28.37  
   28.38      /**
   28.39       * Set the context for JavacPathFileManager.
   28.40       */
   28.41 -    protected void setContext(Context context) {
   28.42 +    public void setContext(Context context) {
   28.43          log = Log.instance(context);
   28.44          options = Options.instance(context);
   28.45          classLoaderClass = options.get("procloader");
   28.46 +        locations.update(log, options, Lint.instance(context), FSInfo.instance(context));
   28.47 +    }
   28.48 +
   28.49 +    protected Locations createLocations() {
   28.50 +        return new Locations();
   28.51      }
   28.52  
   28.53      /**
   28.54 @@ -88,6 +98,8 @@
   28.55  
   28.56      protected String classLoaderClass;
   28.57  
   28.58 +    protected Locations locations;
   28.59 +
   28.60      protected Source getSource() {
   28.61          String sourceName = options.get(OptionName.SOURCE);
   28.62          Source source = null;
    29.1 --- a/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java	Thu Oct 27 13:54:50 2011 -0700
    29.2 +++ b/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java	Fri Oct 28 17:49:36 2011 -0700
    29.3 @@ -80,7 +80,7 @@
    29.4          cpString = appendPath(System.getProperty("env.class.path"), cpString);
    29.5          cpString = appendPath(System.getProperty("java.class.path"), cpString);
    29.6          cpString = appendPath(docletPath, cpString);
    29.7 -        URL[] urls = com.sun.tools.javac.file.Paths.pathToURLs(cpString);
    29.8 +        URL[] urls = com.sun.tools.javac.file.Locations.pathToURLs(cpString);
    29.9          if (docletParentClassLoader == null)
   29.10              appClassLoader = new URLClassLoader(urls, getDelegationClassLoader(docletClassName));
   29.11          else
    30.1 --- a/src/share/classes/com/sun/tools/javadoc/JavadocTool.java	Thu Oct 27 13:54:50 2011 -0700
    30.2 +++ b/src/share/classes/com/sun/tools/javadoc/JavadocTool.java	Fri Oct 28 17:49:36 2011 -0700
    30.3 @@ -39,7 +39,6 @@
    30.4  
    30.5  import com.sun.tools.javac.code.Symbol.CompletionFailure;
    30.6  import com.sun.tools.javac.comp.Annotate;
    30.7 -import com.sun.tools.javac.parser.DocCommentScanner;
    30.8  import com.sun.tools.javac.tree.JCTree;
    30.9  import com.sun.tools.javac.tree.JCTree.JCClassDecl;
   30.10  import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/test/tools/javac/7102515/T7102515.java	Fri Oct 28 17:49:36 2011 -0700
    31.3 @@ -0,0 +1,11 @@
    31.4 +/*
    31.5 + * @test /nodynamiccopyright/
    31.6 + * @bug 7102515
    31.7 + * @summary javac running very very long and not returning
    31.8 + * @compile/fail/ref=T7102515.out -XDrawDiagnostics T7102515.java
    31.9 + */
   31.10 +
   31.11 +class T7102515 {
   31.12 +    T7102515 badBinary = new T7102515() + new T7102515();
   31.13 +    Object badUnary = badBinary++;
   31.14 +}
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/test/tools/javac/7102515/T7102515.out	Fri Oct 28 17:49:36 2011 -0700
    32.3 @@ -0,0 +1,3 @@
    32.4 +T7102515.java:9:41: compiler.err.operator.cant.be.applied.1: +, T7102515, T7102515
    32.5 +T7102515.java:10:32: compiler.err.operator.cant.be.applied: ++, T7102515, null
    32.6 +2 errors
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/test/tools/javac/T7093325.java	Fri Oct 28 17:49:36 2011 -0700
    33.3 @@ -0,0 +1,262 @@
    33.4 +/*
    33.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    33.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    33.7 + *
    33.8 + * This code is free software; you can redistribute it and/or modify it
    33.9 + * under the terms of the GNU General Public License version 2 only, as
   33.10 + * published by the Free Software Foundation.
   33.11 + *
   33.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   33.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   33.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   33.15 + * version 2 for more details (a copy is included in the LICENSE file that
   33.16 + * accompanied this code).
   33.17 + *
   33.18 + * You should have received a copy of the GNU General Public License version
   33.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   33.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   33.21 + *
   33.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   33.23 + * or visit www.oracle.com if you need additional information or have any
   33.24 + * questions.
   33.25 + */
   33.26 +
   33.27 +/*
   33.28 + * @test
   33.29 + * @bug 7093325
   33.30 + * @summary Redundant entry in bytecode exception table
   33.31 + */
   33.32 +
   33.33 +import com.sun.source.util.JavacTask;
   33.34 +import com.sun.tools.classfile.Attribute;
   33.35 +import com.sun.tools.classfile.ClassFile;
   33.36 +import com.sun.tools.classfile.Code_attribute;
   33.37 +import com.sun.tools.classfile.ConstantPool.*;
   33.38 +import com.sun.tools.classfile.Method;
   33.39 +import com.sun.tools.javac.api.JavacTool;
   33.40 +
   33.41 +import java.io.File;
   33.42 +import java.net.URI;
   33.43 +import java.util.Arrays;
   33.44 +import javax.tools.JavaCompiler;
   33.45 +import javax.tools.JavaFileObject;
   33.46 +import javax.tools.SimpleJavaFileObject;
   33.47 +import javax.tools.StandardJavaFileManager;
   33.48 +import javax.tools.ToolProvider;
   33.49 +
   33.50 +
   33.51 +public class T7093325 {
   33.52 +
   33.53 +    /** global decls ***/
   33.54 +
   33.55 +    // Create a single file manager and reuse it for each compile to save time.
   33.56 +    static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
   33.57 +
   33.58 +    //statistics
   33.59 +    static int checkCount = 0;
   33.60 +
   33.61 +    enum StatementKind {
   33.62 +        THROW("throw new RuntimeException();", false, false),
   33.63 +        RETURN_NONEMPTY("System.out.println(); return;", true, false),
   33.64 +        RETURN_EMPTY("return;", true, true),
   33.65 +        APPLY("System.out.println();", true, false);
   33.66 +
   33.67 +        String stmt;
   33.68 +        boolean canInline;
   33.69 +        boolean empty;
   33.70 +
   33.71 +        private StatementKind(String stmt, boolean canInline, boolean empty) {
   33.72 +            this.stmt = stmt;
   33.73 +            this.canInline = canInline;
   33.74 +            this.empty = empty;
   33.75 +        }
   33.76 +    }
   33.77 +
   33.78 +    enum CatchArity {
   33.79 +        NONE(""),
   33.80 +        ONE("catch (A a) { #S1 }"),
   33.81 +        TWO("catch (B b) { #S2 }"),
   33.82 +        THREE("catch (C c) { #S3 }"),
   33.83 +        FOUR("catch (D d) { #S4 }");
   33.84 +
   33.85 +        String catchStr;
   33.86 +
   33.87 +        private CatchArity(String catchStr) {
   33.88 +            this.catchStr = catchStr;
   33.89 +        }
   33.90 +
   33.91 +        String catchers() {
   33.92 +            if (this.ordinal() == 0) {
   33.93 +                return catchStr;
   33.94 +            } else {
   33.95 +                return CatchArity.values()[this.ordinal() - 1].catchers() + catchStr;
   33.96 +            }
   33.97 +        }
   33.98 +    }
   33.99 +
  33.100 +    public static void main(String... args) throws Exception {
  33.101 +        for (CatchArity ca : CatchArity.values()) {
  33.102 +            for (StatementKind stmt0 : StatementKind.values()) {
  33.103 +                if (ca.ordinal() == 0) {
  33.104 +                    new T7093325(ca, stmt0).compileAndCheck();
  33.105 +                    continue;
  33.106 +                }
  33.107 +                for (StatementKind stmt1 : StatementKind.values()) {
  33.108 +                    if (ca.ordinal() == 1) {
  33.109 +                        new T7093325(ca, stmt0, stmt1).compileAndCheck();
  33.110 +                        continue;
  33.111 +                    }
  33.112 +                    for (StatementKind stmt2 : StatementKind.values()) {
  33.113 +                        if (ca.ordinal() == 2) {
  33.114 +                            new T7093325(ca, stmt0, stmt1, stmt2).compileAndCheck();
  33.115 +                            continue;
  33.116 +                        }
  33.117 +                        for (StatementKind stmt3 : StatementKind.values()) {
  33.118 +                            if (ca.ordinal() == 3) {
  33.119 +                                new T7093325(ca, stmt0, stmt1, stmt2, stmt3).compileAndCheck();
  33.120 +                                continue;
  33.121 +                            }
  33.122 +                            for (StatementKind stmt4 : StatementKind.values()) {
  33.123 +                                if (ca.ordinal() == 4) {
  33.124 +                                    new T7093325(ca, stmt0, stmt1, stmt2, stmt3, stmt4).compileAndCheck();
  33.125 +                                    continue;
  33.126 +                                }
  33.127 +                                for (StatementKind stmt5 : StatementKind.values()) {
  33.128 +                                    new T7093325(ca, stmt0, stmt1, stmt2, stmt3, stmt4, stmt5).compileAndCheck();
  33.129 +                                }
  33.130 +                            }
  33.131 +                        }
  33.132 +                    }
  33.133 +                }
  33.134 +            }
  33.135 +        }
  33.136 +
  33.137 +        System.out.println("Total checks made: " + checkCount);
  33.138 +    }
  33.139 +
  33.140 +    /** instance decls **/
  33.141 +
  33.142 +    CatchArity ca;
  33.143 +    StatementKind[] stmts;
  33.144 +
  33.145 +    public T7093325(CatchArity ca, StatementKind... stmts) {
  33.146 +        this.ca = ca;
  33.147 +        this.stmts = stmts;
  33.148 +    }
  33.149 +
  33.150 +    void compileAndCheck() throws Exception {
  33.151 +        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
  33.152 +        JavaSource source = new JavaSource();
  33.153 +        JavacTask ct = (JavacTask)tool.getTask(null, fm, null,
  33.154 +                null, null, Arrays.asList(source));
  33.155 +        ct.call();
  33.156 +        verifyBytecode(source);
  33.157 +    }
  33.158 +
  33.159 +    void verifyBytecode(JavaSource source) {
  33.160 +        checkCount++;
  33.161 +        boolean lastInlined = false;
  33.162 +        boolean hasCode = false;
  33.163 +        int gapsCount = 0;
  33.164 +        for (int i = 0; i < stmts.length ; i++) {
  33.165 +            lastInlined = stmts[i].canInline;
  33.166 +            hasCode = hasCode || !stmts[i].empty;
  33.167 +            if (lastInlined && hasCode) {
  33.168 +                hasCode = false;
  33.169 +                gapsCount++;
  33.170 +            }
  33.171 +        }
  33.172 +        if (!lastInlined) {
  33.173 +            gapsCount++;
  33.174 +        }
  33.175 +
  33.176 +        //System.out.printf("gaps %d \n %s \n", gapsCount, source.toString());
  33.177 +
  33.178 +        File compiledTest = new File("Test.class");
  33.179 +        try {
  33.180 +            ClassFile cf = ClassFile.read(compiledTest);
  33.181 +            if (cf == null) {
  33.182 +                throw new Error("Classfile not found: " + compiledTest.getName());
  33.183 +            }
  33.184 +
  33.185 +            Method test_method = null;
  33.186 +            for (Method m : cf.methods) {
  33.187 +                if (m.getName(cf.constant_pool).equals("test")) {
  33.188 +                    test_method = m;
  33.189 +                    break;
  33.190 +                }
  33.191 +            }
  33.192 +
  33.193 +            if (test_method == null) {
  33.194 +                throw new Error("Method test() not found in class Test");
  33.195 +            }
  33.196 +
  33.197 +            Code_attribute code = null;
  33.198 +            for (Attribute a : test_method.attributes) {
  33.199 +                if (a.getName(cf.constant_pool).equals(Attribute.Code)) {
  33.200 +                    code = (Code_attribute)a;
  33.201 +                    break;
  33.202 +                }
  33.203 +            }
  33.204 +
  33.205 +            if (code == null) {
  33.206 +                throw new Error("Code attribute not found in method test()");
  33.207 +            }
  33.208 +
  33.209 +            int actualGapsCount = 0;
  33.210 +            for (int i = 0; i < code.exception_table_langth ; i++) {
  33.211 +                int catchType = code.exception_table[i].catch_type;
  33.212 +                if (catchType == 0) { //any
  33.213 +                    actualGapsCount++;
  33.214 +                }
  33.215 +            }
  33.216 +
  33.217 +            if (actualGapsCount != gapsCount) {
  33.218 +                throw new Error("Bad exception table for test()\n" +
  33.219 +                            "expected gaps: " + gapsCount + "\n" +
  33.220 +                            "found gaps: " + actualGapsCount + "\n" +
  33.221 +                            source);
  33.222 +            }
  33.223 +        } catch (Exception e) {
  33.224 +            e.printStackTrace();
  33.225 +            throw new Error("error reading " + compiledTest +": " + e);
  33.226 +        }
  33.227 +
  33.228 +    }
  33.229 +
  33.230 +    class JavaSource extends SimpleJavaFileObject {
  33.231 +
  33.232 +        static final String source_template =
  33.233 +                "class A extends RuntimeException {} \n" +
  33.234 +                "class B extends RuntimeException {} \n" +
  33.235 +                "class C extends RuntimeException {} \n" +
  33.236 +                "class D extends RuntimeException {} \n" +
  33.237 +                "class E extends RuntimeException {} \n" +
  33.238 +                "class Test {\n" +
  33.239 +                "   void test() {\n" +
  33.240 +                "   try { #S0 } #C finally { System.out.println(); }\n" +
  33.241 +                "   }\n" +
  33.242 +                "}";
  33.243 +
  33.244 +        String source;
  33.245 +
  33.246 +        public JavaSource() {
  33.247 +            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
  33.248 +            source = source_template.replace("#C", ca.catchers());
  33.249 +            source = source.replace("#S0", stmts[0].stmt);
  33.250 +            for (int i = 1; i < ca.ordinal() + 1; i++) {
  33.251 +                source = source.replace("#S" + i, stmts[i].stmt);
  33.252 +            }
  33.253 +        }
  33.254 +
  33.255 +        @Override
  33.256 +        public String toString() {
  33.257 +            return source;
  33.258 +        }
  33.259 +
  33.260 +        @Override
  33.261 +        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
  33.262 +            return source;
  33.263 +        }
  33.264 +    }
  33.265 +}
    34.1 --- a/test/tools/javac/api/TestJavacTaskScanner.java	Thu Oct 27 13:54:50 2011 -0700
    34.2 +++ b/test/tools/javac/api/TestJavacTaskScanner.java	Fri Oct 28 17:49:36 2011 -0700
    34.3 @@ -32,6 +32,7 @@
    34.4  
    34.5  import com.sun.tools.javac.api.JavacTaskImpl;
    34.6  import com.sun.tools.javac.parser.*;
    34.7 +import com.sun.tools.javac.parser.Tokens.Token;
    34.8  import com.sun.tools.javac.util.*;
    34.9  import java.io.*;
   34.10  import java.net.*;
   34.11 @@ -93,7 +94,7 @@
   34.12  
   34.13          check(numTokens, "#Tokens", 1222);
   34.14          check(numParseTypeElements, "#parseTypeElements", 136);
   34.15 -        check(numAllMembers, "#allMembers", 67);
   34.16 +        check(numAllMembers, "#allMembers", 52);
   34.17      }
   34.18  
   34.19      void check(int value, String name, int expected) {
   34.20 @@ -206,7 +207,8 @@
   34.21  
   34.22      public void nextToken() {
   34.23          super.nextToken();
   34.24 -        System.err.format("Saw token %s (%s)%n", token(), name());
   34.25 +        Token tk = token();
   34.26 +        System.err.format("Saw token %s %n", tk.kind);
   34.27          test.numTokens++;
   34.28      }
   34.29  
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/test/tools/javac/depDocComment/DeprecatedDocComment3.java	Fri Oct 28 17:49:36 2011 -0700
    35.3 @@ -0,0 +1,41 @@
    35.4 +/*
    35.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    35.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    35.7 + *
    35.8 + * This code is free software; you can redistribute it and/or modify it
    35.9 + * under the terms of the GNU General Public License version 2 only, as
   35.10 + * published by the Free Software Foundation.
   35.11 + *
   35.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   35.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   35.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   35.15 + * version 2 for more details (a copy is included in the LICENSE file that
   35.16 + * accompanied this code).
   35.17 + *
   35.18 + * You should have received a copy of the GNU General Public License version
   35.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   35.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   35.21 + *
   35.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   35.23 + * or visit www.oracle.com if you need additional information or have any
   35.24 + * questions.
   35.25 + */
   35.26 +
   35.27 +/**
   35.28 + * @test
   35.29 + * @bug 7096014
   35.30 + * @summary Javac tokens should retain state
   35.31 + * @compile -Xlint -Werror DeprecatedDocComment3.java
   35.32 + */
   35.33 +
   35.34 +class DeprecatedDocComment3 {
   35.35 +    static class Foo { }
   35.36 +
   35.37 +    ; /** @deprecated */ ;
   35.38 +
   35.39 +    static class A {}
   35.40 +
   35.41 +    static class B {
   35.42 +       A a; //not deprecated!
   35.43 +    }
   35.44 +}
    36.1 --- a/test/tools/javac/diags/ArgTypeCompilerFactory.java	Thu Oct 27 13:54:50 2011 -0700
    36.2 +++ b/test/tools/javac/diags/ArgTypeCompilerFactory.java	Fri Oct 28 17:49:36 2011 -0700
    36.3 @@ -35,7 +35,7 @@
    36.4  import com.sun.tools.javac.file.*;
    36.5  import com.sun.tools.javac.main.Main;
    36.6  import com.sun.tools.javac.main.JavaCompiler;
    36.7 -import com.sun.tools.javac.parser.Token;
    36.8 +import com.sun.tools.javac.parser.Tokens.TokenKind;
    36.9  import com.sun.tools.javac.util.*;
   36.10  import com.sun.tools.javac.util.AbstractDiagnosticFormatter.SimpleConfiguration;
   36.11  import javax.lang.model.SourceVersion;
   36.12 @@ -319,7 +319,7 @@
   36.13              return "modifier";
   36.14          if (o instanceof KindName)
   36.15              return "symbol kind";
   36.16 -        if (o instanceof Token)
   36.17 +        if (o instanceof TokenKind)
   36.18              return "token";
   36.19          if (o instanceof Symbol)
   36.20              return "symbol";
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/test/tools/javac/diags/examples/ApplicableMethodFound.java	Fri Oct 28 17:49:36 2011 -0700
    37.3 @@ -0,0 +1,33 @@
    37.4 +/*
    37.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    37.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    37.7 + *
    37.8 + * This code is free software; you can redistribute it and/or modify it
    37.9 + * under the terms of the GNU General Public License version 2 only, as
   37.10 + * published by the Free Software Foundation.
   37.11 + *
   37.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   37.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   37.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   37.15 + * version 2 for more details (a copy is included in the LICENSE file that
   37.16 + * accompanied this code).
   37.17 + *
   37.18 + * You should have received a copy of the GNU General Public License version
   37.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   37.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   37.21 + *
   37.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   37.23 + * or visit www.oracle.com if you need additional information or have any
   37.24 + * questions.
   37.25 + */
   37.26 +
   37.27 +// key: compiler.misc.applicable.method.found
   37.28 +// key: compiler.note.verbose.resolve.multi
   37.29 +// options: -XDverboseResolution=applicable,success
   37.30 +
   37.31 +class ApplicableMethodFound {
   37.32 +
   37.33 +    void m() {}
   37.34 +
   37.35 +    { m(); }
   37.36 +}
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/test/tools/javac/diags/examples/ApplicableMethodFound1.java	Fri Oct 28 17:49:36 2011 -0700
    38.3 @@ -0,0 +1,34 @@
    38.4 +/*
    38.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    38.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    38.7 + *
    38.8 + * This code is free software; you can redistribute it and/or modify it
    38.9 + * under the terms of the GNU General Public License version 2 only, as
   38.10 + * published by the Free Software Foundation.
   38.11 + *
   38.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   38.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   38.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   38.15 + * version 2 for more details (a copy is included in the LICENSE file that
   38.16 + * accompanied this code).
   38.17 + *
   38.18 + * You should have received a copy of the GNU General Public License version
   38.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   38.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   38.21 + *
   38.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   38.23 + * or visit www.oracle.com if you need additional information or have any
   38.24 + * questions.
   38.25 + */
   38.26 +
   38.27 +// key: compiler.misc.applicable.method.found.1
   38.28 +// key: compiler.note.verbose.resolve.multi
   38.29 +// key: compiler.misc.full.inst.sig
   38.30 +// options: -XDverboseResolution=applicable,success
   38.31 +
   38.32 +class ApplicableMethodFound1 {
   38.33 +
   38.34 +    <X> void m(X x) {}
   38.35 +
   38.36 +    { m(1); }
   38.37 +}
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/test/tools/javac/diags/examples/DeferredMethodInst.java	Fri Oct 28 17:49:36 2011 -0700
    39.3 @@ -0,0 +1,35 @@
    39.4 +/*
    39.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    39.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    39.7 + *
    39.8 + * This code is free software; you can redistribute it and/or modify it
    39.9 + * under the terms of the GNU General Public License version 2 only, as
   39.10 + * published by the Free Software Foundation.
   39.11 + *
   39.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   39.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   39.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   39.15 + * version 2 for more details (a copy is included in the LICENSE file that
   39.16 + * accompanied this code).
   39.17 + *
   39.18 + * You should have received a copy of the GNU General Public License version
   39.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   39.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   39.21 + *
   39.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   39.23 + * or visit www.oracle.com if you need additional information or have any
   39.24 + * questions.
   39.25 + */
   39.26 +
   39.27 +// key: compiler.misc.applicable.method.found.1
   39.28 +// key: compiler.note.verbose.resolve.multi
   39.29 +// key: compiler.note.deferred.method.inst
   39.30 +// key: compiler.misc.partial.inst.sig
   39.31 +// options: -XDverboseResolution=applicable,success,deferred-inference
   39.32 +
   39.33 +class DeferredMethodInst {
   39.34 +
   39.35 +    <X> X m() { return null; }
   39.36 +
   39.37 +    { Integer i = m(); }
   39.38 +}
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/test/tools/javac/diags/examples/FullInstSig.java	Fri Oct 28 17:49:36 2011 -0700
    40.3 @@ -0,0 +1,34 @@
    40.4 +/*
    40.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    40.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    40.7 + *
    40.8 + * This code is free software; you can redistribute it and/or modify it
    40.9 + * under the terms of the GNU General Public License version 2 only, as
   40.10 + * published by the Free Software Foundation.
   40.11 + *
   40.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   40.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   40.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   40.15 + * version 2 for more details (a copy is included in the LICENSE file that
   40.16 + * accompanied this code).
   40.17 + *
   40.18 + * You should have received a copy of the GNU General Public License version
   40.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   40.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   40.21 + *
   40.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   40.23 + * or visit www.oracle.com if you need additional information or have any
   40.24 + * questions.
   40.25 + */
   40.26 +
   40.27 +// key: compiler.misc.applicable.method.found.1
   40.28 +// key: compiler.note.verbose.resolve.multi
   40.29 +// key: compiler.misc.full.inst.sig
   40.30 +// options: -XDverboseResolution=applicable,success
   40.31 +
   40.32 +class FullInstSig {
   40.33 +
   40.34 +    <X> void m(X x) {}
   40.35 +
   40.36 +    { m(1); }
   40.37 +}
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/test/tools/javac/diags/examples/NotApplicableMethodFound.java	Fri Oct 28 17:49:36 2011 -0700
    41.3 @@ -0,0 +1,35 @@
    41.4 +/*
    41.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    41.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    41.7 + *
    41.8 + * This code is free software; you can redistribute it and/or modify it
    41.9 + * under the terms of the GNU General Public License version 2 only, as
   41.10 + * published by the Free Software Foundation.
   41.11 + *
   41.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   41.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   41.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   41.15 + * version 2 for more details (a copy is included in the LICENSE file that
   41.16 + * accompanied this code).
   41.17 + *
   41.18 + * You should have received a copy of the GNU General Public License version
   41.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   41.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   41.21 + *
   41.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   41.23 + * or visit www.oracle.com if you need additional information or have any
   41.24 + * questions.
   41.25 + */
   41.26 +
   41.27 +// key: compiler.misc.not.applicable.method.found
   41.28 +// key: compiler.note.verbose.resolve.multi.1
   41.29 +// key: compiler.err.cant.apply.symbol.1
   41.30 +// key: compiler.misc.no.conforming.assignment.exists
   41.31 +// options: -XDverboseResolution=inapplicable,failure
   41.32 +
   41.33 +class NotApplicableMethodFound {
   41.34 +
   41.35 +    void m(int i) {}
   41.36 +
   41.37 +    { m(""); }
   41.38 +}
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/test/tools/javac/diags/examples/PartialInstSig.java	Fri Oct 28 17:49:36 2011 -0700
    42.3 @@ -0,0 +1,34 @@
    42.4 +/*
    42.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    42.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    42.7 + *
    42.8 + * This code is free software; you can redistribute it and/or modify it
    42.9 + * under the terms of the GNU General Public License version 2 only, as
   42.10 + * published by the Free Software Foundation.
   42.11 + *
   42.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   42.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   42.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   42.15 + * version 2 for more details (a copy is included in the LICENSE file that
   42.16 + * accompanied this code).
   42.17 + *
   42.18 + * You should have received a copy of the GNU General Public License version
   42.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   42.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   42.21 + *
   42.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   42.23 + * or visit www.oracle.com if you need additional information or have any
   42.24 + * questions.
   42.25 + */
   42.26 +
   42.27 +// key: compiler.misc.applicable.method.found.1
   42.28 +// key: compiler.note.verbose.resolve.multi
   42.29 +// key: compiler.misc.partial.inst.sig
   42.30 +// options: -XDverboseResolution=applicable,success
   42.31 +
   42.32 +class PartialInstSig {
   42.33 +
   42.34 +    <X> X m() { return null; }
   42.35 +
   42.36 +    { m(); }
   42.37 +}
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/test/tools/javac/diags/examples/VerboseResolveMulti.java	Fri Oct 28 17:49:36 2011 -0700
    43.3 @@ -0,0 +1,33 @@
    43.4 +/*
    43.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    43.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    43.7 + *
    43.8 + * This code is free software; you can redistribute it and/or modify it
    43.9 + * under the terms of the GNU General Public License version 2 only, as
   43.10 + * published by the Free Software Foundation.
   43.11 + *
   43.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   43.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   43.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   43.15 + * version 2 for more details (a copy is included in the LICENSE file that
   43.16 + * accompanied this code).
   43.17 + *
   43.18 + * You should have received a copy of the GNU General Public License version
   43.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   43.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   43.21 + *
   43.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   43.23 + * or visit www.oracle.com if you need additional information or have any
   43.24 + * questions.
   43.25 + */
   43.26 +
   43.27 +// key: compiler.misc.applicable.method.found
   43.28 +// key: compiler.note.verbose.resolve.multi
   43.29 +// options: -XDverboseResolution=applicable,success
   43.30 +
   43.31 +class VerboseResolveMulti {
   43.32 +
   43.33 +    void m() {}
   43.34 +
   43.35 +    { m(); }
   43.36 +}
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/test/tools/javac/diags/examples/VerboseResolveMulti1.java	Fri Oct 28 17:49:36 2011 -0700
    44.3 @@ -0,0 +1,35 @@
    44.4 +/*
    44.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    44.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    44.7 + *
    44.8 + * This code is free software; you can redistribute it and/or modify it
    44.9 + * under the terms of the GNU General Public License version 2 only, as
   44.10 + * published by the Free Software Foundation.
   44.11 + *
   44.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   44.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   44.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   44.15 + * version 2 for more details (a copy is included in the LICENSE file that
   44.16 + * accompanied this code).
   44.17 + *
   44.18 + * You should have received a copy of the GNU General Public License version
   44.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   44.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   44.21 + *
   44.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   44.23 + * or visit www.oracle.com if you need additional information or have any
   44.24 + * questions.
   44.25 + */
   44.26 +
   44.27 +// key: compiler.misc.not.applicable.method.found
   44.28 +// key: compiler.note.verbose.resolve.multi.1
   44.29 +// key: compiler.err.cant.apply.symbol.1
   44.30 +// key: compiler.misc.no.conforming.assignment.exists
   44.31 +// options: -XDverboseResolution=inapplicable,failure
   44.32 +
   44.33 +class VerboseResolveMulti1 {
   44.34 +
   44.35 +    void m(int i) {}
   44.36 +
   44.37 +    { m(""); }
   44.38 +}
    45.1 --- a/test/tools/javac/javazip/Test.sh	Thu Oct 27 13:54:50 2011 -0700
    45.2 +++ b/test/tools/javac/javazip/Test.sh	Fri Oct 28 17:49:36 2011 -0700
    45.3 @@ -47,7 +47,7 @@
    45.4      ;;
    45.5    CYGWIN* )
    45.6      FS="/"
    45.7 -    SCR=`pwd | cygpath -d`
    45.8 +    SCR=`pwd | cygpath -d -f -`
    45.9      ;;
   45.10    Windows* )
   45.11      FS="\\"
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/test/tools/javac/resolve/Candidate.java	Fri Oct 28 17:49:36 2011 -0700
    46.3 @@ -0,0 +1,68 @@
    46.4 +/*
    46.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    46.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    46.7 + *
    46.8 + * This code is free software; you can redistribute it and/or modify it
    46.9 + * under the terms of the GNU General Public License version 2 only, as
   46.10 + * published by the Free Software Foundation.
   46.11 + *
   46.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   46.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   46.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   46.15 + * version 2 for more details (a copy is included in the LICENSE file that
   46.16 + * accompanied this code).
   46.17 + *
   46.18 + * You should have received a copy of the GNU General Public License version
   46.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   46.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   46.21 + *
   46.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   46.23 + * or visit www.oracle.com if you need additional information or have any
   46.24 + * questions.
   46.25 + */
   46.26 +import java.lang.annotation.ElementType;
   46.27 +import java.lang.annotation.Target;
   46.28 +
   46.29 +@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
   46.30 +@interface Candidate {
   46.31 +    /**
   46.32 +     * the candidate position (line/col of the method call for which this candidate
   46.33 +     * is a potential overload candidate)
   46.34 +     */
   46.35 +    Pos pos() default @Pos(userDefined=false);
   46.36 +    /**
   46.37 +     * resolution phases for which this candidate is applicable
   46.38 +     */
   46.39 +    Phase[] applicable() default { };
   46.40 +    /**
   46.41 +     * is this candidate the most specific (in the resolution phases for which it
   46.42 +     * is also applicable)
   46.43 +     */
   46.44 +    boolean mostSpecific() default false;
   46.45 +    /**
   46.46 +     * this candidate inferred signature (in the resolution phases for which it
   46.47 +     * is also applicable, in case it corresponds to a generic method)
   46.48 +     */
   46.49 +    String sig() default "";
   46.50 +}
   46.51 +
   46.52 +enum Phase {
   46.53 +    BASIC("BASIC"),
   46.54 +    BOX("BOX"),
   46.55 +    VARARGS("VARARITY");
   46.56 +
   46.57 +    final String javacString;
   46.58 +
   46.59 +    private Phase(String javacString) {
   46.60 +        this.javacString = javacString;
   46.61 +    }
   46.62 +
   46.63 +    static Phase fromString(String s) {
   46.64 +        for (Phase phase : Phase.values()) {
   46.65 +            if (phase.javacString.equals(s)) {
   46.66 +                return phase;
   46.67 +            }
   46.68 +        }
   46.69 +        throw new AssertionError("Invalid resolution phase string " + s);
   46.70 +    }
   46.71 +}
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/test/tools/javac/resolve/Pos.java	Fri Oct 28 17:49:36 2011 -0700
    47.3 @@ -0,0 +1,31 @@
    47.4 +/*
    47.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    47.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    47.7 + *
    47.8 + * This code is free software; you can redistribute it and/or modify it
    47.9 + * under the terms of the GNU General Public License version 2 only, as
   47.10 + * published by the Free Software Foundation.
   47.11 + *
   47.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   47.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   47.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   47.15 + * version 2 for more details (a copy is included in the LICENSE file that
   47.16 + * accompanied this code).
   47.17 + *
   47.18 + * You should have received a copy of the GNU General Public License version
   47.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   47.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   47.21 + *
   47.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   47.23 + * or visit www.oracle.com if you need additional information or have any
   47.24 + * questions.
   47.25 + */
   47.26 +import java.lang.annotation.ElementType;
   47.27 +import java.lang.annotation.Target;
   47.28 +
   47.29 +@Target(ElementType.ANNOTATION_TYPE)
   47.30 +@interface Pos {
   47.31 +    long line() default -1;
   47.32 +    long col() default -1;
   47.33 +    boolean userDefined() default true;
   47.34 +}
   47.35 \ No newline at end of file
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/test/tools/javac/resolve/ResolveHarness.java	Fri Oct 28 17:49:36 2011 -0700
    48.3 @@ -0,0 +1,475 @@
    48.4 +/*
    48.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    48.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    48.7 + *
    48.8 + * This code is free software; you can redistribute it and/or modify it
    48.9 + * under the terms of the GNU General Public License version 2 only, as
   48.10 + * published by the Free Software Foundation.
   48.11 + *
   48.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   48.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   48.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   48.15 + * version 2 for more details (a copy is included in the LICENSE file that
   48.16 + * accompanied this code).
   48.17 + *
   48.18 + * You should have received a copy of the GNU General Public License version
   48.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   48.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   48.21 + *
   48.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   48.23 + * or visit www.oracle.com if you need additional information or have any
   48.24 + * questions.
   48.25 + */
   48.26 +
   48.27 +/*
   48.28 + * @test
   48.29 + * @bug 7098660
   48.30 + * @summary Write better overload resolution/inference tests
   48.31 + * @library ../lib
   48.32 + * @build JavacTestingAbstractProcessor ResolveHarness
   48.33 + * @run main ResolveHarness
   48.34 + */
   48.35 +
   48.36 +import com.sun.source.util.JavacTask;
   48.37 +import com.sun.tools.javac.api.ClientCodeWrapper.DiagnosticSourceUnwrapper;
   48.38 +import com.sun.tools.javac.code.Type.MethodType;
   48.39 +import com.sun.tools.javac.util.JCDiagnostic;
   48.40 +
   48.41 +import java.io.File;
   48.42 +import java.util.Set;
   48.43 +import java.util.Arrays;
   48.44 +import java.util.ArrayList;
   48.45 +import java.util.Collections;
   48.46 +import java.util.HashMap;
   48.47 +import java.util.HashSet;
   48.48 +import java.util.List;
   48.49 +import java.util.Map;
   48.50 +
   48.51 +import javax.annotation.processing.AbstractProcessor;
   48.52 +import javax.annotation.processing.RoundEnvironment;
   48.53 +import javax.annotation.processing.SupportedAnnotationTypes;
   48.54 +import javax.lang.model.element.Element;
   48.55 +import javax.lang.model.element.TypeElement;
   48.56 +import javax.tools.Diagnostic;
   48.57 +import javax.tools.Diagnostic.Kind;
   48.58 +import javax.tools.DiagnosticListener;
   48.59 +import javax.tools.JavaCompiler;
   48.60 +import javax.tools.JavaFileObject;
   48.61 +import javax.tools.StandardJavaFileManager;
   48.62 +import javax.tools.ToolProvider;
   48.63 +
   48.64 +import static javax.tools.StandardLocation.*;
   48.65 +
   48.66 +public class ResolveHarness implements javax.tools.DiagnosticListener<JavaFileObject> {
   48.67 +
   48.68 +    static int nerrors = 0;
   48.69 +
   48.70 +    static final JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
   48.71 +    static final StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
   48.72 +
   48.73 +    public static void main(String[] args) throws Exception {
   48.74 +        fm.setLocation(SOURCE_PATH,
   48.75 +                Arrays.asList(new File(System.getProperty("test.src"), "tests")));
   48.76 +        for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", Collections.singleton(JavaFileObject.Kind.SOURCE), true)) {
   48.77 +            new ResolveHarness(jfo).check();
   48.78 +        }
   48.79 +        if (nerrors > 0) {
   48.80 +            throw new AssertionError("Errors were found");
   48.81 +        }
   48.82 +    }
   48.83 +
   48.84 +
   48.85 +    JavaFileObject jfo;
   48.86 +    DiagnosticProcessor[] diagProcessors;
   48.87 +    Map<ElementKey, Candidate> candidatesMap = new HashMap<ElementKey, Candidate>();
   48.88 +    Set<String> declaredKeys = new HashSet<>();
   48.89 +    List<Diagnostic<? extends JavaFileObject>> diags = new ArrayList<>();
   48.90 +    List<ElementKey> seenCandidates = new ArrayList<>();
   48.91 +
   48.92 +    protected ResolveHarness(JavaFileObject jfo) {
   48.93 +        this.jfo = jfo;
   48.94 +        this.diagProcessors = new DiagnosticProcessor[] {
   48.95 +            new VerboseResolutionNoteProcessor(),
   48.96 +            new VerboseDeferredInferenceNoteProcessor(),
   48.97 +            new ErrorProcessor()
   48.98 +        };
   48.99 +    }
  48.100 +
  48.101 +    protected void check() throws Exception {
  48.102 +        String[] options = {
  48.103 +            "-XDshouldStopPolicy=ATTR",
  48.104 +            "-XDverboseResolution=success,failure,applicable,inapplicable,deferred-inference"
  48.105 +        };
  48.106 +
  48.107 +        AbstractProcessor[] processors = { new ResolveCandidateFinder(), null };
  48.108 +
  48.109 +        @SuppressWarnings("unchecked")
  48.110 +        DiagnosticListener<? super JavaFileObject>[] diagListeners =
  48.111 +                new DiagnosticListener[] { new DiagnosticHandler(false), new DiagnosticHandler(true) };
  48.112 +
  48.113 +        for (int i = 0 ; i < options.length ; i ++) {
  48.114 +            JavacTask ct = (JavacTask)comp.getTask(null, fm, diagListeners[i],
  48.115 +                    Arrays.asList(options[i]), null, Arrays.asList(jfo));
  48.116 +            if (processors[i] != null) {
  48.117 +                ct.setProcessors(Collections.singleton(processors[i]));
  48.118 +            }
  48.119 +            ct.analyze();
  48.120 +        }
  48.121 +
  48.122 +        //check diags
  48.123 +        for (Diagnostic<? extends JavaFileObject> diag : diags) {
  48.124 +            for (DiagnosticProcessor proc : diagProcessors) {
  48.125 +                if (proc.matches(diag)) {
  48.126 +                    proc.process(diag);
  48.127 +                    break;
  48.128 +                }
  48.129 +            }
  48.130 +        }
  48.131 +        //check all candidates have been used up
  48.132 +        for (Map.Entry<ElementKey, Candidate> entry : candidatesMap.entrySet()) {
  48.133 +            if (!seenCandidates.contains(entry.getKey())) {
  48.134 +                error("Redundant @Candidate annotation on method " + entry.getKey().elem);
  48.135 +            }
  48.136 +        }
  48.137 +    }
  48.138 +
  48.139 +    public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.140 +        diags.add(diagnostic);
  48.141 +    }
  48.142 +
  48.143 +    Candidate getCandidateAtPos(Element methodSym, long line, long col) {
  48.144 +        Candidate c = candidatesMap.get(new ElementKey(methodSym));
  48.145 +        if (c != null) {
  48.146 +            Pos pos = c.pos();
  48.147 +            if (!pos.userDefined() ||
  48.148 +                    (pos.line() == line && pos.col() == col)) {
  48.149 +                seenCandidates.add(new ElementKey(methodSym));
  48.150 +                return c;
  48.151 +            }
  48.152 +        } else {
  48.153 +            error("Missing @Candidate annotation on method " + methodSym);
  48.154 +        }
  48.155 +        return null;
  48.156 +    }
  48.157 +
  48.158 +    void checkSig(Candidate c, Element methodSym, MethodType mtype) {
  48.159 +        if (c.sig().length() > 0 && !c.sig().equals(mtype.toString())) {
  48.160 +            error("Inferred type mismatch for method: " + methodSym);
  48.161 +        }
  48.162 +    }
  48.163 +
  48.164 +    protected void error(String msg) {
  48.165 +        nerrors++;
  48.166 +        System.err.printf("Error occurred while checking file: %s\nreason: %s\n", jfo.getName(), msg);
  48.167 +    }
  48.168 +
  48.169 +    /**
  48.170 +     * Base class for diagnostic processor. It provides methods for matching and
  48.171 +     * processing a given diagnostic object (overridden by subclasses).
  48.172 +     */
  48.173 +    abstract class DiagnosticProcessor {
  48.174 +
  48.175 +        List<String> codes;
  48.176 +        Diagnostic.Kind kind;
  48.177 +
  48.178 +        public DiagnosticProcessor(Kind kind, String... codes) {
  48.179 +            this.codes = Arrays.asList(codes);
  48.180 +            this.kind = kind;
  48.181 +        }
  48.182 +
  48.183 +        abstract void process(Diagnostic<? extends JavaFileObject> diagnostic);
  48.184 +
  48.185 +        boolean matches(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.186 +            return (codes.isEmpty() || codes.contains(diagnostic.getCode())) &&
  48.187 +                    diagnostic.getKind() == kind;
  48.188 +        }
  48.189 +
  48.190 +        JCDiagnostic asJCDiagnostic(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.191 +            if (diagnostic instanceof JCDiagnostic) {
  48.192 +                return (JCDiagnostic)diagnostic;
  48.193 +            } else if (diagnostic instanceof DiagnosticSourceUnwrapper) {
  48.194 +                return ((DiagnosticSourceUnwrapper)diagnostic).d;
  48.195 +            } else {
  48.196 +                throw new AssertionError("Cannot convert diagnostic to JCDiagnostic: " + diagnostic.getClass().getName());
  48.197 +            }
  48.198 +        }
  48.199 +
  48.200 +        List<JCDiagnostic> subDiagnostics(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.201 +            JCDiagnostic diag = asJCDiagnostic(diagnostic);
  48.202 +            if (diag instanceof JCDiagnostic.MultilineDiagnostic) {
  48.203 +                return ((JCDiagnostic.MultilineDiagnostic)diag).getSubdiagnostics();
  48.204 +            } else {
  48.205 +                throw new AssertionError("Cannot extract subdiagnostics: " + diag.getClass().getName());
  48.206 +            }
  48.207 +        }
  48.208 +    }
  48.209 +
  48.210 +    /**
  48.211 +     * Processor for verbose resolution notes generated by javac. The processor
  48.212 +     * checks that the diagnostic is associated with a method declared by
  48.213 +     * a class annotated with the special @TraceResolve marker annotation. If
  48.214 +     * that's the case, all subdiagnostics (one for each resolution candidate)
  48.215 +     * are checked against the corresponding @Candidate annotations, using
  48.216 +     * a VerboseCandidateSubdiagProcessor.
  48.217 +     */
  48.218 +    class VerboseResolutionNoteProcessor extends DiagnosticProcessor {
  48.219 +
  48.220 +        VerboseResolutionNoteProcessor() {
  48.221 +            super(Kind.NOTE,
  48.222 +                    "compiler.note.verbose.resolve.multi",
  48.223 +                    "compiler.note.verbose.resolve.multi.1");
  48.224 +        }
  48.225 +
  48.226 +        @Override
  48.227 +        void process(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.228 +            Element siteSym = getSiteSym(diagnostic);
  48.229 +            if (siteSym.getAnnotation(TraceResolve.class) == null) {
  48.230 +                return;
  48.231 +            }
  48.232 +            int candidateIdx = 0;
  48.233 +            for (JCDiagnostic d : subDiagnostics(diagnostic)) {
  48.234 +                boolean isMostSpecific = candidateIdx++ == mostSpecific(diagnostic);
  48.235 +                VerboseCandidateSubdiagProcessor subProc =
  48.236 +                        new VerboseCandidateSubdiagProcessor(isMostSpecific, phase(diagnostic), success(diagnostic));
  48.237 +                if (subProc.matches(d)) {
  48.238 +                    subProc.process(d);
  48.239 +                } else {
  48.240 +                    throw new AssertionError("Bad subdiagnostic: " + d.getCode());
  48.241 +                }
  48.242 +            }
  48.243 +        }
  48.244 +
  48.245 +        Element getSiteSym(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.246 +            return (Element)asJCDiagnostic(diagnostic).getArgs()[1];
  48.247 +        }
  48.248 +
  48.249 +        int mostSpecific(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.250 +            return success(diagnostic) ?
  48.251 +                    (Integer)asJCDiagnostic(diagnostic).getArgs()[2] : -1;
  48.252 +        }
  48.253 +
  48.254 +        boolean success(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.255 +            return diagnostic.getCode().equals("compiler.note.verbose.resolve.multi");
  48.256 +        }
  48.257 +
  48.258 +        Phase phase(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.259 +            return Phase.fromString(asJCDiagnostic(diagnostic).getArgs()[3].toString());
  48.260 +        }
  48.261 +    }
  48.262 +
  48.263 +    /**
  48.264 +     * Processor for verbose resolution subdiagnostic notes generated by javac.
  48.265 +     * The processor checks that the details of the overload candidate
  48.266 +     * match against the info contained in the corresponding @Candidate
  48.267 +     * annotation (if any).
  48.268 +     */
  48.269 +    class VerboseCandidateSubdiagProcessor extends DiagnosticProcessor {
  48.270 +
  48.271 +        boolean mostSpecific;
  48.272 +        Phase phase;
  48.273 +        boolean success;
  48.274 +
  48.275 +        public VerboseCandidateSubdiagProcessor(boolean mostSpecific, Phase phase, boolean success) {
  48.276 +            super(Kind.OTHER,
  48.277 +                    "compiler.misc.applicable.method.found",
  48.278 +                    "compiler.misc.applicable.method.found.1",
  48.279 +                    "compiler.misc.not.applicable.method.found");
  48.280 +            this.mostSpecific = mostSpecific;
  48.281 +            this.phase = phase;
  48.282 +            this.success = success;
  48.283 +        }
  48.284 +
  48.285 +        @Override
  48.286 +        void process(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.287 +            Element methodSym = methodSym(diagnostic);
  48.288 +            Candidate c = getCandidateAtPos(methodSym,
  48.289 +                    asJCDiagnostic(diagnostic).getLineNumber(),
  48.290 +                    asJCDiagnostic(diagnostic).getColumnNumber());
  48.291 +            if (c == null) {
  48.292 +                return; //nothing to check
  48.293 +            }
  48.294 +
  48.295 +            if (c.applicable().length == 0 && c.mostSpecific()) {
  48.296 +                error("Inapplicable method cannot be most specific " + methodSym);
  48.297 +            }
  48.298 +
  48.299 +            if (isApplicable(diagnostic) != Arrays.asList(c.applicable()).contains(phase)) {
  48.300 +                error("Invalid candidate's applicability " + methodSym);
  48.301 +            }
  48.302 +
  48.303 +            if (success) {
  48.304 +                for (Phase p : c.applicable()) {
  48.305 +                    if (phase.ordinal() < p.ordinal()) {
  48.306 +                        error("Invalid phase " + p + " on method " + methodSym);
  48.307 +                    }
  48.308 +                }
  48.309 +            }
  48.310 +
  48.311 +            if (Arrays.asList(c.applicable()).contains(phase)) { //applicable
  48.312 +                if (c.mostSpecific() != mostSpecific) {
  48.313 +                    error("Invalid most specific value for method " + methodSym);
  48.314 +                }
  48.315 +                MethodType mtype = getSig(diagnostic);
  48.316 +                if (mtype != null) {
  48.317 +                    checkSig(c, methodSym, mtype);
  48.318 +                }
  48.319 +            }
  48.320 +        }
  48.321 +
  48.322 +        boolean isApplicable(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.323 +            return !diagnostic.getCode().equals("compiler.misc.not.applicable.method.found");
  48.324 +        }
  48.325 +
  48.326 +        Element methodSym(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.327 +            return (Element)asJCDiagnostic(diagnostic).getArgs()[1];
  48.328 +        }
  48.329 +
  48.330 +        MethodType getSig(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.331 +            JCDiagnostic details = (JCDiagnostic)asJCDiagnostic(diagnostic).getArgs()[2];
  48.332 +            if (details == null) {
  48.333 +                return null;
  48.334 +            } else if (details instanceof JCDiagnostic) {
  48.335 +                return details.getCode().equals("compiler.misc.full.inst.sig") ?
  48.336 +                        (MethodType)details.getArgs()[0] : null;
  48.337 +            } else {
  48.338 +                throw new AssertionError("Bad diagnostic arg: " + details);
  48.339 +            }
  48.340 +        }
  48.341 +    }
  48.342 +
  48.343 +    /**
  48.344 +     * Processor for verbose deferred inference notes generated by javac. The
  48.345 +     * processor checks that the inferred signature for a given generic method
  48.346 +     * call corresponds to the one (if any) declared in the @Candidate annotation.
  48.347 +     */
  48.348 +    class VerboseDeferredInferenceNoteProcessor extends DiagnosticProcessor {
  48.349 +
  48.350 +        public VerboseDeferredInferenceNoteProcessor() {
  48.351 +            super(Kind.NOTE, "compiler.note.deferred.method.inst");
  48.352 +        }
  48.353 +
  48.354 +        @Override
  48.355 +        void process(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.356 +            Element methodSym = methodSym(diagnostic);
  48.357 +            Candidate c = getCandidateAtPos(methodSym,
  48.358 +                    asJCDiagnostic(diagnostic).getLineNumber(),
  48.359 +                    asJCDiagnostic(diagnostic).getColumnNumber());
  48.360 +            MethodType sig = sig(diagnostic);
  48.361 +            if (c != null && sig != null) {
  48.362 +                checkSig(c, methodSym, sig);
  48.363 +            }
  48.364 +        }
  48.365 +
  48.366 +        Element methodSym(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.367 +            return (Element)asJCDiagnostic(diagnostic).getArgs()[0];
  48.368 +        }
  48.369 +
  48.370 +        MethodType sig(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.371 +            return (MethodType)asJCDiagnostic(diagnostic).getArgs()[1];
  48.372 +        }
  48.373 +    }
  48.374 +
  48.375 +    /**
  48.376 +     * Processor for all error diagnostics; if the error key is not declared in
  48.377 +     * the test file header, the processor reports an error.
  48.378 +     */
  48.379 +    class ErrorProcessor extends DiagnosticProcessor {
  48.380 +
  48.381 +        public ErrorProcessor() {
  48.382 +            super(Diagnostic.Kind.ERROR);
  48.383 +        }
  48.384 +
  48.385 +        @Override
  48.386 +        void process(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.387 +            if (!declaredKeys.contains(diagnostic.getCode())) {
  48.388 +                error("Unexpected compilation error key '" + diagnostic.getCode() + "'");
  48.389 +            }
  48.390 +        }
  48.391 +    }
  48.392 +
  48.393 +    @SupportedAnnotationTypes({"Candidate","TraceResolve"})
  48.394 +    class ResolveCandidateFinder extends JavacTestingAbstractProcessor {
  48.395 +
  48.396 +        @Override
  48.397 +        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
  48.398 +            if (roundEnv.processingOver())
  48.399 +                return true;
  48.400 +
  48.401 +            TypeElement traceResolveAnno = elements.getTypeElement("TraceResolve");
  48.402 +            TypeElement candidateAnno = elements.getTypeElement("Candidate");
  48.403 +
  48.404 +            if (!annotations.contains(traceResolveAnno)) {
  48.405 +                error("no @TraceResolve annotation found in test class");
  48.406 +            }
  48.407 +
  48.408 +            if (!annotations.contains(candidateAnno)) {
  48.409 +                error("no @candidate annotation found in test class");
  48.410 +            }
  48.411 +
  48.412 +            for (Element elem: roundEnv.getElementsAnnotatedWith(traceResolveAnno)) {
  48.413 +                TraceResolve traceResolve = elem.getAnnotation(TraceResolve.class);
  48.414 +                declaredKeys.addAll(Arrays.asList(traceResolve.keys()));
  48.415 +            }
  48.416 +
  48.417 +            for (Element elem: roundEnv.getElementsAnnotatedWith(candidateAnno)) {
  48.418 +                candidatesMap.put(new ElementKey(elem), elem.getAnnotation(Candidate.class));
  48.419 +            }
  48.420 +            return true;
  48.421 +        }
  48.422 +    }
  48.423 +
  48.424 +    class ElementKey {
  48.425 +
  48.426 +        String key;
  48.427 +        Element elem;
  48.428 +
  48.429 +        public ElementKey(Element elem) {
  48.430 +            this.elem = elem;
  48.431 +            this.key = computeKey(elem);
  48.432 +        }
  48.433 +
  48.434 +        @Override
  48.435 +        public boolean equals(Object obj) {
  48.436 +            if (obj instanceof ElementKey) {
  48.437 +                ElementKey other = (ElementKey)obj;
  48.438 +                return other.key.equals(key);
  48.439 +            }
  48.440 +            return false;
  48.441 +        }
  48.442 +
  48.443 +        @Override
  48.444 +        public int hashCode() {
  48.445 +            return key.hashCode();
  48.446 +        }
  48.447 +
  48.448 +        String computeKey(Element e) {
  48.449 +            StringBuilder buf = new StringBuilder();
  48.450 +            while (e != null) {
  48.451 +                buf.append(e.toString());
  48.452 +                e = e.getEnclosingElement();
  48.453 +            }
  48.454 +            buf.append(jfo.getName());
  48.455 +            return buf.toString();
  48.456 +        }
  48.457 +
  48.458 +        @Override
  48.459 +        public String toString() {
  48.460 +            return "Key{"+key+"}";
  48.461 +        }
  48.462 +    }
  48.463 +
  48.464 +    class DiagnosticHandler implements DiagnosticListener<JavaFileObject> {
  48.465 +
  48.466 +        boolean shouldRecordDiags;
  48.467 +
  48.468 +        DiagnosticHandler(boolean shouldRecordDiags) {
  48.469 +            this.shouldRecordDiags = shouldRecordDiags;
  48.470 +        }
  48.471 +
  48.472 +        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
  48.473 +            if (shouldRecordDiags)
  48.474 +                diags.add(diagnostic);
  48.475 +        }
  48.476 +
  48.477 +    }
  48.478 +}
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/test/tools/javac/resolve/TraceResolve.java	Fri Oct 28 17:49:36 2011 -0700
    49.3 @@ -0,0 +1,29 @@
    49.4 +/*
    49.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    49.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    49.7 + *
    49.8 + * This code is free software; you can redistribute it and/or modify it
    49.9 + * under the terms of the GNU General Public License version 2 only, as
   49.10 + * published by the Free Software Foundation.
   49.11 + *
   49.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   49.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   49.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   49.15 + * version 2 for more details (a copy is included in the LICENSE file that
   49.16 + * accompanied this code).
   49.17 + *
   49.18 + * You should have received a copy of the GNU General Public License version
   49.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   49.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   49.21 + *
   49.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   49.23 + * or visit www.oracle.com if you need additional information or have any
   49.24 + * questions.
   49.25 + */
   49.26 +import java.lang.annotation.ElementType;
   49.27 +import java.lang.annotation.Target;
   49.28 +
   49.29 +@Target(ElementType.TYPE)
   49.30 +@interface TraceResolve {
   49.31 +    String[] keys() default {};
   49.32 +}
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/test/tools/javac/resolve/tests/BoxedReturnTypeInference.java	Fri Oct 28 17:49:36 2011 -0700
    50.3 @@ -0,0 +1,60 @@
    50.4 +/*
    50.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    50.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    50.7 + *
    50.8 + * This code is free software; you can redistribute it and/or modify it
    50.9 + * under the terms of the GNU General Public License version 2 only, as
   50.10 + * published by the Free Software Foundation.
   50.11 + *
   50.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   50.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   50.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   50.15 + * version 2 for more details (a copy is included in the LICENSE file that
   50.16 + * accompanied this code).
   50.17 + *
   50.18 + * You should have received a copy of the GNU General Public License version
   50.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   50.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   50.21 + *
   50.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   50.23 + * or visit www.oracle.com if you need additional information or have any
   50.24 + * questions.
   50.25 + */
   50.26 +
   50.27 +@TraceResolve
   50.28 +class BoxedReturnTypeInference {
   50.29 +    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Byte", mostSpecific=true)
   50.30 +    static <B> B m_byte() { return null; }
   50.31 +
   50.32 +    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Short", mostSpecific=true)
   50.33 +    static <S> S m_short() { return null; }
   50.34 +
   50.35 +    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Integer", mostSpecific=true)
   50.36 +    static <I> I m_int() { return null; }
   50.37 +
   50.38 +    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Long", mostSpecific=true)
   50.39 +    static <L> L m_long() { return null; }
   50.40 +
   50.41 +    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Float", mostSpecific=true)
   50.42 +    static <F> F m_float() { return null; }
   50.43 +
   50.44 +    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Double", mostSpecific=true)
   50.45 +    static <D> D m_double() { return null; }
   50.46 +
   50.47 +    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Character", mostSpecific=true)
   50.48 +    static <C> C m_char() { return null; }
   50.49 +
   50.50 +    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Boolean", mostSpecific=true)
   50.51 +    static <Z> Z m_bool() { return null; }
   50.52 +
   50.53 +    {
   50.54 +        Byte b = m_byte();
   50.55 +        Short s = m_short();
   50.56 +        Integer i = m_int();
   50.57 +        Long l = m_long();
   50.58 +        Float f = m_float();
   50.59 +        Double d = m_double();
   50.60 +        Character c= m_char();
   50.61 +        Boolean z = m_bool();
   50.62 +    }
   50.63 +}
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/test/tools/javac/resolve/tests/PrimitiveOverReferenceOverInferred.java	Fri Oct 28 17:49:36 2011 -0700
    51.3 @@ -0,0 +1,92 @@
    51.4 +/*
    51.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    51.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    51.7 + *
    51.8 + * This code is free software; you can redistribute it and/or modify it
    51.9 + * under the terms of the GNU General Public License version 2 only, as
   51.10 + * published by the Free Software Foundation.
   51.11 + *
   51.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   51.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   51.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   51.15 + * version 2 for more details (a copy is included in the LICENSE file that
   51.16 + * accompanied this code).
   51.17 + *
   51.18 + * You should have received a copy of the GNU General Public License version
   51.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   51.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   51.21 + *
   51.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   51.23 + * or visit www.oracle.com if you need additional information or have any
   51.24 + * questions.
   51.25 + */
   51.26 +
   51.27 +@TraceResolve
   51.28 +class PrimitiveOverReference {
   51.29 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   51.30 +    static void m_byte(byte b) {}
   51.31 +    @Candidate
   51.32 +    static void m_byte(Byte b) {}
   51.33 +    @Candidate
   51.34 +    static <B> void m_byte(B b) {}
   51.35 +
   51.36 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   51.37 +    static void m_short(short s) {}
   51.38 +    @Candidate
   51.39 +    static void m_short(Short s) {}
   51.40 +    @Candidate
   51.41 +    static <S> void m_short(S s) {}
   51.42 +
   51.43 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   51.44 +    static void m_int(int i) {}
   51.45 +    @Candidate
   51.46 +    static void m_int(Integer i) {}
   51.47 +    @Candidate
   51.48 +    static <I> void m_int(I i) {}
   51.49 +
   51.50 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   51.51 +    static void m_long(long l) {}
   51.52 +    @Candidate
   51.53 +    static void m_long(Long l) {}
   51.54 +    @Candidate
   51.55 +    static <L> void m_long(L l) {}
   51.56 +
   51.57 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   51.58 +    static void m_float(float f) {}
   51.59 +    @Candidate
   51.60 +    static void m_float(Float f) {}
   51.61 +    @Candidate
   51.62 +    static <F> void m_float(F f) {}
   51.63 +
   51.64 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   51.65 +    static void m_double(double d) {}
   51.66 +    @Candidate
   51.67 +    static void m_double(Double d) {}
   51.68 +    @Candidate
   51.69 +    static <D> void m_double(D d) {}
   51.70 +
   51.71 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   51.72 +    static void m_char(char c) {}
   51.73 +    @Candidate
   51.74 +    static void m_char(Character c) {}
   51.75 +    @Candidate
   51.76 +    static <C> void m_char(C c) {}
   51.77 +
   51.78 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   51.79 +    static void m_bool(boolean z) {}
   51.80 +    @Candidate
   51.81 +    static void m_bool(Boolean z) {}
   51.82 +    @Candidate
   51.83 +    static <Z> void m_bool(Z z) {}
   51.84 +
   51.85 +    {
   51.86 +        m_byte((byte)0);
   51.87 +        m_short((short)0);
   51.88 +        m_int(0);
   51.89 +        m_long(0L);
   51.90 +        m_float(0.0f);
   51.91 +        m_double(0.0);
   51.92 +        m_char('?');
   51.93 +        m_bool(false);
   51.94 +    }
   51.95 +}
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/test/tools/javac/resolve/tests/PrimitiveOverReferenceOverVarargs.java	Fri Oct 28 17:49:36 2011 -0700
    52.3 @@ -0,0 +1,108 @@
    52.4 +/*
    52.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    52.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    52.7 + *
    52.8 + * This code is free software; you can redistribute it and/or modify it
    52.9 + * under the terms of the GNU General Public License version 2 only, as
   52.10 + * published by the Free Software Foundation.
   52.11 + *
   52.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   52.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   52.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   52.15 + * version 2 for more details (a copy is included in the LICENSE file that
   52.16 + * accompanied this code).
   52.17 + *
   52.18 + * You should have received a copy of the GNU General Public License version
   52.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   52.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   52.21 + *
   52.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   52.23 + * or visit www.oracle.com if you need additional information or have any
   52.24 + * questions.
   52.25 + */
   52.26 +
   52.27 +@TraceResolve
   52.28 +class PrimitiveOverReference {
   52.29 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   52.30 +    static void m_byte(byte b) {}
   52.31 +    @Candidate
   52.32 +    static void m_byte(Byte b) {}
   52.33 +    @Candidate
   52.34 +    static void m_byte(byte... b) {}
   52.35 +    @Candidate
   52.36 +    static void m_byte(Byte... b) {}
   52.37 +
   52.38 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   52.39 +    static void m_short(short s) {}
   52.40 +    @Candidate
   52.41 +    static void m_short(Short s) {}
   52.42 +    @Candidate
   52.43 +    static void m_short(short... s) {}
   52.44 +    @Candidate
   52.45 +    static void m_short(Short... s) {}
   52.46 +
   52.47 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   52.48 +    static void m_int(int i) {}
   52.49 +    @Candidate
   52.50 +    static void m_int(Integer i) {}
   52.51 +    @Candidate
   52.52 +    static void m_int(int... i) {}
   52.53 +    @Candidate
   52.54 +    static void m_int(Integer... i) {}
   52.55 +
   52.56 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   52.57 +    static void m_long(long l) {}
   52.58 +    @Candidate
   52.59 +    static void m_long(Long l) {}
   52.60 +    @Candidate
   52.61 +    static void m_long(long... l) {}
   52.62 +    @Candidate
   52.63 +    static void m_long(Long... l) {}
   52.64 +
   52.65 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   52.66 +    static void m_float(float f) {}
   52.67 +    @Candidate
   52.68 +    static void m_float(Float f) {}
   52.69 +    @Candidate
   52.70 +    static void m_float(float... f) {}
   52.71 +    @Candidate
   52.72 +    static void m_float(Float... f) {}
   52.73 +
   52.74 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   52.75 +    static void m_double(double d) {}
   52.76 +    @Candidate
   52.77 +    static void m_double(Double d) {}
   52.78 +    @Candidate
   52.79 +    static void m_double(double... d) {}
   52.80 +    @Candidate
   52.81 +    static void m_double(Double... d) {}
   52.82 +
   52.83 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   52.84 +    static void m_char(char c) {}
   52.85 +    @Candidate
   52.86 +    static void m_char(Character c) {}
   52.87 +    @Candidate
   52.88 +    static void m_char(char... c) {}
   52.89 +    @Candidate
   52.90 +    static void m_char(Character... c) {}
   52.91 +
   52.92 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   52.93 +    static void m_bool(boolean z) {}
   52.94 +    @Candidate
   52.95 +    static void m_bool(Boolean z) {}
   52.96 +    @Candidate
   52.97 +    static void m_bool(boolean... z) {}
   52.98 +    @Candidate
   52.99 +    static void m_bool(Boolean... z) {}
  52.100 +
  52.101 +    {
  52.102 +        m_byte((byte)0);
  52.103 +        m_short((short)0);
  52.104 +        m_int(0);
  52.105 +        m_long(0L);
  52.106 +        m_float(0.0f);
  52.107 +        m_double(0.0);
  52.108 +        m_char('?');
  52.109 +        m_bool(false);
  52.110 +    }
  52.111 +}
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/test/tools/javac/resolve/tests/PrimitiveOverReferenceVarargsAmbiguous.java	Fri Oct 28 17:49:36 2011 -0700
    53.3 @@ -0,0 +1,76 @@
    53.4 +/*
    53.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    53.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    53.7 + *
    53.8 + * This code is free software; you can redistribute it and/or modify it
    53.9 + * under the terms of the GNU General Public License version 2 only, as
   53.10 + * published by the Free Software Foundation.
   53.11 + *
   53.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   53.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   53.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   53.15 + * version 2 for more details (a copy is included in the LICENSE file that
   53.16 + * accompanied this code).
   53.17 + *
   53.18 + * You should have received a copy of the GNU General Public License version
   53.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   53.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   53.21 + *
   53.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   53.23 + * or visit www.oracle.com if you need additional information or have any
   53.24 + * questions.
   53.25 + */
   53.26 +
   53.27 +@TraceResolve(keys={"compiler.err.ref.ambiguous"})
   53.28 +class PrimitiveOverReferenceVarargsAmbiguous {
   53.29 +    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
   53.30 +    static void m_byte(byte... b) {}
   53.31 +    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
   53.32 +    static void m_byte(Byte... b) {}
   53.33 +
   53.34 +    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
   53.35 +    static void m_short(short... s) {}
   53.36 +    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
   53.37 +    static void m_short(Short... s) {}
   53.38 +
   53.39 +    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
   53.40 +    static void m_int(int... i) {}
   53.41 +    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
   53.42 +    static void m_int(Integer... i) {}
   53.43 +
   53.44 +    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
   53.45 +    static void m_long(long... l) {}
   53.46 +    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
   53.47 +    static void m_long(Long... l) {}
   53.48 +
   53.49 +    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
   53.50 +    static void m_float(float... f) {}
   53.51 +    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
   53.52 +    static void m_float(Float... f) {}
   53.53 +
   53.54 +    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
   53.55 +    static void m_double(double... d) {}
   53.56 +    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
   53.57 +    static void m_double(Double... d) {}
   53.58 +
   53.59 +    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
   53.60 +    static void m_char(char... c) {}
   53.61 +    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
   53.62 +    static void m_char(Character... c) {}
   53.63 +
   53.64 +    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
   53.65 +    static void m_bool(boolean... z) {}
   53.66 +    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
   53.67 +    static void m_bool(Boolean... z) {}
   53.68 +
   53.69 +    {
   53.70 +        m_byte((byte)0);
   53.71 +        m_short((short)0);
   53.72 +        m_int(0);
   53.73 +        m_long(0L);
   53.74 +        m_float(0.0f);
   53.75 +        m_double(0.0);
   53.76 +        m_char('?');
   53.77 +        m_bool(false);
   53.78 +    }
   53.79 +}
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/test/tools/javac/resolve/tests/PrimitiveOverload.java	Fri Oct 28 17:49:36 2011 -0700
    54.3 @@ -0,0 +1,113 @@
    54.4 +/*
    54.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    54.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    54.7 + *
    54.8 + * This code is free software; you can redistribute it and/or modify it
    54.9 + * under the terms of the GNU General Public License version 2 only, as
   54.10 + * published by the Free Software Foundation.
   54.11 + *
   54.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   54.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   54.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   54.15 + * version 2 for more details (a copy is included in the LICENSE file that
   54.16 + * accompanied this code).
   54.17 + *
   54.18 + * You should have received a copy of the GNU General Public License version
   54.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   54.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   54.21 + *
   54.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   54.23 + * or visit www.oracle.com if you need additional information or have any
   54.24 + * questions.
   54.25 + */
   54.26 +
   54.27 +@TraceResolve
   54.28 +class PrimitiveOverload {
   54.29 +
   54.30 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   54.31 +    static void m_byte(byte b) {}
   54.32 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   54.33 +    static void m_byte(short b) {}
   54.34 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   54.35 +    static void m_byte(int b) {}
   54.36 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   54.37 +    static void m_byte(long b) {}
   54.38 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   54.39 +    static void m_byte(float b) {}
   54.40 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   54.41 +    static void m_byte(double b) {}
   54.42 +
   54.43 +    @Candidate
   54.44 +    static void m_short(byte b) {}
   54.45 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   54.46 +    static void m_short(short b) {}
   54.47 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   54.48 +    static void m_short(int b) {}
   54.49 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   54.50 +    static void m_short(long b) {}
   54.51 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   54.52 +    static void m_short(float b) {}
   54.53 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   54.54 +    static void m_short(double b) {}
   54.55 +
   54.56 +    @Candidate
   54.57 +    static void m_int(byte b) {}
   54.58 +    @Candidate
   54.59 +    static void m_int(short b) {}
   54.60 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   54.61 +    static void m_int(int b) {}
   54.62 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   54.63 +    static void m_int(long b) {}
   54.64 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   54.65 +    static void m_int(float b) {}
   54.66 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   54.67 +    static void m_int(double b) {}
   54.68 +
   54.69 +    @Candidate
   54.70 +    static void m_long(byte b) {}
   54.71 +    @Candidate
   54.72 +    static void m_long(short b) {}
   54.73 +    @Candidate
   54.74 +    static void m_long(int b) {}
   54.75 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   54.76 +    static void m_long(long b) {}
   54.77 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   54.78 +    static void m_long(float b) {}
   54.79 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   54.80 +    static void m_long(double b) {}
   54.81 +
   54.82 +    @Candidate
   54.83 +    static void m_float(byte b) {}
   54.84 +    @Candidate
   54.85 +    static void m_float(short b) {}
   54.86 +    @Candidate
   54.87 +    static void m_float(int b) {}
   54.88 +    @Candidate
   54.89 +    static void m_float(long b) {}
   54.90 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   54.91 +    static void m_float(float b) {}
   54.92 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   54.93 +    static void m_float(double b) {}
   54.94 +
   54.95 +    @Candidate
   54.96 +    static void m_double(byte b) {}
   54.97 +    @Candidate
   54.98 +    static void m_double(short b) {}
   54.99 +    @Candidate
  54.100 +    static void m_double(int b) {}
  54.101 +    @Candidate
  54.102 +    static void m_double(long b) {}
  54.103 +    @Candidate
  54.104 +    static void m_double(float b) {}
  54.105 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
  54.106 +    static void m_double(double b) {}
  54.107 +
  54.108 +    {
  54.109 +        m_byte((byte)0);
  54.110 +        m_short((short)0);
  54.111 +        m_int(0);
  54.112 +        m_long(0L);
  54.113 +        m_float(0.0f);
  54.114 +        m_double(0.0);
  54.115 +    }
  54.116 +}
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/test/tools/javac/resolve/tests/PrimitiveReturnTypeInference.java	Fri Oct 28 17:49:36 2011 -0700
    55.3 @@ -0,0 +1,60 @@
    55.4 +/*
    55.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    55.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    55.7 + *
    55.8 + * This code is free software; you can redistribute it and/or modify it
    55.9 + * under the terms of the GNU General Public License version 2 only, as
   55.10 + * published by the Free Software Foundation.
   55.11 + *
   55.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   55.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   55.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   55.15 + * version 2 for more details (a copy is included in the LICENSE file that
   55.16 + * accompanied this code).
   55.17 + *
   55.18 + * You should have received a copy of the GNU General Public License version
   55.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   55.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   55.21 + *
   55.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   55.23 + * or visit www.oracle.com if you need additional information or have any
   55.24 + * questions.
   55.25 + */
   55.26 +
   55.27 +@TraceResolve
   55.28 +class PrimitiveReturnTypeInference {
   55.29 +    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Byte", mostSpecific=true)
   55.30 +    static <B> B m_byte() { return null; }
   55.31 +
   55.32 +    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Short", mostSpecific=true)
   55.33 +    static <S> S m_short() { return null; }
   55.34 +
   55.35 +    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Integer", mostSpecific=true)
   55.36 +    static <I> I m_int() { return null; }
   55.37 +
   55.38 +    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Long", mostSpecific=true)
   55.39 +    static <L> L m_long() { return null; }
   55.40 +
   55.41 +    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Float", mostSpecific=true)
   55.42 +    static <F> F m_float() { return null; }
   55.43 +
   55.44 +    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Double", mostSpecific=true)
   55.45 +    static <D> D m_double() { return null; }
   55.46 +
   55.47 +    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Character", mostSpecific=true)
   55.48 +    static <C> C m_char() { return null; }
   55.49 +
   55.50 +    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Boolean", mostSpecific=true)
   55.51 +    static <Z> Z m_bool() { return null; }
   55.52 +
   55.53 +    {
   55.54 +        byte b = m_byte();
   55.55 +        short s = m_short();
   55.56 +        int i = m_int();
   55.57 +        long l = m_long();
   55.58 +        float f = m_float();
   55.59 +        double d = m_double();
   55.60 +        char c= m_char();
   55.61 +        boolean z = m_bool();
   55.62 +    }
   55.63 +}
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/test/tools/javac/resolve/tests/ReferenceOverInferred.java	Fri Oct 28 17:49:36 2011 -0700
    56.3 @@ -0,0 +1,76 @@
    56.4 +/*
    56.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    56.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    56.7 + *
    56.8 + * This code is free software; you can redistribute it and/or modify it
    56.9 + * under the terms of the GNU General Public License version 2 only, as
   56.10 + * published by the Free Software Foundation.
   56.11 + *
   56.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   56.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   56.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   56.15 + * version 2 for more details (a copy is included in the LICENSE file that
   56.16 + * accompanied this code).
   56.17 + *
   56.18 + * You should have received a copy of the GNU General Public License version
   56.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   56.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   56.21 + *
   56.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   56.23 + * or visit www.oracle.com if you need additional information or have any
   56.24 + * questions.
   56.25 + */
   56.26 +
   56.27 +@TraceResolve
   56.28 +class PrimitiveOverInferred {
   56.29 +    @Candidate(applicable=Phase.BOX, mostSpecific=true)
   56.30 +    static void m_byte(Byte b) {}
   56.31 +    @Candidate(applicable=Phase.BOX, sig="(java.lang.Byte)void")
   56.32 +    static <B> void m_byte(B b) {}
   56.33 +
   56.34 +    @Candidate(applicable=Phase.BOX, mostSpecific=true)
   56.35 +    static void m_short(Short s) {}
   56.36 +    @Candidate(applicable=Phase.BOX, sig="(java.lang.Short)void")
   56.37 +    static <S> void m_short(S s) {}
   56.38 +
   56.39 +    @Candidate(applicable=Phase.BOX, mostSpecific=true)
   56.40 +    static void m_int(Integer i) {}
   56.41 +    @Candidate(applicable=Phase.BOX, sig="(java.lang.Integer)void")
   56.42 +    static <I> void m_int(I i) {}
   56.43 +
   56.44 +    @Candidate(applicable=Phase.BOX, mostSpecific=true)
   56.45 +    static void m_long(Long l) {}
   56.46 +    @Candidate(applicable=Phase.BOX, sig="(java.lang.Long)void")
   56.47 +    static <L> void m_long(L l) {}
   56.48 +
   56.49 +    @Candidate(applicable=Phase.BOX, mostSpecific=true)
   56.50 +    static void m_float(Float f) {}
   56.51 +    @Candidate(applicable=Phase.BOX, sig="(java.lang.Float)void")
   56.52 +    static <F> void m_float(F f) {}
   56.53 +
   56.54 +    @Candidate(applicable=Phase.BOX, mostSpecific=true)
   56.55 +    static void m_double(Double d) {}
   56.56 +    @Candidate(applicable=Phase.BOX, sig="(java.lang.Double)void")
   56.57 +    static <D> void m_double(D d) {}
   56.58 +
   56.59 +    @Candidate(applicable=Phase.BOX, mostSpecific=true)
   56.60 +    static void m_char(Character c) {}
   56.61 +    @Candidate(applicable=Phase.BOX, sig="(java.lang.Character)void")
   56.62 +    static <C> void m_char(C c) {}
   56.63 +
   56.64 +    @Candidate(applicable=Phase.BOX, mostSpecific=true)
   56.65 +    static void m_bool(Boolean z) {}
   56.66 +    @Candidate(applicable=Phase.BOX, sig="(java.lang.Boolean)void")
   56.67 +    static <Z> void m_bool(Z z) {}
   56.68 +
   56.69 +    {
   56.70 +        m_byte((byte)0);
   56.71 +        m_short((short)0);
   56.72 +        m_int(0);
   56.73 +        m_long(0L);
   56.74 +        m_float(0.0f);
   56.75 +        m_double(0.0);
   56.76 +        m_char('?');
   56.77 +        m_bool(false);
   56.78 +    }
   56.79 +}
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/test/tools/javac/resolve/tests/ReferenceOverVarargs.java	Fri Oct 28 17:49:36 2011 -0700
    57.3 @@ -0,0 +1,93 @@
    57.4 +/*
    57.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    57.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    57.7 + *
    57.8 + * This code is free software; you can redistribute it and/or modify it
    57.9 + * under the terms of the GNU General Public License version 2 only, as
   57.10 + * published by the Free Software Foundation.
   57.11 + *
   57.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   57.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   57.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   57.15 + * version 2 for more details (a copy is included in the LICENSE file that
   57.16 + * accompanied this code).
   57.17 + *
   57.18 + * You should have received a copy of the GNU General Public License version
   57.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   57.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   57.21 + *
   57.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   57.23 + * or visit www.oracle.com if you need additional information or have any
   57.24 + * questions.
   57.25 + */
   57.26 +
   57.27 +@TraceResolve
   57.28 +class ReferenceOverVarargs {
   57.29 +
   57.30 +    @Candidate(applicable=Phase.BOX, mostSpecific=true)
   57.31 +    static void m_byte(Byte b) {}
   57.32 +    @Candidate
   57.33 +    static void m_byte(byte... b) {}
   57.34 +    @Candidate
   57.35 +    static void m_byte(Byte... b) {}
   57.36 +
   57.37 +    @Candidate(applicable=Phase.BOX, mostSpecific=true)
   57.38 +    static void m_short(Short s) {}
   57.39 +    @Candidate
   57.40 +    static void m_short(short... s) {}
   57.41 +    @Candidate
   57.42 +    static void m_short(Short... s) {}
   57.43 +
   57.44 +    @Candidate(applicable=Phase.BOX, mostSpecific=true)
   57.45 +    static void m_int(Integer i) {}
   57.46 +    @Candidate
   57.47 +    static void m_int(int... i) {}
   57.48 +    @Candidate
   57.49 +    static void m_int(Integer... i) {}
   57.50 +
   57.51 +    @Candidate(applicable=Phase.BOX, mostSpecific=true)
   57.52 +    static void m_long(Long l) {}
   57.53 +    @Candidate
   57.54 +    static void m_long(long... l) {}
   57.55 +    @Candidate
   57.56 +    static void m_long(Long... l) {}
   57.57 +
   57.58 +    @Candidate(applicable=Phase.BOX, mostSpecific=true)
   57.59 +    static void m_float(Float f) {}
   57.60 +    @Candidate
   57.61 +    static void m_float(float... f) {}
   57.62 +    @Candidate
   57.63 +    static void m_float(Float... f) {}
   57.64 +
   57.65 +    @Candidate(applicable=Phase.BOX, mostSpecific=true)
   57.66 +    static void m_double(Double d) {}
   57.67 +    @Candidate
   57.68 +    static void m_double(double... d) {}
   57.69 +    @Candidate
   57.70 +    static void m_double(Double... d) {}
   57.71 +
   57.72 +    @Candidate(applicable=Phase.BOX, mostSpecific=true)
   57.73 +    static void m_char(Character c) {}
   57.74 +    @Candidate
   57.75 +    static void m_char(char... c) {}
   57.76 +    @Candidate
   57.77 +    static void m_char(Character... c) {}
   57.78 +
   57.79 +    @Candidate(applicable=Phase.BOX, mostSpecific=true)
   57.80 +    static void m_bool(Boolean z) {}
   57.81 +    @Candidate
   57.82 +    static void m_bool(boolean... z) {}
   57.83 +    @Candidate
   57.84 +    static void m_bool(Boolean... z) {}
   57.85 +
   57.86 +    {
   57.87 +        m_byte((byte)0);
   57.88 +        m_short((short)0);
   57.89 +        m_int(0);
   57.90 +        m_long(0L);
   57.91 +        m_float(0.0f);
   57.92 +        m_double(0.0);
   57.93 +        m_char('?');
   57.94 +        m_bool(false);
   57.95 +    }
   57.96 +}
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/test/tools/javac/resolve/tests/ReferenceOverload.java	Fri Oct 28 17:49:36 2011 -0700
    58.3 @@ -0,0 +1,95 @@
    58.4 +/*
    58.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    58.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    58.7 + *
    58.8 + * This code is free software; you can redistribute it and/or modify it
    58.9 + * under the terms of the GNU General Public License version 2 only, as
   58.10 + * published by the Free Software Foundation.
   58.11 + *
   58.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   58.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   58.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   58.15 + * version 2 for more details (a copy is included in the LICENSE file that
   58.16 + * accompanied this code).
   58.17 + *
   58.18 + * You should have received a copy of the GNU General Public License version
   58.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   58.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   58.21 + *
   58.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   58.23 + * or visit www.oracle.com if you need additional information or have any
   58.24 + * questions.
   58.25 + */
   58.26 +
   58.27 +@TraceResolve
   58.28 +class ReferenceOverload {
   58.29 +
   58.30 +    static class A {}
   58.31 +    static class B extends A {}
   58.32 +    static class C extends B {}
   58.33 +    static class D extends C {}
   58.34 +    static class E extends D {}
   58.35 +
   58.36 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   58.37 +    static void m_A(A a) {}
   58.38 +    @Candidate
   58.39 +    static void m_A(B a) {}
   58.40 +    @Candidate
   58.41 +    static void m_A(C a) {}
   58.42 +    @Candidate
   58.43 +    static void m_A(D a) {}
   58.44 +    @Candidate
   58.45 +    static void m_A(E a) {}
   58.46 +
   58.47 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   58.48 +    static void m_B(A b) {}
   58.49 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   58.50 +    static void m_B(B b) {}
   58.51 +    @Candidate
   58.52 +    static void m_B(C b) {}
   58.53 +    @Candidate
   58.54 +    static void m_B(D b) {}
   58.55 +    @Candidate
   58.56 +    static void m_B(E b) {}
   58.57 +
   58.58 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   58.59 +    static void m_C(A c) {}
   58.60 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   58.61 +    static void m_C(B c) {}
   58.62 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   58.63 +    static void m_C(C c) {}
   58.64 +    @Candidate
   58.65 +    static void m_C(D c) {}
   58.66 +    @Candidate
   58.67 +    static void m_C(E c) {}
   58.68 +
   58.69 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   58.70 +    static void m_D(A d) {}
   58.71 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   58.72 +    static void m_D(B d) {}
   58.73 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   58.74 +    static void m_D(C d) {}
   58.75 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   58.76 +    static void m_D(D d) {}
   58.77 +    @Candidate
   58.78 +    static void m_D(E d) {}
   58.79 +
   58.80 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   58.81 +    static void m_E(A e) {}
   58.82 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   58.83 +    static void m_E(B e) {}
   58.84 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   58.85 +    static void m_E(C e) {}
   58.86 +    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
   58.87 +    static void m_E(D e) {}
   58.88 +    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
   58.89 +    static void m_E(E e) {}
   58.90 +
   58.91 +    {
   58.92 +        m_A((A)null);
   58.93 +        m_B((B)null);
   58.94 +        m_C((C)null);
   58.95 +        m_D((D)null);
   58.96 +        m_E((E)null);
   58.97 +    }
   58.98 +}
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/test/tools/javac/tree/DocCommentToplevelTest.java	Fri Oct 28 17:49:36 2011 -0700
    59.3 @@ -0,0 +1,196 @@
    59.4 +/*
    59.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    59.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    59.7 + *
    59.8 + * This code is free software; you can redistribute it and/or modify it
    59.9 + * under the terms of the GNU General Public License version 2 only, as
   59.10 + * published by the Free Software Foundation.
   59.11 + *
   59.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   59.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   59.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   59.15 + * version 2 for more details (a copy is included in the LICENSE file that
   59.16 + * accompanied this code).
   59.17 + *
   59.18 + * You should have received a copy of the GNU General Public License version
   59.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   59.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   59.21 + *
   59.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   59.23 + * or visit www.oracle.com if you need additional information or have any
   59.24 + * questions.
   59.25 + */
   59.26 +
   59.27 +/*
   59.28 + * @test
   59.29 + * @bug 7096014
   59.30 + * @summary Javac tokens should retain state
   59.31 + */
   59.32 +
   59.33 +import com.sun.source.tree.*;
   59.34 +import com.sun.source.util.*;
   59.35 +import com.sun.tools.javac.tree.JCTree;
   59.36 +
   59.37 +import java.net.URI;
   59.38 +import java.util.*;
   59.39 +import javax.tools.*;
   59.40 +
   59.41 +
   59.42 +public class DocCommentToplevelTest {
   59.43 +
   59.44 +    enum PackageKind {
   59.45 +        HAS_PKG("package pkg;"),
   59.46 +        NO_PKG("");
   59.47 +
   59.48 +        String pkgStr;
   59.49 +
   59.50 +        PackageKind(String pkgStr) {
   59.51 +            this.pkgStr = pkgStr;
   59.52 +        }
   59.53 +    }
   59.54 +
   59.55 +    enum ImportKind {
   59.56 +        ZERO(""),
   59.57 +        ONE("import java.lang.*;"),
   59.58 +        TWO("import java.lang.*; import java.util.*;");
   59.59 +
   59.60 +        String importStr;
   59.61 +
   59.62 +        ImportKind(String importStr) {
   59.63 +            this.importStr = importStr;
   59.64 +        }
   59.65 +    }
   59.66 +
   59.67 +    enum ModifierKind {
   59.68 +        DEFAULT(""),
   59.69 +        PUBLIC("public");
   59.70 +
   59.71 +        String modStr;
   59.72 +
   59.73 +        ModifierKind(String modStr) {
   59.74 +            this.modStr = modStr;
   59.75 +        }
   59.76 +    }
   59.77 +
   59.78 +    enum ToplevelDocKind {
   59.79 +        HAS_DOC("/** Toplevel! */"),
   59.80 +        NO_DOC("");
   59.81 +
   59.82 +        String docStr;
   59.83 +
   59.84 +        ToplevelDocKind(String docStr) {
   59.85 +            this.docStr = docStr;
   59.86 +        }
   59.87 +    }
   59.88 +
   59.89 +    static int errors;
   59.90 +    static int checks;
   59.91 +
   59.92 +    public static void main(String... args) throws Exception {
   59.93 +        //create default shared JavaCompiler - reused across multiple compilations
   59.94 +        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
   59.95 +        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
   59.96 +
   59.97 +        for (PackageKind pk : PackageKind.values()) {
   59.98 +            for (ImportKind ik : ImportKind.values()) {
   59.99 +                for (ModifierKind mk1 : ModifierKind.values()) {
  59.100 +                    for (ModifierKind mk2 : ModifierKind.values()) {
  59.101 +                        for (ToplevelDocKind tdk : ToplevelDocKind.values()) {
  59.102 +                            new DocCommentToplevelTest(pk, ik, mk1, mk2, tdk).run(comp, fm);
  59.103 +                        }
  59.104 +                    }
  59.105 +                }
  59.106 +            }
  59.107 +        }
  59.108 +
  59.109 +        if (errors > 0)
  59.110 +            throw new AssertionError(errors + " errors found");
  59.111 +
  59.112 +        System.out.println(checks + " checks were made");
  59.113 +    }
  59.114 +
  59.115 +    PackageKind pk;
  59.116 +    ImportKind ik;
  59.117 +    ModifierKind mk1;
  59.118 +    ModifierKind mk2;
  59.119 +    ToplevelDocKind tdk;
  59.120 +    JavaSource source;
  59.121 +
  59.122 +    DocCommentToplevelTest(PackageKind pk, ImportKind ik, ModifierKind mk1, ModifierKind mk2, ToplevelDocKind tdk) {
  59.123 +        this.pk = pk;
  59.124 +        this.ik = ik;
  59.125 +        this.mk1 = mk1;
  59.126 +        this.mk2 = mk2;
  59.127 +        this.tdk = tdk;
  59.128 +        source = new JavaSource();
  59.129 +    }
  59.130 +
  59.131 +    void run(JavaCompiler comp, JavaFileManager fm) throws Exception {
  59.132 +        JavacTask task = (JavacTask)comp.getTask(null, fm, null, Arrays.asList("-printsource"), null, Arrays.asList(source));
  59.133 +        for (CompilationUnitTree cu: task.parse()) {
  59.134 +            check(cu);
  59.135 +        }
  59.136 +    }
  59.137 +
  59.138 +    void check(CompilationUnitTree cu) {
  59.139 +        checks++;
  59.140 +
  59.141 +        new TreeScanner<ClassTree,Void>() {
  59.142 +
  59.143 +            Map<JCTree, String> docComments;
  59.144 +
  59.145 +            @Override
  59.146 +            public ClassTree visitCompilationUnit(CompilationUnitTree node, Void unused) {
  59.147 +                docComments = ((JCTree.JCCompilationUnit)node).docComments;
  59.148 +                boolean expectedComment = tdk == ToplevelDocKind.HAS_DOC &&
  59.149 +                        (pk != PackageKind.NO_PKG || ik != ImportKind.ZERO);
  59.150 +                boolean foundComment = docComments.get(node) != null;
  59.151 +                if (expectedComment != foundComment) {
  59.152 +                    error("Unexpected comment " + docComments.get(node) + " on toplevel");
  59.153 +                }
  59.154 +                return super.visitCompilationUnit(node, null);
  59.155 +            }
  59.156 +
  59.157 +            @Override
  59.158 +            public ClassTree visitClass(ClassTree node, Void unused) {
  59.159 +                boolean expectedComment = tdk == ToplevelDocKind.HAS_DOC &&
  59.160 +                        pk == PackageKind.NO_PKG && ik == ImportKind.ZERO &&
  59.161 +                        node.getSimpleName().toString().equals("First");
  59.162 +                boolean foundComment = docComments.get(node) != null;
  59.163 +                if (expectedComment != foundComment) {
  59.164 +                    error("Unexpected comment " + docComments.get(node) + " on class " + node.getSimpleName());
  59.165 +                }
  59.166 +                return super.visitClass(node, unused);
  59.167 +            }
  59.168 +        }.scan(cu, null);
  59.169 +    }
  59.170 +
  59.171 +    void error(String msg) {
  59.172 +        System.err.println("Error: " + msg);
  59.173 +        System.err.println("Source: " + source.source);
  59.174 +        errors++;
  59.175 +    }
  59.176 +
  59.177 +    class JavaSource extends SimpleJavaFileObject {
  59.178 +
  59.179 +        String template = "#D\n#P\n#I\n" +
  59.180 +                          "#M1 class First { }\n" +
  59.181 +                          "#M2 class Second { }\n";
  59.182 +
  59.183 +        String source;
  59.184 +
  59.185 +        public JavaSource() {
  59.186 +            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
  59.187 +            source = template.replace("#P", pk.pkgStr)
  59.188 +                             .replace("#I", ik.importStr)
  59.189 +                             .replace("#M1", mk1.modStr)
  59.190 +                             .replace("#M2", mk2.modStr)
  59.191 +                             .replace("#D", tdk.docStr);
  59.192 +        }
  59.193 +
  59.194 +        @Override
  59.195 +        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
  59.196 +            return source;
  59.197 +        }
  59.198 +    }
  59.199 +}
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/test/tools/javac/varargs/7097436/T7097436.java	Fri Oct 28 17:49:36 2011 -0700
    60.3 @@ -0,0 +1,18 @@
    60.4 +/*
    60.5 + * @test /nodynamiccopyright/
    60.6 + * @bug     7097436
    60.7 + * @summary  ClassCastException occurs in assignment expressions without any heap pollutions
    60.8 + * @compile/fail/ref=T7097436.out -Xlint:varargs -Werror -XDrawDiagnostics T7097436.java
    60.9 + */
   60.10 +
   60.11 +import java.util.List;
   60.12 +
   60.13 +class T7097436 {
   60.14 +    @SafeVarargs
   60.15 +    static void m(List<String>... ls) {
   60.16 +        Object o = ls; //warning
   60.17 +        Object[] oArr = ls; //warning
   60.18 +        String s = ls; // no warning
   60.19 +        Integer[] iArr = ls; // no warning
   60.20 +    }
   60.21 +}
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/test/tools/javac/varargs/7097436/T7097436.out	Fri Oct 28 17:49:36 2011 -0700
    61.3 @@ -0,0 +1,6 @@
    61.4 +T7097436.java:13:20: compiler.warn.varargs.unsafe.use.varargs.param: ls
    61.5 +T7097436.java:14:25: compiler.warn.varargs.unsafe.use.varargs.param: ls
    61.6 +T7097436.java:15:20: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.util.List<java.lang.String>[], java.lang.String
    61.7 +T7097436.java:16:26: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.util.List<java.lang.String>[], java.lang.Integer[]
    61.8 +2 errors
    61.9 +2 warnings
    62.1 --- a/test/tools/javac/varargs/warning/Warn5.java	Thu Oct 27 13:54:50 2011 -0700
    62.2 +++ b/test/tools/javac/varargs/warning/Warn5.java	Fri Oct 28 17:49:36 2011 -0700
    62.3 @@ -23,7 +23,7 @@
    62.4  
    62.5  /**
    62.6   * @test
    62.7 - * @bug     6993978
    62.8 + * @bug     6993978 7097436
    62.9   * @summary Project Coin: Annotation to reduce varargs warnings
   62.10   * @author  mcimadamore
   62.11   * @run main Warn5
   62.12 @@ -31,8 +31,8 @@
   62.13  import com.sun.source.util.JavacTask;
   62.14  import com.sun.tools.javac.api.JavacTool;
   62.15  import java.net.URI;
   62.16 -import java.util.ArrayList;
   62.17  import java.util.Arrays;
   62.18 +import java.util.EnumSet;
   62.19  import javax.tools.Diagnostic;
   62.20  import javax.tools.JavaCompiler;
   62.21  import javax.tools.JavaFileObject;
   62.22 @@ -95,7 +95,6 @@
   62.23          METHOD("void m"),
   62.24          CONSTRUCTOR("Test");
   62.25  
   62.26 -
   62.27          String name;
   62.28  
   62.29          MethodKind(String name) {
   62.30 @@ -155,7 +154,124 @@
   62.31          }
   62.32      }
   62.33  
   62.34 -    static class JavaSource extends SimpleJavaFileObject {
   62.35 +    enum WarningKind {
   62.36 +        UNSAFE_BODY,
   62.37 +        UNSAFE_DECL,
   62.38 +        MALFORMED_SAFEVARARGS,
   62.39 +        REDUNDANT_SAFEVARARGS;
   62.40 +    }
   62.41 +
   62.42 +    // Create a single file manager and reuse it for each compile to save time.
   62.43 +    static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
   62.44 +
   62.45 +    public static void main(String... args) throws Exception {
   62.46 +        for (SourceLevel sourceLevel : SourceLevel.values()) {
   62.47 +            for (XlintOption xlint : XlintOption.values()) {
   62.48 +                for (TrustMe trustMe : TrustMe.values()) {
   62.49 +                    for (SuppressLevel suppressLevel : SuppressLevel.values()) {
   62.50 +                        for (ModifierKind modKind : ModifierKind.values()) {
   62.51 +                            for (MethodKind methKind : MethodKind.values()) {
   62.52 +                                for (SignatureKind sig : SignatureKind.values()) {
   62.53 +                                    for (BodyKind body : BodyKind.values()) {
   62.54 +                                        new Warn5(sourceLevel,
   62.55 +                                                xlint,
   62.56 +                                                trustMe,
   62.57 +                                                suppressLevel,
   62.58 +                                                modKind,
   62.59 +                                                methKind,
   62.60 +                                                sig,
   62.61 +                                                body).test();
   62.62 +                                    }
   62.63 +                                }
   62.64 +                            }
   62.65 +                        }
   62.66 +                    }
   62.67 +                }
   62.68 +            }
   62.69 +        }
   62.70 +    }
   62.71 +
   62.72 +    final SourceLevel sourceLevel;
   62.73 +    final XlintOption xlint;
   62.74 +    final TrustMe trustMe;
   62.75 +    final SuppressLevel suppressLevel;
   62.76 +    final ModifierKind modKind;
   62.77 +    final MethodKind methKind;
   62.78 +    final SignatureKind sig;
   62.79 +    final BodyKind body;
   62.80 +    final JavaSource source;
   62.81 +    final DiagnosticChecker dc;
   62.82 +
   62.83 +    public Warn5(SourceLevel sourceLevel, XlintOption xlint, TrustMe trustMe, SuppressLevel suppressLevel, ModifierKind modKind, MethodKind methKind, SignatureKind sig, BodyKind body) {
   62.84 +        this.sourceLevel = sourceLevel;
   62.85 +        this.xlint = xlint;
   62.86 +        this.trustMe = trustMe;
   62.87 +        this.suppressLevel = suppressLevel;
   62.88 +        this.modKind = modKind;
   62.89 +        this.methKind = methKind;
   62.90 +        this.sig = sig;
   62.91 +        this.body = body;
   62.92 +        this.source = new JavaSource();
   62.93 +        this.dc = new DiagnosticChecker();
   62.94 +    }
   62.95 +
   62.96 +    void test() throws Exception {
   62.97 +        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
   62.98 +        JavacTask ct = (JavacTask)tool.getTask(null, fm, dc,
   62.99 +                Arrays.asList(xlint.getXlintOption(), "-source", sourceLevel.sourceKey), null, Arrays.asList(source));
  62.100 +        ct.analyze();
  62.101 +        check();
  62.102 +    }
  62.103 +
  62.104 +    void check() {
  62.105 +
  62.106 +        EnumSet<WarningKind> expectedWarnings = EnumSet.noneOf(WarningKind.class);
  62.107 +
  62.108 +        if (sourceLevel == SourceLevel.JDK_7 &&
  62.109 +                trustMe == TrustMe.TRUST &&
  62.110 +                suppressLevel != SuppressLevel.VARARGS &&
  62.111 +                xlint != XlintOption.NONE &&
  62.112 +                sig.isVarargs && !sig.isReifiableArg && body.hasAliasing &&
  62.113 +                (methKind == MethodKind.CONSTRUCTOR || (methKind == MethodKind.METHOD && modKind != ModifierKind.NONE))) {
  62.114 +            expectedWarnings.add(WarningKind.UNSAFE_BODY);
  62.115 +        }
  62.116 +
  62.117 +        if (sourceLevel == SourceLevel.JDK_7 &&
  62.118 +                trustMe == TrustMe.DONT_TRUST &&
  62.119 +                sig.isVarargs &&
  62.120 +                !sig.isReifiableArg &&
  62.121 +                xlint == XlintOption.ALL) {
  62.122 +            expectedWarnings.add(WarningKind.UNSAFE_DECL);
  62.123 +        }
  62.124 +
  62.125 +        if (sourceLevel == SourceLevel.JDK_7 &&
  62.126 +                trustMe == TrustMe.TRUST &&
  62.127 +                (!sig.isVarargs ||
  62.128 +                (modKind == ModifierKind.NONE && methKind == MethodKind.METHOD))) {
  62.129 +            expectedWarnings.add(WarningKind.MALFORMED_SAFEVARARGS);
  62.130 +        }
  62.131 +
  62.132 +        if (sourceLevel == SourceLevel.JDK_7 &&
  62.133 +                trustMe == TrustMe.TRUST &&
  62.134 +                xlint != XlintOption.NONE &&
  62.135 +                suppressLevel != SuppressLevel.VARARGS &&
  62.136 +                (modKind != ModifierKind.NONE || methKind == MethodKind.CONSTRUCTOR) &&
  62.137 +                sig.isVarargs &&
  62.138 +                sig.isReifiableArg) {
  62.139 +            expectedWarnings.add(WarningKind.REDUNDANT_SAFEVARARGS);
  62.140 +        }
  62.141 +
  62.142 +        if (!expectedWarnings.containsAll(dc.warnings) ||
  62.143 +                !dc.warnings.containsAll(expectedWarnings)) {
  62.144 +            throw new Error("invalid diagnostics for source:\n" +
  62.145 +                    source.getCharContent(true) +
  62.146 +                    "\nOptions: " + xlint.getXlintOption() +
  62.147 +                    "\nExpected warnings: " + expectedWarnings +
  62.148 +                    "\nFound warnings: " + dc.warnings);
  62.149 +        }
  62.150 +    }
  62.151 +
  62.152 +    class JavaSource extends SimpleJavaFileObject {
  62.153  
  62.154          String template = "import com.sun.tools.javac.api.*;\n" +
  62.155                            "import java.util.List;\n" +
  62.156 @@ -167,12 +283,11 @@
  62.157  
  62.158          String source;
  62.159  
  62.160 -        public JavaSource(TrustMe trustMe, SuppressLevel suppressLevel, ModifierKind modKind,
  62.161 -                MethodKind methKind, SignatureKind meth, BodyKind body) {
  62.162 +        public JavaSource() {
  62.163              super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
  62.164              source = template.replace("#T", trustMe.anno).
  62.165                      replace("#S", suppressLevel.getSuppressAnno()).
  62.166 -                    replace("#M", meth.getSignature(modKind, methKind)).
  62.167 +                    replace("#M", sig.getSignature(modKind, methKind)).
  62.168                      replace("#B", body.body);
  62.169          }
  62.170  
  62.171 @@ -182,117 +297,34 @@
  62.172          }
  62.173      }
  62.174  
  62.175 -    public static void main(String... args) throws Exception {
  62.176 -        for (SourceLevel sourceLevel : SourceLevel.values()) {
  62.177 -            for (XlintOption xlint : XlintOption.values()) {
  62.178 -                for (TrustMe trustMe : TrustMe.values()) {
  62.179 -                    for (SuppressLevel suppressLevel : SuppressLevel.values()) {
  62.180 -                        for (ModifierKind modKind : ModifierKind.values()) {
  62.181 -                            for (MethodKind methKind : MethodKind.values()) {
  62.182 -                                for (SignatureKind sig : SignatureKind.values()) {
  62.183 -                                    for (BodyKind body : BodyKind.values()) {
  62.184 -                                        test(sourceLevel,
  62.185 -                                                xlint,
  62.186 -                                                trustMe,
  62.187 -                                                suppressLevel,
  62.188 -                                                modKind,
  62.189 -                                                methKind,
  62.190 -                                                sig,
  62.191 -                                                body);
  62.192 -                                    }
  62.193 -                                }
  62.194 -                            }
  62.195 -                        }
  62.196 -                    }
  62.197 -                }
  62.198 -            }
  62.199 -        }
  62.200 -    }
  62.201 +    class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
  62.202  
  62.203 -    // Create a single file manager and reuse it for each compile to save time.
  62.204 -    static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
  62.205 -
  62.206 -    static void test(SourceLevel sourceLevel, XlintOption xlint, TrustMe trustMe, SuppressLevel suppressLevel,
  62.207 -            ModifierKind modKind, MethodKind methKind, SignatureKind sig, BodyKind body) throws Exception {
  62.208 -        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
  62.209 -        JavaSource source = new JavaSource(trustMe, suppressLevel, modKind, methKind, sig, body);
  62.210 -        DiagnosticChecker dc = new DiagnosticChecker();
  62.211 -        JavacTask ct = (JavacTask)tool.getTask(null, fm, dc,
  62.212 -                Arrays.asList(xlint.getXlintOption(), "-source", sourceLevel.sourceKey), null, Arrays.asList(source));
  62.213 -        ct.analyze();
  62.214 -        check(sourceLevel, dc, source, xlint, trustMe,
  62.215 -                suppressLevel, modKind, methKind, sig, body);
  62.216 -    }
  62.217 -
  62.218 -    static void check(SourceLevel sourceLevel, DiagnosticChecker dc, JavaSource source,
  62.219 -            XlintOption xlint, TrustMe trustMe, SuppressLevel suppressLevel, ModifierKind modKind,
  62.220 -            MethodKind methKind, SignatureKind meth, BodyKind body) {
  62.221 -
  62.222 -        boolean hasPotentiallyUnsafeBody = sourceLevel == SourceLevel.JDK_7 &&
  62.223 -                trustMe == TrustMe.TRUST &&
  62.224 -                suppressLevel != SuppressLevel.VARARGS &&
  62.225 -                xlint != XlintOption.NONE &&
  62.226 -                meth.isVarargs && !meth.isReifiableArg && body.hasAliasing &&
  62.227 -                (methKind == MethodKind.CONSTRUCTOR || (methKind == MethodKind.METHOD && modKind != ModifierKind.NONE));
  62.228 -
  62.229 -        boolean hasPotentiallyPollutingDecl = sourceLevel == SourceLevel.JDK_7 &&
  62.230 -                trustMe == TrustMe.DONT_TRUST &&
  62.231 -                meth.isVarargs &&
  62.232 -                !meth.isReifiableArg &&
  62.233 -                xlint == XlintOption.ALL;
  62.234 -
  62.235 -        boolean hasMalformedAnnoInDecl = sourceLevel == SourceLevel.JDK_7 &&
  62.236 -                trustMe == TrustMe.TRUST &&
  62.237 -                (!meth.isVarargs ||
  62.238 -                (modKind == ModifierKind.NONE && methKind == MethodKind.METHOD));
  62.239 -
  62.240 -        boolean hasRedundantAnnoInDecl = sourceLevel == SourceLevel.JDK_7 &&
  62.241 -                trustMe == TrustMe.TRUST &&
  62.242 -                xlint != XlintOption.NONE &&
  62.243 -                suppressLevel != SuppressLevel.VARARGS &&
  62.244 -                (modKind != ModifierKind.NONE || methKind == MethodKind.CONSTRUCTOR) &&
  62.245 -                meth.isVarargs &&
  62.246 -                meth.isReifiableArg;
  62.247 -
  62.248 -        if (hasPotentiallyUnsafeBody != dc.hasPotentiallyUnsafeBody ||
  62.249 -                hasPotentiallyPollutingDecl != dc.hasPotentiallyPollutingDecl ||
  62.250 -                hasMalformedAnnoInDecl != dc.hasMalformedAnnoInDecl ||
  62.251 -                hasRedundantAnnoInDecl != dc.hasRedundantAnnoInDecl) {
  62.252 -            throw new Error("invalid diagnostics for source:\n" +
  62.253 -                    source.getCharContent(true) +
  62.254 -                    "\nOptions: " + xlint.getXlintOption() +
  62.255 -                    "\nExpected potentially unsafe body warning: " + hasPotentiallyUnsafeBody +
  62.256 -                    "\nExpected potentially polluting decl warning: " + hasPotentiallyPollutingDecl +
  62.257 -                    "\nExpected malformed anno error: " + hasMalformedAnnoInDecl +
  62.258 -                    "\nExpected redundant anno warning: " + hasRedundantAnnoInDecl +
  62.259 -                    "\nFound potentially unsafe body warning: " + dc.hasPotentiallyUnsafeBody +
  62.260 -                    "\nFound potentially polluting decl warning: " + dc.hasPotentiallyPollutingDecl +
  62.261 -                    "\nFound malformed anno error: " + dc.hasMalformedAnnoInDecl +
  62.262 -                    "\nFound redundant anno warning: " + dc.hasRedundantAnnoInDecl);
  62.263 -        }
  62.264 -    }
  62.265 -
  62.266 -    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
  62.267 -
  62.268 -        boolean hasPotentiallyUnsafeBody = false;
  62.269 -        boolean hasPotentiallyPollutingDecl = false;
  62.270 -        boolean hasMalformedAnnoInDecl = false;
  62.271 -        boolean hasRedundantAnnoInDecl = false;
  62.272 +        EnumSet<WarningKind> warnings = EnumSet.noneOf(WarningKind.class);
  62.273  
  62.274          public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
  62.275              if (diagnostic.getKind() == Diagnostic.Kind.WARNING) {
  62.276                      if (diagnostic.getCode().contains("unsafe.use.varargs.param")) {
  62.277 -                        hasPotentiallyUnsafeBody = true;
  62.278 +                        setWarning(WarningKind.UNSAFE_BODY);
  62.279                      } else if (diagnostic.getCode().contains("redundant.trustme")) {
  62.280 -                        hasRedundantAnnoInDecl = true;
  62.281 +                        setWarning(WarningKind.REDUNDANT_SAFEVARARGS);
  62.282                      }
  62.283              } else if (diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING &&
  62.284                      diagnostic.getCode().contains("varargs.non.reifiable.type")) {
  62.285 -                hasPotentiallyPollutingDecl = true;
  62.286 +                setWarning(WarningKind.UNSAFE_DECL);
  62.287              } else if (diagnostic.getKind() == Diagnostic.Kind.ERROR &&
  62.288                      diagnostic.getCode().contains("invalid.trustme")) {
  62.289 -                hasMalformedAnnoInDecl = true;
  62.290 +                setWarning(WarningKind.MALFORMED_SAFEVARARGS);
  62.291              }
  62.292          }
  62.293 +
  62.294 +        void setWarning(WarningKind wk) {
  62.295 +            if (!warnings.add(wk)) {
  62.296 +                throw new AssertionError("Duplicate warning of kind " + wk + " in source:\n" + source);
  62.297 +            }
  62.298 +        }
  62.299 +
  62.300 +        boolean hasWarning(WarningKind wk) {
  62.301 +            return warnings.contains(wk);
  62.302 +        }
  62.303      }
  62.304  }

mercurial