Fri, 28 Oct 2011 17:49:36 -0700
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 }