提交 3345c06c 编写于 作者: L lana

Merge

......@@ -107,7 +107,8 @@ javac.includes = \
javax/annotation/processing/ \
javax/lang/model/ \
javax/tools/ \
com/sun/source/ com/sun/tools/javac/
com/sun/source/ \
com/sun/tools/javac/
javac.tests = \
tools/javac
......
......@@ -322,6 +322,35 @@
datafile="${build.coverage.dir}/cobertura.ser"/>
</target>
<target name="diags-examples" depends="build-javac">
<!-- can override the following on the command line if desired. -->
<property name="diags.examples.out" location="${build.dir}/diag-examples/diags-examples.html"/>
<mkdir dir="${build.dir}/diag-examples/classes"/>
<javac fork="true"
executable="${dist.bin.dir}/javac"
srcdir="test/tools/javac/diags"
destdir="${build.dir}/diag-examples/classes"
includes="Example.java,FileManager.java,HTMLWriter.java,RunExamples.java"
sourcepath=""
classpath="${dist.lib.dir}/javac.jar"
includeAntRuntime="no"
debug="${javac.debug}"
debuglevel="${javac.debuglevel}"/>
<java fork="true"
jvm="${target.java.home}/bin/java"
dir="test/tools/javac/diags"
classpath="${build.dir}/diag-examples/classes;${dist.lib.dir}/javac.jar"
classname="RunExamples">
<arg value="-examples"/>
<arg value="examples"/>
<arg value="-o"/>
<arg file="${diags.examples.out}"/>
<arg value="-showFiles"/>
<arg value="-title"/>
<arg value="Examples of javac diagnostics"/>
</java>
</target>
<!--
**** Debugging/diagnostic targets.
......
......@@ -49,4 +49,5 @@ public interface TryTree extends StatementTree {
BlockTree getBlock();
List<? extends CatchTree> getCatches();
BlockTree getFinallyBlock();
List<? extends Tree> getResources();
}
......@@ -209,7 +209,8 @@ public class TreeScanner<R,P> implements TreeVisitor<R,P> {
}
public R visitTry(TryTree node, P p) {
R r = scan(node.getBlock(), p);
R r = scan(node.getResources(), p);
r = scanAndReduce(node.getBlock(), p, r);
r = scanAndReduce(node.getCatches(), p, r);
r = scanAndReduce(node.getFinallyBlock(), p, r);
return r;
......
......@@ -119,6 +119,7 @@ public class Lint
this.suppressedValues = other.suppressedValues.clone();
}
@Override
public String toString() {
return "Lint:[values" + values + " suppressedValues" + suppressedValues + "]";
}
......@@ -208,7 +209,12 @@ public class Lint
/**
* Warn about potentially unsafe vararg methods
*/
VARARGS("varargs");
VARARGS("varargs"),
/**
* Warn about arm resources
*/
ARM("arm");
LintCategory(String option) {
this(option, false);
......
......@@ -159,6 +159,9 @@ public enum Source {
public boolean enforceMandatoryWarnings() {
return compareTo(JDK1_5) >= 0;
}
public boolean allowTryWithResources() {
return compareTo(JDK1_7) >= 0;
}
public boolean allowTypeAnnotations() {
return compareTo(JDK1_7) >= 0;
}
......
......@@ -993,12 +993,17 @@ public abstract class Symbol implements Element {
return data == ElementKind.EXCEPTION_PARAMETER;
}
public boolean isResourceVariable() {
return data == ElementKind.RESOURCE_VARIABLE;
}
public Object getConstValue() {
// TODO: Consider if getConstValue and getConstantValue can be collapsed
if (data == ElementKind.EXCEPTION_PARAMETER) {
if (data == ElementKind.EXCEPTION_PARAMETER ||
data == ElementKind.RESOURCE_VARIABLE) {
return null;
} else if (data instanceof Callable<?>) {
// In this case, this is final a variable, with an as
// In this case, this is a final variable, with an as
// yet unevaluated initializer.
Callable<?> eval = (Callable<?>)data;
data = null; // to make sure we don't evaluate this twice.
......
......@@ -148,6 +148,7 @@ public class Symtab {
public final Type inheritedType;
public final Type proprietaryType;
public final Type systemType;
public final Type autoCloseableType;
/** The symbol representing the length field of an array.
*/
......@@ -159,6 +160,9 @@ public class Symtab {
/** The symbol representing the final finalize method on enums */
public final MethodSymbol enumFinalFinalize;
/** The symbol representing the close method on TWR AutoCloseable type */
public final MethodSymbol autoCloseableClose;
/** The predefined type that belongs to a tag.
*/
public final Type[] typeOfTag = new Type[TypeTags.TypeTagCount];
......@@ -444,6 +448,12 @@ public class Symtab {
suppressWarningsType = enterClass("java.lang.SuppressWarnings");
inheritedType = enterClass("java.lang.annotation.Inherited");
systemType = enterClass("java.lang.System");
autoCloseableType = enterClass("java.lang.AutoCloseable");
autoCloseableClose = new MethodSymbol(PUBLIC,
names.close,
new MethodType(List.<Type>nil(), voidType,
List.of(exceptionType), methodClass),
autoCloseableType.tsym);
synthesizeEmptyInterfaceIfMissing(cloneableType);
synthesizeEmptyInterfaceIfMissing(serializableType);
......
......@@ -192,7 +192,7 @@ public class Attr extends JCTree.Visitor {
Type check(JCTree tree, Type owntype, int ownkind, int pkind, Type pt) {
if (owntype.tag != ERROR && pt.tag != METHOD && pt.tag != FORALL) {
if ((ownkind & ~pkind) == 0) {
owntype = chk.checkType(tree.pos(), owntype, pt);
owntype = chk.checkType(tree.pos(), owntype, pt, errKey);
} else {
log.error(tree.pos(), "unexpected.type",
kindNames(pkind),
......@@ -239,7 +239,11 @@ public class Attr extends JCTree.Visitor {
!((base == null ||
(base.getTag() == JCTree.IDENT && TreeInfo.name(base) == names._this)) &&
isAssignableAsBlankFinal(v, env)))) {
log.error(pos, "cant.assign.val.to.final.var", v);
if (v.isResourceVariable()) { //TWR resource
log.error(pos, "twr.resource.may.not.be.assigned", v);
} else {
log.error(pos, "cant.assign.val.to.final.var", v);
}
}
}
......@@ -372,6 +376,10 @@ public class Attr extends JCTree.Visitor {
*/
Type pt;
/** Visitor argument: the error key to be generated when a type error occurs
*/
String errKey;
/** Visitor result: the computed type.
*/
Type result;
......@@ -385,13 +393,19 @@ public class Attr extends JCTree.Visitor {
* @param pt The prototype visitor argument.
*/
Type attribTree(JCTree tree, Env<AttrContext> env, int pkind, Type pt) {
return attribTree(tree, env, pkind, pt, "incompatible.types");
}
Type attribTree(JCTree tree, Env<AttrContext> env, int pkind, Type pt, String errKey) {
Env<AttrContext> prevEnv = this.env;
int prevPkind = this.pkind;
Type prevPt = this.pt;
String prevErrKey = this.errKey;
try {
this.env = env;
this.pkind = pkind;
this.pt = pt;
this.errKey = errKey;
tree.accept(this);
if (tree == breakTree)
throw new BreakAttr(env);
......@@ -403,6 +417,7 @@ public class Attr extends JCTree.Visitor {
this.env = prevEnv;
this.pkind = prevPkind;
this.pt = prevPt;
this.errKey = prevErrKey;
}
}
......@@ -412,6 +427,10 @@ public class Attr extends JCTree.Visitor {
return attribTree(tree, env, VAL, pt.tag != ERROR ? pt : Type.noType);
}
public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt, String key) {
return attribTree(tree, env, VAL, pt.tag != ERROR ? pt : Type.noType, key);
}
/** Derived visitor method: attribute an expression tree with
* no constraints on the computed type.
*/
......@@ -976,14 +995,34 @@ public class Attr extends JCTree.Visitor {
}
public void visitTry(JCTry tree) {
// Create a new local environment with a local
Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
boolean isTryWithResource = tree.resources.nonEmpty();
// Create a nested environment for attributing the try block if needed
Env<AttrContext> tryEnv = isTryWithResource ?
env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
localEnv;
// Attribute resource declarations
for (JCTree resource : tree.resources) {
if (resource.getTag() == JCTree.VARDEF) {
attribStat(resource, tryEnv);
chk.checkType(resource, resource.type, syms.autoCloseableType, "twr.not.applicable.to.type");
VarSymbol var = (VarSymbol)TreeInfo.symbolFor(resource);
var.setData(ElementKind.RESOURCE_VARIABLE);
} else {
attribExpr(resource, tryEnv, syms.autoCloseableType, "twr.not.applicable.to.type");
}
}
// Attribute body
attribStat(tree.body, env.dup(tree, env.info.dup()));
attribStat(tree.body, tryEnv);
if (isTryWithResource)
tryEnv.info.scope.leave();
// Attribute catch clauses
for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
JCCatch c = l.head;
Env<AttrContext> catchEnv =
env.dup(c, env.info.dup(env.info.scope.dup()));
localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup()));
Type ctype = attribStat(c.param, catchEnv);
if (TreeInfo.isMultiCatch(c)) {
//check that multi-catch parameter is marked as final
......@@ -1003,7 +1042,9 @@ public class Attr extends JCTree.Visitor {
}
// Attribute finalizer
if (tree.finalizer != null) attribStat(tree.finalizer, env);
if (tree.finalizer != null) attribStat(tree.finalizer, localEnv);
localEnv.info.scope.leave();
result = null;
}
......@@ -1653,8 +1694,22 @@ public class Attr extends JCTree.Visitor {
//if the type of the instance creation expression is an interface
//skip the method resolution step (JLS 15.12.2.7). The type to be
//inferred is of the kind <X1,X2, ... Xn>C<X1,X2, ... Xn>
clazztype = new ForAll(clazztype.tsym.type.allparams(),
clazztype.tsym.type);
clazztype = new ForAll(clazztype.tsym.type.allparams(), clazztype.tsym.type) {
@Override
public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
switch (ck) {
case EXTENDS: return types.getBounds(tv);
default: return List.nil();
}
}
@Override
public Type inst(List<Type> inferred, Types types) throws Infer.NoInstanceException {
// check that inferred bounds conform to their bounds
infer.checkWithinBounds(tvars,
types.subst(tvars, tvars, inferred), Warner.noWarnings);
return super.inst(inferred, types);
}
};
} else {
//if the type of the instance creation expression is a class type
//apply method resolution inference (JLS 15.12.2.7). The return type
......@@ -2139,6 +2194,15 @@ public class Attr extends JCTree.Visitor {
checkAssignable(tree.pos(), v, tree.selected, env);
}
if (sitesym != null &&
sitesym.kind == VAR &&
((VarSymbol)sitesym).isResourceVariable() &&
sym.kind == MTH &&
sym.overrides(syms.autoCloseableClose, sitesym.type.tsym, types, true) &&
env.info.lint.isEnabled(Lint.LintCategory.ARM)) {
log.warning(tree, "twr.explicit.close.call");
}
// Disallow selecting a type from an expression
if (isType(sym) && (sitesym==null || (sitesym.kind&(TYP|PCK)) == 0)) {
tree.type = check(tree.selected, pt,
......@@ -3061,7 +3125,8 @@ public class Attr extends JCTree.Visitor {
Scope.Entry e = c.members().lookup(names.serialVersionUID);
while (e.scope != null && e.sym.kind != VAR) e = e.next();
if (e.scope == null) {
log.warning(tree.pos(), "missing.SVUID", c);
log.warning(Lint.LintCategory.SERIAL,
tree.pos(), "missing.SVUID", c);
return;
}
......@@ -3069,15 +3134,18 @@ public class Attr extends JCTree.Visitor {
VarSymbol svuid = (VarSymbol)e.sym;
if ((svuid.flags() & (STATIC | FINAL)) !=
(STATIC | FINAL))
log.warning(TreeInfo.diagnosticPositionFor(svuid, tree), "improper.SVUID", c);
log.warning(Lint.LintCategory.SERIAL,
TreeInfo.diagnosticPositionFor(svuid, tree), "improper.SVUID", c);
// check that it is long
else if (svuid.type.tag != TypeTags.LONG)
log.warning(TreeInfo.diagnosticPositionFor(svuid, tree), "long.SVUID", c);
log.warning(Lint.LintCategory.SERIAL,
TreeInfo.diagnosticPositionFor(svuid, tree), "long.SVUID", c);
// check constant
else if (svuid.getConstValue() == null)
log.warning(TreeInfo.diagnosticPositionFor(svuid, tree), "constant.SVUID", c);
log.warning(Lint.LintCategory.SERIAL,
TreeInfo.diagnosticPositionFor(svuid, tree), "constant.SVUID", c);
}
private Type capture(Type type) {
......
......@@ -111,13 +111,13 @@ public class Check {
boolean enforceMandatoryWarnings = source.enforceMandatoryWarnings();
deprecationHandler = new MandatoryWarningHandler(log, verboseDeprecated,
enforceMandatoryWarnings, "deprecated");
enforceMandatoryWarnings, "deprecated", LintCategory.DEPRECATION);
uncheckedHandler = new MandatoryWarningHandler(log, verboseUnchecked,
enforceMandatoryWarnings, "unchecked");
enforceMandatoryWarnings, "unchecked", LintCategory.UNCHECKED);
unsafeVarargsHandler = new MandatoryWarningHandler(log, verboseVarargs,
enforceMandatoryWarnings, "varargs");
enforceMandatoryWarnings, "varargs", LintCategory.VARARGS);
sunApiHandler = new MandatoryWarningHandler(log, verboseSunApi,
enforceMandatoryWarnings, "sunapi");
enforceMandatoryWarnings, "sunapi", null);
}
/** Switch: generics enabled?
......@@ -209,7 +209,7 @@ public class Check {
public void warnStatic(DiagnosticPosition pos, String msg, Object... args) {
if (lint.isEnabled(LintCategory.STATIC))
log.warning(pos, msg, args);
log.warning(LintCategory.STATIC, pos, msg, args);
}
/**
......@@ -393,6 +393,10 @@ public class Check {
* @param req The type that was required.
*/
Type checkType(DiagnosticPosition pos, Type found, Type req) {
return checkType(pos, found, req, "incompatible.types");
}
Type checkType(DiagnosticPosition pos, Type found, Type req, String errKey) {
if (req.tag == ERROR)
return req;
if (found.tag == FORALL)
......@@ -411,7 +415,7 @@ public class Check {
log.error(pos, "assignment.to.extends-bound", req);
return types.createErrorType(found);
}
return typeError(pos, diags.fragment("incompatible.types"), found, req);
return typeError(pos, diags.fragment(errKey), found, req);
}
/** Instantiate polymorphic type to some prototype, unless
......@@ -925,7 +929,8 @@ public class Check {
!TreeInfo.isDiamond(tree) &&
!env.enclClass.name.isEmpty() && //anonymous or intersection
tree.type.isRaw()) {
log.warning(tree.pos(), "raw.class.use", tree.type, tree.type.tsym.type);
log.warning(Lint.LintCategory.RAW,
tree.pos(), "raw.class.use", tree.type, tree.type.tsym.type);
}
}
......@@ -1853,6 +1858,7 @@ public class Check {
types.isSameType(types.erasure(sym.type), types.erasure(e.sym.type)) &&
sym != e.sym &&
(sym.flags() & Flags.SYNTHETIC) != (e.sym.flags() & Flags.SYNTHETIC) &&
(sym.flags() & IPROXY) == 0 && (e.sym.flags() & IPROXY) == 0 &&
(sym.flags() & BRIDGE) == 0 && (e.sym.flags() & BRIDGE) == 0) {
syntheticError(pos, (e.sym.flags() & SYNTHETIC) == 0 ? e.sym : sym);
return;
......@@ -2151,7 +2157,8 @@ public class Check {
(s.flags() & DEPRECATED) != 0 &&
!syms.deprecatedType.isErroneous() &&
s.attribute(syms.deprecatedType.tsym) == null) {
log.warning(pos, "missing.deprecated.annotation");
log.warning(Lint.LintCategory.DEP_ANN,
pos, "missing.deprecated.annotation");
}
}
......@@ -2302,7 +2309,7 @@ public class Check {
int opc = ((OperatorSymbol)operator).opcode;
if (opc == ByteCodes.idiv || opc == ByteCodes.imod
|| opc == ByteCodes.ldiv || opc == ByteCodes.lmod) {
log.warning(pos, "div.zero");
log.warning(Lint.LintCategory.DIVZERO, pos, "div.zero");
}
}
}
......@@ -2312,7 +2319,7 @@ public class Check {
*/
void checkEmptyIf(JCIf tree) {
if (tree.thenpart.getTag() == JCTree.SKIP && tree.elsepart == null && lint.isEnabled(Lint.LintCategory.EMPTY))
log.warning(tree.thenpart.pos(), "empty.if");
log.warning(Lint.LintCategory.EMPTY, tree.thenpart.pos(), "empty.if");
}
/** Check that symbol is unique in given scope.
......
......@@ -28,6 +28,8 @@
package com.sun.tools.javac.comp;
import java.util.HashMap;
import java.util.Map;
import java.util.LinkedHashMap;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.tree.*;
......@@ -35,6 +37,7 @@ import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.comp.Resolve;
import com.sun.tools.javac.tree.JCTree.*;
import static com.sun.tools.javac.code.Flags.*;
......@@ -185,6 +188,8 @@ public class Flow extends TreeScanner {
private final Types types;
private final Check chk;
private TreeMaker make;
private final Resolve rs;
private Env<AttrContext> attrEnv;
private Lint lint;
private final boolean allowRethrowAnalysis;
......@@ -203,6 +208,7 @@ public class Flow extends TreeScanner {
types = Types.instance(context);
chk = Check.instance(context);
lint = Lint.instance(context);
rs = Resolve.instance(context);
Source source = Source.instance(context);
allowRethrowAnalysis = source.allowMulticatch();
}
......@@ -265,6 +271,10 @@ public class Flow extends TreeScanner {
*/
List<Type> caught;
/** The list of unreferenced automatic resources.
*/
Map<VarSymbol, JCVariableDecl> unrefdResources;
/** Set when processing a loop body the second time for DU analysis. */
boolean loopPassTwo = false;
......@@ -936,7 +946,8 @@ public class Flow extends TreeScanner {
alive &&
lint.isEnabled(Lint.LintCategory.FALLTHROUGH) &&
c.stats.nonEmpty() && l.tail.nonEmpty())
log.warning(l.tail.head.pos(),
log.warning(Lint.LintCategory.FALLTHROUGH,
l.tail.head.pos(),
"possible.fall-through.into.case");
}
if (!hasDefault) {
......@@ -963,6 +974,7 @@ public class Flow extends TreeScanner {
public void visitTry(JCTry tree) {
List<Type> caughtPrev = caught;
List<Type> thrownPrev = thrown;
Map<VarSymbol, JCVariableDecl> unrefdResourcesPrev = unrefdResources;
thrown = List.nil();
for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
......@@ -977,6 +989,38 @@ public class Flow extends TreeScanner {
pendingExits = new ListBuffer<PendingExit>();
Bits initsTry = inits.dup();
uninitsTry = uninits.dup();
unrefdResources = new LinkedHashMap<VarSymbol, JCVariableDecl>();
for (JCTree resource : tree.resources) {
if (resource instanceof JCVariableDecl) {
JCVariableDecl vdecl = (JCVariableDecl) resource;
visitVarDef(vdecl);
unrefdResources.put(vdecl.sym, vdecl);
} else if (resource instanceof JCExpression) {
scanExpr((JCExpression) resource);
} else {
throw new AssertionError(tree); // parser error
}
}
for (JCTree resource : tree.resources) {
List<Type> closeableSupertypes = resource.type.isCompound() ?
types.interfaces(resource.type).prepend(types.supertype(resource.type)) :
List.of(resource.type);
for (Type sup : closeableSupertypes) {
if (types.asSuper(sup, syms.autoCloseableType.tsym) != null) {
Symbol closeMethod = rs.resolveInternalMethod(tree,
attrEnv,
sup,
names.close,
List.<Type>nil(),
List.<Type>nil());
if (closeMethod.kind == MTH) {
for (Type t : ((MethodSymbol)closeMethod).getThrownTypes()) {
markThrown(tree.body, t);
}
}
}
}
}
scanStat(tree.body);
List<Type> thrownInTry = thrown;
thrown = thrownPrev;
......@@ -987,6 +1031,14 @@ public class Flow extends TreeScanner {
Bits uninitsEnd = uninits;
int nextadrCatch = nextadr;
if (!unrefdResources.isEmpty() &&
lint.isEnabled(Lint.LintCategory.ARM)) {
for (Map.Entry<VarSymbol, JCVariableDecl> e : unrefdResources.entrySet()) {
log.warning(e.getValue().pos(),
"automatic.resource.not.referenced", e.getKey());
}
}
List<Type> caughtInTry = List.nil();
for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
alive = true;
......@@ -1040,8 +1092,9 @@ public class Flow extends TreeScanner {
thrown = chk.union(thrown, thrownPrev);
if (!loopPassTwo &&
lint.isEnabled(Lint.LintCategory.FINALLY)) {
log.warning(TreeInfo.diagEndPos(tree.finalizer),
"finally.cannot.complete");
log.warning(Lint.LintCategory.FINALLY,
TreeInfo.diagEndPos(tree.finalizer),
"finally.cannot.complete");
}
} else {
thrown = chk.union(thrown, chk.diff(thrownInTry, caughtInTry));
......@@ -1070,6 +1123,7 @@ public class Flow extends TreeScanner {
while (exits.nonEmpty()) pendingExits.append(exits.next());
}
uninitsTry.andSet(uninitsTryPrev).andSet(uninits);
unrefdResources = unrefdResourcesPrev;
}
public void visitConditional(JCConditional tree) {
......@@ -1293,8 +1347,16 @@ public class Flow extends TreeScanner {
}
public void visitIdent(JCIdent tree) {
if (tree.sym.kind == VAR)
if (tree.sym.kind == VAR) {
checkInit(tree.pos(), (VarSymbol)tree.sym);
referenced(tree.sym);
}
}
void referenced(Symbol sym) {
if (unrefdResources != null && unrefdResources.containsKey(sym)) {
unrefdResources.remove(sym);
}
}
public void visitTypeCast(JCTypeCast tree) {
......@@ -1303,7 +1365,8 @@ public class Flow extends TreeScanner {
&& lint.isEnabled(Lint.LintCategory.CAST)
&& types.isSameType(tree.expr.type, tree.clazz.type)
&& !(ignoreAnnotatedCasts && containsTypeAnnotation(tree.clazz))) {
log.warning(tree.pos(), "redundant.cast", tree.expr.type);
log.warning(Lint.LintCategory.CAST,
tree.pos(), "redundant.cast", tree.expr.type);
}
}
......@@ -1334,8 +1397,10 @@ public class Flow extends TreeScanner {
/** Perform definite assignment/unassignment analysis on a tree.
*/
public void analyzeTree(JCTree tree, TreeMaker make) {
public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
try {
attrEnv = env;
JCTree tree = env.tree;
this.make = make;
inits = new Bits();
uninits = new Bits();
......
......@@ -256,7 +256,7 @@ public class Infer {
UndetVar uv = (UndetVar) l.head;
TypeVar tv = (TypeVar)uv.qtype;
ListBuffer<Type> hibounds = new ListBuffer<Type>();
for (Type t : that.getConstraints(tv, ConstraintKind.EXTENDS).prependList(types.getBounds(tv))) {
for (Type t : that.getConstraints(tv, ConstraintKind.EXTENDS)) {
if (!t.containsSome(that.tvars) && t.tag != BOT) {
hibounds.append(t);
}
......@@ -280,7 +280,6 @@ public class Infer {
// check bounds
List<Type> targs = Type.map(undetvars, getInstFun);
targs = types.subst(targs, that.tvars, targs);
checkWithinBounds(that.tvars, targs, warn);
return chk.checkType(warn.pos(), that.inst(targs, types), to);
}
......@@ -398,7 +397,7 @@ public class Infer {
UndetVar uv = (UndetVar)t;
if (uv.qtype == tv) {
switch (ck) {
case EXTENDS: return uv.hibounds;
case EXTENDS: return uv.hibounds.appendList(types.subst(types.getBounds(tv), all_tvars, inferredTypes));
case SUPER: return uv.lobounds;
case EQUAL: return uv.inst != null ? List.of(uv.inst) : List.<Type>nil();
}
......@@ -458,7 +457,7 @@ public class Infer {
/** check that type parameters are within their bounds.
*/
private void checkWithinBounds(List<Type> tvars,
void checkWithinBounds(List<Type> tvars,
List<Type> arguments,
Warner warn)
throws InvalidInstanceException {
......
......@@ -605,6 +605,23 @@ public class Lower extends TreeTranslator {
s.enter(sym);
}
/** Create a fresh synthetic name within a given scope - the unique name is
* obtained by appending '$' chars at the end of the name until no match
* is found.
*
* @param name base name
* @param s scope in which the name has to be unique
* @return fresh synthetic name
*/
private Name makeSyntheticName(Name name, Scope s) {
do {
name = name.append(
target.syntheticNameChar(),
names.empty);
} while (lookupSynthetic(name, s) != null);
return name;
}
/** Check whether synthetic symbols generated during lowering conflict
* with user-defined symbols.
*
......@@ -1299,6 +1316,11 @@ public class Lower extends TreeTranslator {
*/
Scope proxies;
/** A scope containing all unnamed resource variables/saved
* exception variables for translated TWR blocks
*/
Scope twrVars;
/** A stack containing the this$n field of the currently translated
* classes (if needed) in innermost first order.
* Inside a constructor, proxies and any this$n symbol are duplicated
......@@ -1400,6 +1422,122 @@ public class Lower extends TreeTranslator {
}
}
/** Optionally replace a try statement with an automatic resource
* management (ARM) block.
* @param tree The try statement to inspect.
* @return An ARM block, or the original try block if there are no
* resources to manage.
*/
JCTree makeArmTry(JCTry tree) {
make_at(tree.pos());
twrVars = twrVars.dup();
JCBlock armBlock = makeArmBlock(tree.resources, tree.body, 0);
if (tree.catchers.isEmpty() && tree.finalizer == null)
result = translate(armBlock);
else
result = translate(make.Try(armBlock, tree.catchers, tree.finalizer));
twrVars = twrVars.leave();
return result;
}
private JCBlock makeArmBlock(List<JCTree> resources, JCBlock block, int depth) {
if (resources.isEmpty())
return block;
// Add resource declaration or expression to block statements
ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
JCTree resource = resources.head;
JCExpression expr = null;
if (resource instanceof JCVariableDecl) {
JCVariableDecl var = (JCVariableDecl) resource;
expr = make.Ident(var.sym).setType(resource.type);
stats.add(var);
} else {
assert resource instanceof JCExpression;
VarSymbol syntheticTwrVar =
new VarSymbol(SYNTHETIC | FINAL,
makeSyntheticName(names.fromString("twrVar" +
depth), twrVars),
(resource.type.tag == TypeTags.BOT) ?
syms.autoCloseableType : resource.type,
currentMethodSym);
twrVars.enter(syntheticTwrVar);
JCVariableDecl syntheticTwrVarDecl =
make.VarDef(syntheticTwrVar, (JCExpression)resource);
expr = (JCExpression)make.Ident(syntheticTwrVar);
stats.add(syntheticTwrVarDecl);
}
// Add primaryException declaration
VarSymbol primaryException =
new VarSymbol(SYNTHETIC,
makeSyntheticName(names.fromString("primaryException" +
depth), twrVars),
syms.throwableType,
currentMethodSym);
twrVars.enter(primaryException);
JCVariableDecl primaryExceptionTreeDecl = make.VarDef(primaryException, makeNull());
stats.add(primaryExceptionTreeDecl);
// Create catch clause that saves exception and then rethrows it
VarSymbol param =
new VarSymbol(FINAL|SYNTHETIC,
names.fromString("t" +
target.syntheticNameChar()),
syms.throwableType,
currentMethodSym);
JCVariableDecl paramTree = make.VarDef(param, null);
JCStatement assign = make.Assignment(primaryException, make.Ident(param));
JCStatement rethrowStat = make.Throw(make.Ident(param));
JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(assign, rethrowStat));
JCCatch catchClause = make.Catch(paramTree, catchBlock);
int oldPos = make.pos;
make.at(TreeInfo.endPos(block));
JCBlock finallyClause = makeArmFinallyClause(primaryException, expr);
make.at(oldPos);
JCTry outerTry = make.Try(makeArmBlock(resources.tail, block, depth + 1),
List.<JCCatch>of(catchClause),
finallyClause);
stats.add(outerTry);
return make.Block(0L, stats.toList());
}
private JCBlock makeArmFinallyClause(Symbol primaryException, JCExpression resource) {
// primaryException.addSuppressedException(catchException);
VarSymbol catchException =
new VarSymbol(0, make.paramName(2),
syms.throwableType,
currentMethodSym);
JCStatement addSuppressionStatement =
make.Exec(makeCall(make.Ident(primaryException),
names.fromString("addSuppressedException"),
List.<JCExpression>of(make.Ident(catchException))));
// try { resource.close(); } catch (e) { primaryException.addSuppressedException(e); }
JCBlock tryBlock =
make.Block(0L, List.<JCStatement>of(makeResourceCloseInvocation(resource)));
JCVariableDecl catchExceptionDecl = make.VarDef(catchException, null);
JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(addSuppressionStatement));
List<JCCatch> catchClauses = List.<JCCatch>of(make.Catch(catchExceptionDecl, catchBlock));
JCTry tryTree = make.Try(tryBlock, catchClauses, null);
// if (resource != null) resourceClose;
JCExpression nullCheck = makeBinary(JCTree.NE,
make.Ident(primaryException),
makeNull());
JCIf closeIfStatement = make.If(nullCheck,
tryTree,
makeResourceCloseInvocation(resource));
return make.Block(0L, List.<JCStatement>of(closeIfStatement));
}
private JCStatement makeResourceCloseInvocation(JCExpression resource) {
// create resource.close() method invocation
JCExpression resourceClose = makeCall(resource, names.close, List.<JCExpression>nil());
return make.Exec(resourceClose);
}
/** Construct a tree that represents the outer instance
* <C.this>. Never pick the current `this'.
* @param pos The source code position to be used for the tree.
......@@ -3405,6 +3543,15 @@ public class Lower extends TreeTranslator {
result = tree;
}
@Override
public void visitTry(JCTry tree) {
if (tree.resources.isEmpty()) {
super.visitTry(tree);
} else {
result = makeArmTry(tree);
}
}
/**************************************************************************
* main method
*************************************************************************/
......@@ -3430,6 +3577,7 @@ public class Lower extends TreeTranslator {
actualSymbols = new HashMap<Symbol,Symbol>();
freevarCache = new HashMap<ClassSymbol,List<VarSymbol>>();
proxies = new Scope(syms.noSymbol);
twrVars = new Scope(syms.noSymbol);
outerThisStack = List.nil();
accessNums = new HashMap<Symbol,Integer>();
accessSyms = new HashMap<Symbol,MethodSymbol[]>();
......
......@@ -1797,13 +1797,13 @@ public class Resolve {
return null;
if (isOperator(name)) {
return diags.create(dkind, false, log.currentSource(), pos,
return diags.create(dkind, log.currentSource(), pos,
"operator.cant.be.applied", name, argtypes);
}
boolean hasLocation = false;
if (!site.tsym.name.isEmpty()) {
if (site.tsym.kind == PCK && !site.tsym.exists()) {
return diags.create(dkind, false, log.currentSource(), pos,
return diags.create(dkind, log.currentSource(), pos,
"doesnt.exist", site.tsym);
}
hasLocation = true;
......@@ -1814,13 +1814,13 @@ public class Resolve {
Name idname = isConstructor ? site.tsym.name : name;
String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
if (hasLocation) {
return diags.create(dkind, false, log.currentSource(), pos,
return diags.create(dkind, log.currentSource(), pos,
errKey, kindname, idname, //symbol kindname, name
typeargtypes, argtypes, //type parameters and arguments (if any)
typeKindName(site), site); //location kindname, type
}
else {
return diags.create(dkind, false, log.currentSource(), pos,
return diags.create(dkind, log.currentSource(), pos,
errKey, kindname, idname, //symbol kindname, name
typeargtypes, argtypes); //type parameters and arguments (if any)
}
......@@ -1886,12 +1886,12 @@ public class Resolve {
return null;
if (isOperator(name)) {
return diags.create(dkind, false, log.currentSource(),
return diags.create(dkind, log.currentSource(),
pos, "operator.cant.be.applied", name, argtypes);
}
else {
Symbol ws = sym.asMemberOf(site, types);
return diags.create(dkind, false, log.currentSource(), pos,
return diags.create(dkind, log.currentSource(), pos,
"cant.apply.symbol" + (explanation != null ? ".1" : ""),
kindName(ws),
ws.name == names.init ? ws.owner.name : ws.name,
......@@ -1974,18 +1974,18 @@ public class Resolve {
else if ((sym.flags() & PUBLIC) != 0
|| (env != null && this.site != null
&& !isAccessible(env, this.site))) {
return diags.create(dkind, false, log.currentSource(),
return diags.create(dkind, log.currentSource(),
pos, "not.def.access.class.intf.cant.access",
sym, sym.location());
}
else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
return diags.create(dkind, false, log.currentSource(),
return diags.create(dkind, log.currentSource(),
pos, "report.access", sym,
asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
sym.location());
}
else {
return diags.create(dkind, false, log.currentSource(),
return diags.create(dkind, log.currentSource(),
pos, "not.def.public.cant.access", sym, sym.location());
}
}
......@@ -2011,7 +2011,7 @@ public class Resolve {
Symbol errSym = ((sym.kind == TYP && sym.type.tag == CLASS)
? types.erasure(sym.type).tsym
: sym);
return diags.create(dkind, false, log.currentSource(), pos,
return diags.create(dkind, log.currentSource(), pos,
"non-static.cant.be.ref", kindName(sym), errSym);
}
}
......@@ -2048,7 +2048,7 @@ public class Resolve {
}
Name sname = pair.sym.name;
if (sname == names.init) sname = pair.sym.owner.name;
return diags.create(dkind, false, log.currentSource(),
return diags.create(dkind, log.currentSource(),
pos, "ref.ambiguous", sname,
kindName(pair.sym),
pair.sym,
......
......@@ -535,6 +535,14 @@ public class TransTypes extends TreeTranslator {
result = tree;
}
public void visitTry(JCTry tree) {
tree.resources = translate(tree.resources, syms.autoCloseableType);
tree.body = translate(tree.body);
tree.catchers = translateCatchers(tree.catchers);
tree.finalizer = translate(tree.finalizer);
result = tree;
}
public void visitConditional(JCConditional tree) {
tree.cond = translate(tree.cond, syms.booleanType);
tree.truepart = translate(tree.truepart, erasure(tree.type));
......
......@@ -246,7 +246,8 @@ public class Paths {
private void addDirectory(File dir, boolean warn) {
if (!dir.isDirectory()) {
if (warn)
log.warning("dir.path.element.not.found", dir);
log.warning(Lint.LintCategory.PATH,
"dir.path.element.not.found", dir);
return;
}
......@@ -280,8 +281,10 @@ public class Paths {
if (! fsInfo.exists(file)) {
/* No such file or directory exists */
if (warn)
log.warning("path.element.not.found", file);
if (warn) {
log.warning(Lint.LintCategory.PATH,
"path.element.not.found", file);
}
} else if (fsInfo.isFile(file)) {
/* File is an ordinary file. */
if (!isArchive(file)) {
......@@ -290,12 +293,16 @@ public class Paths {
try {
ZipFile z = new ZipFile(file);
z.close();
if (warn)
log.warning("unexpected.archive.file", file);
if (warn) {
log.warning(Lint.LintCategory.PATH,
"unexpected.archive.file", file);
}
} catch (IOException e) {
// FIXME: include e.getLocalizedMessage in warning
if (warn)
log.warning("invalid.archive.file", file);
if (warn) {
log.warning(Lint.LintCategory.PATH,
"invalid.archive.file", file);
}
return;
}
}
......
......@@ -325,6 +325,7 @@ implements CRTFlags {
public void visitTry(JCTry tree) {
SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
sr.mergeWith(csp(tree.resources));
sr.mergeWith(csp(tree.body));
sr.mergeWith(cspCatchers(tree.catchers));
sr.mergeWith(csp(tree.finalizer));
......
......@@ -2628,7 +2628,7 @@ public class ClassReader implements Completer {
* @param arg An argument for substitution into the output string.
*/
private void printVerbose(String key, CharSequence arg) {
Log.printLines(log.noticeWriter, Log.getLocalizedString("verbose." + key, arg));
log.printNoteLines("verbose." + key, arg);
}
/** Output for "-checkclassfile" option.
......@@ -2636,7 +2636,7 @@ public class ClassReader implements Completer {
* @param arg An argument for substitution into the output string.
*/
private void printCCF(String key, Object arg) {
Log.printLines(log.noticeWriter, Log.getLocalizedString(key, arg));
log.printNoteLines(key, arg);
}
......
......@@ -1604,7 +1604,7 @@ public class ClassWriter extends ClassFile {
try {
writeClassFile(out, c);
if (verbose)
log.errWriter.println(Log.getLocalizedString("verbose.wrote.file", outFile));
log.printErrLines("verbose.wrote.file", outFile);
out.close();
out = null;
} finally {
......
......@@ -1105,7 +1105,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
return env;
if (verboseCompilePolicy)
Log.printLines(log.noticeWriter, "[attribute " + env.enclClass.sym + "]");
printNote("[attribute " + env.enclClass.sym + "]");
if (verbose)
printVerbose("checking.attribution", env.enclClass.sym);
......@@ -1174,7 +1174,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
try {
make.at(Position.FIRSTPOS);
TreeMaker localMake = make.forToplevel(env.toplevel);
flow.analyzeTree(env.tree, localMake);
flow.analyzeTree(env, localMake);
compileStates.put(env, CompileState.FLOW);
if (shouldStop(CompileState.FLOW))
......@@ -1527,19 +1527,19 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
* @param arg An argument for substitution into the output string.
*/
protected void printVerbose(String key, Object arg) {
Log.printLines(log.noticeWriter, Log.getLocalizedString("verbose." + key, arg));
log.printNoteLines("verbose." + key, arg);
}
/** Print numbers of errors and warnings.
*/
protected void printCount(String kind, int count) {
if (count != 0) {
String text;
String key;
if (count == 1)
text = Log.getLocalizedString("count." + kind, String.valueOf(count));
key = "count." + kind;
else
text = Log.getLocalizedString("count." + kind + ".plural", String.valueOf(count));
Log.printLines(log.errWriter, text);
key = "count." + kind + ".plural";
log.printErrLines(key, String.valueOf(count));
log.errWriter.flush();
}
}
......
......@@ -131,6 +131,7 @@ public class JavacParser implements Parser {
this.allowForeach = source.allowForeach();
this.allowStaticImport = source.allowStaticImport();
this.allowAnnotations = source.allowAnnotations();
this.allowTWR = source.allowTryWithResources();
this.allowDiamond = source.allowDiamond();
this.allowMulticatch = source.allowMulticatch();
this.allowTypeAnnotations = source.allowTypeAnnotations();
......@@ -186,6 +187,10 @@ public class JavacParser implements Parser {
*/
boolean allowTypeAnnotations;
/** Switch: should we recognize automatic resource management?
*/
boolean allowTWR;
/** Switch: should we keep docComments?
*/
boolean keepDocComments;
......@@ -1151,8 +1156,12 @@ public class JavacParser implements Parser {
t = toP(F.at(pos).Select(t, ident()));
break;
case ELLIPSIS:
assert this.permitTypeAnnotationsPushBack;
typeAnnotationsPushedBack = annos;
if (this.permitTypeAnnotationsPushBack) {
this.typeAnnotationsPushedBack = annos;
} else if (annos.nonEmpty()) {
// Don't return here -- error recovery attempt
illegal(annos.head.pos);
}
break loop;
default:
break loop;
......@@ -1842,6 +1851,7 @@ public class JavacParser implements Parser {
* | WHILE ParExpression Statement
* | DO Statement WHILE ParExpression ";"
* | TRY Block ( Catches | [Catches] FinallyPart )
* | TRY "(" ResourceSpecification ")" Block [Catches] [FinallyPart]
* | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
* | SYNCHRONIZED ParExpression Block
* | RETURN [Expression] ";"
......@@ -1912,6 +1922,13 @@ public class JavacParser implements Parser {
}
case TRY: {
S.nextToken();
List<JCTree> resources = List.<JCTree>nil();
if (S.token() == LPAREN) {
checkAutomaticResourceManagement();
S.nextToken();
resources = resources();
accept(RPAREN);
}
JCBlock body = block();
ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
JCBlock finalizer = null;
......@@ -1922,9 +1939,13 @@ public class JavacParser implements Parser {
finalizer = block();
}
} else {
log.error(pos, "try.without.catch.or.finally");
if (allowTWR) {
if (resources.isEmpty())
log.error(pos, "try.without.catch.finally.or.resource.decls");
} else
log.error(pos, "try.without.catch.or.finally");
}
return F.at(pos).Try(body, catchers.toList(), finalizer);
return F.at(pos).Try(resources, body, catchers.toList(), finalizer);
}
case SWITCH: {
S.nextToken();
......@@ -2217,7 +2238,7 @@ public class JavacParser implements Parser {
/* A modifiers tree with no modifier tokens or annotations
* has no text position. */
if ((flags & Flags.ModifierFlags) == 0 && annotations.isEmpty())
if ((flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0 && annotations.isEmpty())
pos = Position.NOPOS;
JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
......@@ -2385,6 +2406,39 @@ public class JavacParser implements Parser {
return toP(F.at(pos).VarDef(mods, name, type, null));
}
/** Resources = Resource { ";" Resources }
*/
List<JCTree> resources() {
ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
defs.append(resource());
while (S.token() == SEMI) {
// All but last of multiple declarators subsume a semicolon
storeEnd(defs.elems.last(), S.endPos());
S.nextToken();
defs.append(resource());
}
return defs.toList();
}
/** Resource =
* VariableModifiers Type VariableDeclaratorId = Expression
* | Expression
*/
JCTree resource() {
int pos = S.pos();
if (S.token() == FINAL || S.token() == MONKEYS_AT) {
return variableDeclaratorRest(pos, optFinal(0), parseType(),
ident(), true, null);
} else {
JCExpression t = term(EXPR | TYPE);
if ((lastmode & TYPE) != 0 && S.token() == IDENTIFIER)
return variableDeclaratorRest(pos, toP(F.at(pos).Modifiers(Flags.FINAL)), t,
ident(), true, null);
else
return t;
}
}
/** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
*/
public JCTree.JCCompilationUnit parseCompilationUnit() {
......@@ -3216,6 +3270,12 @@ public class JavacParser implements Parser {
if (!allowMulticatch) {
log.error(S.pos(), "multicatch.not.supported.in.source", source.name);
allowMulticatch = true;
}
}
}
void checkAutomaticResourceManagement() {
if (!allowTWR) {
log.error(S.pos(), "automatic.resource.management.not.supported.in.source", source.name);
allowTWR = true;
}
}
}
......@@ -379,6 +379,15 @@ public class JavacFiler implements Filer, Closeable {
}
private JavaFileObject createSourceOrClassFile(boolean isSourceFile, String name) throws IOException {
if (lint) {
int periodIndex = name.lastIndexOf(".");
if (periodIndex != -1) {
String base = name.substring(periodIndex);
String extn = (isSourceFile ? ".java" : ".class");
if (base.equals(extn))
log.warning("proc.suspicious.class.name", name, extn);
}
}
checkNameAndExistence(name, isSourceFile);
Location loc = (isSourceFile ? SOURCE_OUTPUT : CLASS_OUTPUT);
JavaFileObject.Kind kind = (isSourceFile ?
......@@ -530,13 +539,16 @@ public class JavacFiler implements Filer, Closeable {
/**
* Update internal state for a new round.
*/
public void newRound(Context context, boolean lastRound) {
public void newRound(Context context) {
this.context = context;
this.log = Log.instance(context);
this.lastRound = lastRound;
clearRoundState();
}
void setLastRound(boolean lastRound) {
this.lastRound = lastRound;
}
public void close() {
clearRoundState();
// Cross-round state
......
......@@ -46,6 +46,7 @@ public class JavacMessager implements Messager {
Log log;
JavacProcessingEnvironment processingEnv;
int errorCount = 0;
int warningCount = 0;
JavacMessager(Context context, JavacProcessingEnvironment processingEnv) {
log = Log.instance(context);
......@@ -116,10 +117,12 @@ public class JavacMessager implements Messager {
break;
case WARNING:
warningCount++;
log.warning(pos, "proc.messager", msg.toString());
break;
case MANDATORY_WARNING:
warningCount++;
log.mandatoryWarning(pos, "proc.messager", msg.toString());
break;
......@@ -167,6 +170,10 @@ public class JavacMessager implements Messager {
return errorCount;
}
public int warningCount() {
return warningCount;
}
public void newRound(Context context) {
log = Log.instance(context);
errorCount = 0;
......
......@@ -61,6 +61,8 @@ compiler.err.anon.class.impl.intf.no.typeargs=\
anonymous class implements interface; cannot have type arguments
compiler.err.anon.class.impl.intf.no.qual.for.new=\
anonymous class implements interface; cannot have qualifier for new
compiler.misc.twr.not.applicable.to.type=\
automatic resource management not applicable to variable type
compiler.err.array.and.varargs=\
cannot declare both {0} and {1} in {2}
compiler.err.array.dimension.missing=\
......@@ -172,6 +174,8 @@ compiler.err.except.never.thrown.in.try=\
compiler.err.final.parameter.may.not.be.assigned=\
final parameter {0} may not be assigned
compiler.err.twr.resource.may.not.be.assigned=\
automatic resource {0} may not be assigned
compiler.err.multicatch.parameter.may.not.be.assigned=\
multi-catch parameter {0} may not be assigned
compiler.err.multicatch.param.must.be.final=\
......@@ -448,6 +452,8 @@ compiler.err.throws.not.allowed.in.intf.annotation=\
throws clause not allowed in @interface members
compiler.err.try.without.catch.or.finally=\
''try'' without ''catch'' or ''finally''
compiler.err.try.without.catch.finally.or.resource.decls=\
''try'' without ''catch'', ''finally'' or resource declarations
compiler.err.type.doesnt.take.params=\
type {0} does not take parameters
compiler.err.type.var.cant.be.deref=\
......@@ -691,25 +697,31 @@ compiler.misc.resume.abort=\
compiler.warn.warning=\
warning:\u0020
## Warning messages may also include the following prefix to identify a
## lint option
compiler.warn.lintOption=\
[{0}]\u0020
compiler.warn.constant.SVUID=\
[serial] serialVersionUID must be constant in class {0}
serialVersionUID must be constant in class {0}
compiler.warn.dir.path.element.not.found=\
[path] bad path element "{0}": no such directory
bad path element "{0}": no such directory
compiler.warn.finally.cannot.complete=\
[finally] finally clause cannot complete normally
finally clause cannot complete normally
compiler.warn.has.been.deprecated=\
[deprecation] {0} in {1} has been deprecated
{0} in {1} has been deprecated
compiler.warn.sun.proprietary=\
{0} is internal proprietary API and may be removed in a future release
compiler.warn.illegal.char.for.encoding=\
unmappable character for encoding {0}
compiler.warn.improper.SVUID=\
[serial] serialVersionUID must be declared static final in class {0}
serialVersionUID must be declared static final in class {0}
compiler.warn.inexact.non-varargs.call=\
non-varargs call of varargs method with inexact argument type for last parameter;\n\
......@@ -717,10 +729,10 @@ cast to {0} for a varargs call\n\
cast to {1} for a non-varargs call and to suppress this warning
compiler.warn.long.SVUID=\
[serial] serialVersionUID must be of type long in class {0}
serialVersionUID must be of type long in class {0}
compiler.warn.missing.SVUID=\
[serial] serializable class {0} has no definition of serialVersionUID
serializable class {0} has no definition of serialVersionUID
compiler.warn.override.varargs.missing=\
{0}; overridden method has no ''...''
......@@ -731,13 +743,15 @@ compiler.warn.override.bridge=\
compiler.warn.pkg-info.already.seen=\
a package-info.java file has already been seen for package {0}
compiler.warn.path.element.not.found=\
[path] bad path element "{0}": no such file or directory
bad path element "{0}": no such file or directory
compiler.warn.possible.fall-through.into.case=\
[fallthrough] possible fall-through into case
possible fall-through into case
compiler.warn.redundant.cast=\
[cast] redundant cast to {0}
redundant cast to {0}
compiler.warn.position.overflow=\
Position encoding overflows at line {0}
......@@ -747,7 +761,7 @@ compiler.warn.big.major.version=\
It is recommended that the compiler be upgraded.
compiler.warn.static.not.qualified.by.type=\
[static] static {0} should be qualified by type name, {1}, instead of by an expression
static {0} should be qualified by type name, {1}, instead of by an expression
# Warnings related to annotation processing
compiler.warn.proc.package.does.not.exist=\
......@@ -764,6 +778,9 @@ compiler.warn.proc.type.recreate=\
compiler.warn.proc.illegal.file.name=\
Cannot create file for illegal name ''{0}''.
compiler.warn.proc.suspicious.class.name=\
Creating file for a type whose name ends in {1}: ''{0}''
compiler.warn.proc.file.create.last.round=\
File for type ''{0}'' created in the last round will not be subject to annotation processing.
......@@ -797,39 +814,43 @@ compiler.warn.proc.unclosed.type.files=\
compiler.warn.proc.unmatched.processor.options=\
The following options were not recognized by any processor: ''{0}''
compiler.warn.twr.explicit.close.call=\
[arm] explicit call to close() on an automatic resource
compiler.warn.automatic.resource.not.referenced=\
[arm] automatic resource {0} is never referenced in body of corresponding try statement
compiler.warn.unchecked.assign=\
[unchecked] unchecked assignment: {0} to {1}
unchecked assignment: {0} to {1}
compiler.warn.unchecked.assign.to.var=\
[unchecked] unchecked assignment to variable {0} as member of raw type {1}
unchecked assignment to variable {0} as member of raw type {1}
compiler.warn.unchecked.call.mbr.of.raw.type=\
[unchecked] unchecked call to {0} as a member of the raw type {1}
unchecked call to {0} as a member of the raw type {1}
compiler.warn.unchecked.cast.to.type=\
[unchecked] unchecked cast to type {0}
unchecked cast to type {0}
compiler.warn.unchecked.meth.invocation.applied=\
[unchecked] unchecked method invocation: {0} {1} in {4} {5} is applied to given types\n\
unchecked method invocation: {0} {1} in {4} {5} is applied to given types\n\
required: {2}\n\
found: {3}
compiler.warn.unchecked.generic.array.creation=\
[unchecked] unchecked generic array creation for varargs parameter of type {0}
unchecked generic array creation for varargs parameter of type {0}
compiler.warn.varargs.non.reifiable.type=\
[varargs] Possible heap pollution from parameterized vararg type {0}
Possible heap pollution from parameterized vararg type {0}
compiler.warn.missing.deprecated.annotation=\
[dep-ann] deprecated item is not annotated with @Deprecated
deprecated item is not annotated with @Deprecated
compiler.warn.invalid.archive.file=\
[path] Unexpected file on path: {0}
Unexpected file on path: {0}
compiler.warn.unexpected.archive.file=\
[path] Unexpected extension for archive file: {0}
Unexpected extension for archive file: {0}
compiler.warn.div.zero=\
[divzero] division by zero
division by zero
compiler.warn.empty.if=\
[empty] empty statement after if
empty statement after if
compiler.warn.annotation.method.not.found=\
Cannot find annotation method ''{1}()'' in type ''{0}''
......@@ -838,7 +859,7 @@ compiler.warn.annotation.method.not.found.reason=\
Cannot find annotation method ''{1}()'' in type ''{0}'': {2}
compiler.warn.raw.class.use=\
[rawtypes] found raw type: {0}\n\
found raw type: {0}\n\
missing type parameters for generic class {1}
#####
......@@ -996,13 +1017,13 @@ compiler.misc.possible.loss.of.precision=\
possible loss of precision
compiler.misc.unchecked.assign=\
[unchecked] unchecked conversion
unchecked conversion
# compiler.misc.storecheck=\
# [unchecked] assignment might cause later store checks to fail
# assignment might cause later store checks to fail
# compiler.misc.unchecked=\
# [unchecked] assigned array cannot dynamically check its stores
# assigned array cannot dynamically check its stores
compiler.misc.unchecked.cast.to.type=\
[unchecked] unchecked cast
unchecked cast
compiler.misc.assignment.from.super-bound=\
assignment from super-bound type {0}
......@@ -1172,11 +1193,11 @@ compiler.err.override.incompatible.ret=\
return type {1} is not compatible with {2}
compiler.warn.override.unchecked.ret=\
[unchecked] {0}\n\
{0}\n\
return type requires unchecked conversion from {1} to {2}
compiler.warn.override.unchecked.thrown=\
[unchecked] {0}\n\
{0}\n\
overridden method does not throw {1}
## The following are all possible strings for the first argument ({0}) of the
......@@ -1217,6 +1238,10 @@ compiler.err.unsupported.underscore.lit=\
underscores in literals are not supported in -source {0}\n\
(use -source 7 or higher to enable underscores in literals)
compiler.err.automatic.resource.management.not.supported.in.source=\
automatic resource management is not supported in -source {0}\n\
(use -source 7 or higher to enable automatic resource management)
compiler.warn.enum.as.identifier=\
as of release 5, ''enum'' is a keyword, and may not be used as an identifier\n\
(use -source 5 or higher to use ''enum'' as a keyword)
......@@ -1263,7 +1288,7 @@ compiler.err.enums.not.supported.in.source=\
compiler.err.diamond.not.supported.in.source=\
diamond operator is not supported in -source {0}\n\
(use -source 7 or higher to enable multi-catch statement)
(use -source 7 or higher to enable diamond operator)
compiler.err.multicatch.not.supported.in.source=\
multi-catch statement is not supported in -source {0}\n\
......
......@@ -1021,10 +1021,15 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
public JCBlock body;
public List<JCCatch> catchers;
public JCBlock finalizer;
protected JCTry(JCBlock body, List<JCCatch> catchers, JCBlock finalizer) {
public List<JCTree> resources;
protected JCTry(List<JCTree> resources,
JCBlock body,
List<JCCatch> catchers,
JCBlock finalizer) {
this.body = body;
this.catchers = catchers;
this.finalizer = finalizer;
this.resources = resources;
}
@Override
public void accept(Visitor v) { v.visitTry(this); }
......@@ -1040,6 +1045,10 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
return v.visitTry(this, d);
}
@Override
public List<? extends JCTree> getResources() {
return resources;
}
@Override
public int getTag() {
return TRY;
}
......@@ -2162,6 +2171,10 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
JCCase Case(JCExpression pat, List<JCStatement> stats);
JCSynchronized Synchronized(JCExpression lock, JCBlock body);
JCTry Try(JCBlock body, List<JCCatch> catchers, JCBlock finalizer);
JCTry Try(List<JCTree> resources,
JCBlock body,
List<JCCatch> catchers,
JCBlock finalizer);
JCCatch Catch(JCVariableDecl param, JCBlock body);
JCConditional Conditional(JCExpression cond,
JCExpression thenpart,
......
......@@ -691,6 +691,19 @@ public class Pretty extends JCTree.Visitor {
public void visitTry(JCTry tree) {
try {
print("try ");
if (tree.resources.nonEmpty()) {
print("(");
boolean first = true;
for (JCTree var : tree.resources) {
if (!first) {
println();
indent();
}
printStat(var);
first = false;
}
print(") ");
}
printStat(tree.body);
for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
printStat(l.head);
......
......@@ -332,10 +332,11 @@ public class TreeCopier<P> implements TreeVisitor<JCTree,P> {
public JCTree visitTry(TryTree node, P p) {
JCTry t = (JCTry) node;
List<JCTree> resources = copy(t.resources, p);
JCBlock body = copy(t.body, p);
List<JCCatch> catchers = copy(t.catchers, p);
JCBlock finalizer = copy(t.finalizer, p);
return M.at(t.pos).Try(body, catchers, finalizer);
return M.at(t.pos).Try(resources, body, catchers, finalizer);
}
public JCTree visitParameterizedType(ParameterizedTypeTree node, P p) {
......
......@@ -269,7 +269,14 @@ public class TreeMaker implements JCTree.Factory {
}
public JCTry Try(JCBlock body, List<JCCatch> catchers, JCBlock finalizer) {
JCTry tree = new JCTry(body, catchers, finalizer);
return Try(List.<JCTree>nil(), body, catchers, finalizer);
}
public JCTry Try(List<JCTree> resources,
JCBlock body,
List<JCCatch> catchers,
JCBlock finalizer) {
JCTry tree = new JCTry(resources, body, catchers, finalizer);
tree.pos = pos;
return tree;
}
......@@ -486,7 +493,7 @@ public class TreeMaker implements JCTree.Factory {
public JCModifiers Modifiers(long flags, List<JCAnnotation> annotations) {
JCModifiers tree = new JCModifiers(flags, annotations);
boolean noFlags = (flags & Flags.ModifierFlags) == 0;
boolean noFlags = (flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0;
tree.pos = (noFlags && annotations.isEmpty()) ? Position.NOPOS : pos;
return tree;
}
......
......@@ -147,6 +147,7 @@ public class TreeScanner extends Visitor {
}
public void visitTry(JCTry tree) {
scan(tree.resources);
scan(tree.body);
scan(tree.catchers);
scan(tree.finalizer);
......
......@@ -212,6 +212,7 @@ public class TreeTranslator extends JCTree.Visitor {
}
public void visitTry(JCTry tree) {
tree.resources = translate(tree.resources);
tree.body = translate(tree.body);
tree.catchers = translateCatchers(tree.catchers);
tree.finalizer = translate(tree.finalizer);
......
......@@ -38,6 +38,7 @@ import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.DiagnosticPart;
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.MultilineLimit;
import com.sun.tools.javac.api.DiagnosticFormatter.PositionKind;
import com.sun.tools.javac.api.Formattable;
import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.Printer;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Type;
......@@ -285,6 +286,13 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
return buf.toString();
}
protected String formatLintCategory(JCDiagnostic d, Locale l) {
LintCategory lc = d.getLintCategory();
if (lc == null)
return "";
return localize(l, "compiler.warn.lintOption", lc.option);
}
/**
* Converts a String into a locale-dependent representation accordingly to a given locale.
*
......
......@@ -29,6 +29,7 @@ import java.util.HashMap;
import java.util.Map;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
......@@ -112,6 +113,16 @@ public abstract class AbstractLog {
report(diags.warning(source, null, key, args));
}
/** Report a lint warning, unless suppressed by the -nowarn option or the
* maximum number of warnings has been reached.
* @param lc The lint category for the diagnostic
* @param key The key for the localized warning message.
* @param args Fields of the warning message.
*/
public void warning(LintCategory lc, String key, Object ... args) {
report(diags.warning(lc, key, args));
}
/** Report a warning, unless suppressed by the -nowarn option or the
* maximum number of warnings has been reached.
* @param pos The source position at which to report the warning.
......@@ -122,6 +133,17 @@ public abstract class AbstractLog {
report(diags.warning(source, pos, key, args));
}
/** Report a lint warning, unless suppressed by the -nowarn option or the
* maximum number of warnings has been reached.
* @param lc The lint category for the diagnostic
* @param pos The source position at which to report the warning.
* @param key The key for the localized warning message.
* @param args Fields of the warning message.
*/
public void warning(LintCategory lc, DiagnosticPosition pos, String key, Object ... args) {
report(diags.warning(lc, source, pos, key, args));
}
/** Report a warning, unless suppressed by the -nowarn option or the
* maximum number of warnings has been reached.
* @param pos The source position at which to report the warning.
......@@ -141,6 +163,16 @@ public abstract class AbstractLog {
report(diags.mandatoryWarning(source, pos, key, args));
}
/** Report a warning.
* @param lc The lint category for the diagnostic
* @param pos The source position at which to report the warning.
* @param key The key for the localized warning message.
* @param args Fields of the warning message.
*/
public void mandatoryWarning(LintCategory lc, DiagnosticPosition pos, String key, Object ... args) {
report(diags.mandatoryWarning(lc, source, pos, key, args));
}
/** Provide a non-fatal notification, unless suppressed by the -nowarn option.
* @param key The key for the localized notification message.
* @param args Fields of the notint an error or warning message:
......
......@@ -73,7 +73,6 @@ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
* @param opts list of command-line options
* @param msgs JavacMessages object used for i18n
*/
@SuppressWarnings("fallthrough")
public BasicDiagnosticFormatter(Options options, JavacMessages msgs) {
super(msgs, new BasicConfiguration(options));
}
......@@ -189,6 +188,8 @@ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
}
case 'm':
return formatMessage(d, l);
case 'L':
return formatLintCategory(d, l);
case '_':
return " ";
case '%':
......@@ -244,9 +245,9 @@ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
setFormat(BasicFormatKind.DEFAULT_POS_FORMAT, formats[0]);
}
}
String sourcePosition = null;
if ((((sourcePosition = options.get("sourcePosition")) != null)) &&
sourcePosition.equals("bottom"))
String srcPos = null;
if ((((srcPos = options.get("sourcePosition")) != null)) &&
srcPos.equals("bottom"))
setSourcePosition(SourcePosition.BOTTOM);
else
setSourcePosition(SourcePosition.AFTER_SUMMARY);
......@@ -289,9 +290,9 @@ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
//where
private void initFormat() {
availableFormats = new HashMap<BasicFormatKind, String>();
setFormat(BasicFormatKind.DEFAULT_POS_FORMAT, "%f:%l:%_%t%m");
setFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT, "%p%m");
setFormat(BasicFormatKind.DEFAULT_CLASS_FORMAT, "%f:%_%t%m");
setFormat(BasicFormatKind.DEFAULT_POS_FORMAT, "%f:%l:%_%t%L%m");
setFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT, "%p%L%m");
setFormat(BasicFormatKind.DEFAULT_CLASS_FORMAT, "%f:%_%t%L%m");
}
//where
private void initIndentation() {
......
......@@ -32,6 +32,7 @@ import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.api.DiagnosticFormatter;
import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.tree.JCTree;
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
......@@ -82,86 +83,143 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
*/
public JCDiagnostic error(
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
return create(ERROR, true, source, pos, key, args);
return create(ERROR, null, true, source, pos, key, args);
}
/**
* Create a warning diagnostic that will not be hidden by the -nowarn or -Xlint:none options.
* @param source The source of the compilation unit, if any, in which to report the warning.
* @param pos The source position at which to report the warning.
* @param key The key for the localized error message.
* @param args Fields of the error message.
* @param key The key for the localized warning message.
* @param args Fields of the warning message.
* @see MandatoryWarningHandler
*/
public JCDiagnostic mandatoryWarning(
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
return create(WARNING, true, source, pos, key, args);
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
return create(WARNING, null, true, source, pos, key, args);
}
/**
* Create a warning diagnostic.
* Create a warning diagnostic that will not be hidden by the -nowarn or -Xlint:none options.
* @param lc The lint category for the diagnostic
* @param source The source of the compilation unit, if any, in which to report the warning.
* @param pos The source position at which to report the warning.
* @param key The key for the localized warning message.
* @param args Fields of the warning message.
* @see MandatoryWarningHandler
*/
public JCDiagnostic mandatoryWarning(
LintCategory lc,
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
return create(WARNING, lc, true, source, pos, key, args);
}
/**
* Create a warning diagnostic.
* @param lc The lint category for the diagnostic
* @param key The key for the localized error message.
* @param args Fields of the error message.
* @param args Fields of the warning message.
* @see MandatoryWarningHandler
*/
public JCDiagnostic warning(
LintCategory lc, String key, Object... args) {
return create(WARNING, lc, false, null, null, key, args);
}
/**
* Create a warning diagnostic.
* @param source The source of the compilation unit, if any, in which to report the warning.
* @param pos The source position at which to report the warning.
* @param key The key for the localized warning message.
* @param args Fields of the warning message.
*/
public JCDiagnostic warning(
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
return create(WARNING, false, source, pos, key, args);
return create(WARNING, null, false, source, pos, key, args);
}
/**
* Create a warning diagnostic.
* @param lc The lint category for the diagnostic
* @param source The source of the compilation unit, if any, in which to report the warning.
* @param pos The source position at which to report the warning.
* @param key The key for the localized warning message.
* @param args Fields of the warning message.
* @see MandatoryWarningHandler
*/
public JCDiagnostic warning(
LintCategory lc, DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
return create(WARNING, lc, false, source, pos, key, args);
}
/**
* Create a note diagnostic that will not be hidden by the -nowarn or -Xlint:none options.
* @param key The key for the localized error message.
* @param args Fields of the error message.
* @param key The key for the localized message.
* @param args Fields of the message.
* @see MandatoryWarningHandler
*/
public JCDiagnostic mandatoryNote(DiagnosticSource source, String key, Object... args) {
return create(NOTE, true, source, null, key, args);
return create(NOTE, null, true, source, null, key, args);
}
/**
* Create a note diagnostic.
* @param key The key for the localized error message.
* @param args Fields of the error message.
* @param args Fields of the message.
*/
public JCDiagnostic note(String key, Object... args) {
return create(NOTE, false, null, null, key, args);
return create(NOTE, null, false, null, null, key, args);
}
/**
* Create a note diagnostic.
* @param source The source of the compilation unit, if any, in which to report the note.
* @param pos The source position at which to report the note.
* @param key The key for the localized error message.
* @param args Fields of the error message.
* @param key The key for the localized message.
* @param args Fields of the message.
*/
public JCDiagnostic note(
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
return create(NOTE, false, source, pos, key, args);
return create(NOTE, null, false, source, pos, key, args);
}
/**
* Create a fragment diagnostic, for use as an argument in other diagnostics
* @param key The key for the localized error message.
* @param args Fields of the error message.
* @param key The key for the localized message.
* @param args Fields of the message.
*/
public JCDiagnostic fragment(String key, Object... args) {
return create(FRAGMENT, false, null, null, key, args);
return create(FRAGMENT, null, false, null, null, key, args);
}
/**
* Create a new diagnostic of the given kind, which is not mandatory and which has
* no lint category.
* @param kind The diagnostic kind
* @param ls The lint category, if applicable, or null
* @param source The source of the compilation unit, if any, in which to report the message.
* @param pos The source position at which to report the message.
* @param key The key for the localized message.
* @param args Fields of the message.
*/
public JCDiagnostic create(
DiagnosticType kind, DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
return create(kind, null, false, source, pos, key, args);
}
/**
* Create a new diagnostic of the given kind.
* @param kind The diagnostic kind
* @param lc The lint category, if applicable, or null
* @param isMandatory is diagnostic mandatory?
* @param source The source of the compilation unit, if any, in which to report the note.
* @param pos The source position at which to report the note.
* @param key The key for the localized error message.
* @param args Fields of the error message.
* @param source The source of the compilation unit, if any, in which to report the message.
* @param pos The source position at which to report the message.
* @param key The key for the localized message.
* @param args Fields of the message.
*/
public JCDiagnostic create(
DiagnosticType kind, boolean isMandatory, DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
return new JCDiagnostic(formatter, kind, isMandatory, source, pos, qualify(kind, key), args);
DiagnosticType kind, LintCategory lc, boolean isMandatory, DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
return new JCDiagnostic(formatter, kind, lc, isMandatory, source, pos, qualify(kind, key), args);
}
protected String qualify(DiagnosticType t, String key) {
......@@ -181,6 +239,7 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
public static JCDiagnostic fragment(String key, Object... args) {
return new JCDiagnostic(getFragmentFormatter(),
FRAGMENT,
null,
false,
null,
null,
......@@ -274,30 +333,34 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
private final int line;
private final int column;
private final String key;
protected Object[] args;
private boolean mandatory;
protected final Object[] args;
private final boolean mandatory;
private final LintCategory lintCategory;
/**
* Create a diagnostic object.
* @param messages the resource for localized messages
* @param fomatter the formatter to use for the diagnostic
* @param dt the type of diagnostic
* @param name the name of the source file, or null if none.
* @param lc the lint category for the diagnostic
* @param source the name of the source file, or null if none.
* @param pos the character offset within the source file, if given.
* @param key a resource key to identify the text of the diagnostic
* @param args arguments to be included in the text of the diagnostic
*/
protected JCDiagnostic(DiagnosticFormatter<JCDiagnostic> formatter,
DiagnosticType dt,
LintCategory lc,
boolean mandatory,
DiagnosticSource source,
DiagnosticPosition pos,
String key,
Object ... args) {
Object... args) {
if (source == null && pos != null && pos.getPreferredPosition() != Position.NOPOS)
throw new IllegalArgumentException();
this.defaultFormatter = formatter;
this.type = dt;
this.lintCategory = lc;
this.mandatory = mandatory;
this.source = source;
this.position = pos;
......@@ -341,6 +404,20 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
return mandatory;
}
/**
* Check whether this diagnostic has an associated lint category.
*/
public boolean hasLintCategory() {
return (lintCategory != null);
}
/**
* Get the associated lint category, or null if none.
*/
public LintCategory getLintCategory() {
return lintCategory;
}
/**
* Get the name of the source file referred to by this diagnostic.
* @return the name of the source referred to with this diagnostic, or null if none
......@@ -467,6 +544,7 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
public MultilineDiagnostic(JCDiagnostic other, List<JCDiagnostic> subdiagnostics) {
super(other.defaultFormatter,
other.getType(),
other.getLintCategory(),
other.isMandatory(),
other.getDiagnosticSource(),
other.position,
......
......@@ -269,7 +269,7 @@ public class Log extends AbstractLog {
*/
public void prompt() {
if (promptOnError) {
System.err.println(getLocalizedString("resume.abort"));
System.err.println(localize("resume.abort"));
char ch;
try {
while (true) {
......@@ -317,8 +317,23 @@ public class Log extends AbstractLog {
if (msg.length() != 0) writer.println(msg);
}
/** Print the text of a message to the errWriter stream,
* translating newlines appropriately for the platform.
*/
public void printErrLines(String key, Object... args) {
printLines(errWriter, localize(key, args));
}
/** Print the text of a message to the noticeWriter stream,
* translating newlines appropriately for the platform.
*/
public void printNoteLines(String key, Object... args) {
printLines(noticeWriter, localize(key, args));
}
protected void directError(String key, Object... args) {
printLines(errWriter, getLocalizedString(key, args));
printErrLines(key, args);
errWriter.flush();
}
......@@ -426,6 +441,8 @@ public class Log extends AbstractLog {
}
/** Find a localized string in the resource bundle.
* Because this method is static, it ignores the locale.
* Use localize(key, args) when possible.
* @param key The key for the localized string.
* @param args Fields to substitute into the string.
*/
......@@ -433,6 +450,14 @@ public class Log extends AbstractLog {
return JavacMessages.getDefaultLocalizedString("compiler.misc." + key, args);
}
/** Find a localized string in the resource bundle.
* @param key The key for the localized string.
* @param args Fields to substitute into the string.
*/
public String localize(String key, Object... args) {
return messages.getLocalizedString("compiler.misc." + key, args);
}
/***************************************************************************
* raw error messages without internationalization; used for experimentation
* and quick prototyping
......
......@@ -29,6 +29,7 @@ import java.util.HashSet;
import java.util.Set;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
......@@ -105,13 +106,16 @@ public class MandatoryWarningHandler {
* True if mandatory warnings and notes are being enforced.
* @param prefix A common prefix for the set of message keys for
* the messages that may be generated.
* @param lc An associated lint category for the warnings, or null if none.
*/
public MandatoryWarningHandler(Log log, boolean verbose,
boolean enforceMandatory, String prefix) {
boolean enforceMandatory, String prefix,
LintCategory lc) {
this.log = log;
this.verbose = verbose;
this.prefix = prefix;
this.enforceMandatory = enforceMandatory;
this.lintCategory = lc;
}
/**
......@@ -234,16 +238,23 @@ public class MandatoryWarningHandler {
*/
private final boolean enforceMandatory;
/**
* A LintCategory to be included in point-of-use diagnostics to indicate
* how messages might be suppressed (i.e. with @SuppressWarnings).
*/
private final LintCategory lintCategory;
/**
* Reports a mandatory warning to the log. If mandatory warnings
* are not being enforced, treat this as an ordinary warning.
*/
private void logMandatoryWarning(DiagnosticPosition pos, String msg,
Object... args) {
// Note: the following log methods are safe if lintCategory is null.
if (enforceMandatory)
log.mandatoryWarning(pos, msg, args);
log.mandatoryWarning(lintCategory, pos, msg, args);
else
log.warning(pos, msg, args);
log.warning(lintCategory, pos, msg, args);
}
/**
......
......@@ -148,6 +148,8 @@ public class Names {
public final Name getDeclaringClass;
public final Name ex;
public final Name finalize;
public final Name java_lang_AutoCloseable;
public final Name close;
public final Name.Table table;
......@@ -263,6 +265,9 @@ public class Names {
getDeclaringClass = fromString("getDeclaringClass");
ex = fromString("ex");
finalize = fromString("finalize");
java_lang_AutoCloseable = fromString("java.lang.AutoCloseable");
close = fromString("close");
}
protected Name.Table createTable(Options options) {
......
/*
* @test /nodynamiccopyright/
* @bug 4980495 6260444
* @compile/fail/ref=Test.out -XDstdout -XDrawDiagnostics Test.java p1/A1.java p2/A2.java
* @compile/fail/ref=Test.out -XDrawDiagnostics Test.java p1/A1.java p2/A2.java
*/
package p;
......
/*
* @test /nodynamiccopyright/
* @bug 4980495 6260444
* @compile/fail/ref=Test.out -XDstdout -XDrawDiagnostics Test.java p1/A1.java p2/A2.java
* @compile/fail/ref=Test.out -XDrawDiagnostics Test.java p1/A1.java p2/A2.java
*
*/
......
/*
* @test (important: no SCCS keywords to affect offsets in golden file.) /nodynamiccopyright/
* @bug 6304921
* @compile/fail/ref=T6304921.out -XDstdout -XDcompilePolicy=bytodo -XDrawDiagnostics -Xjcov -Xlint:all,-path -Werror T6304921.java
* @compile/fail/ref=T6304921.out -XDcompilePolicy=bytodo -XDrawDiagnostics -Xjcov -Xlint:all,-path -Werror T6304921.java
*/
import java.util.ArrayList;
......
......@@ -3,7 +3,7 @@
* @bug 6330920
* @summary Verify that javac doesn't duplicate method error on method with error
* @author Peter von der Ah\u00e9
* @compile/fail/ref=T6330920.out -XDstdout -XDrawDiagnostics T6330920.java
* @compile/fail/ref=T6330920.out -XDrawDiagnostics T6330920.java
*/
public class T6330920 {
......
......@@ -3,7 +3,7 @@
* @bug 6491592
* @summary Compiler crashes on assignment operator
* @author alex.buckley@...
* @compile/fail/ref=T6491592.out -XDstdout -XDrawDiagnostics T6491592.java
* @compile/fail/ref=T6491592.out -XDrawDiagnostics T6491592.java
*/
public class T6491592 {
......
......@@ -3,7 +3,7 @@
* @bug 6717241
* @summary some diagnostic argument is prematurely converted into a String object
* @author Maurizio Cimadamore
* @compile/fail/ref=T6717241a.out -XDstdout -XDrawDiagnostics T6717241a.java
* @compile/fail/ref=T6717241a.out -XDrawDiagnostics T6717241a.java
*/
class T6717241a<X extends Object & java.io.Serializable> {
......
......@@ -3,7 +3,7 @@
* @bug 6717241
* @summary some diagnostic argument is prematurely converted into a String object
* @author Maurizio Cimadamore
* @compile/fail/ref=T6717241b.out -XDstdout -XDrawDiagnostics T6717241b.java
* @compile/fail/ref=T6717241b.out -XDrawDiagnostics T6717241b.java
*/
class T6717241b {
......
......@@ -28,7 +28,7 @@
* file are correct, including those within InnerClasses attributes.
* @author John Rose (jrose). Entered as a regression test by Bill Maddox (maddox).
*
* @compile/ref=ClassModifiers.out -XDstdout -XDdumpmodifiers=ci ClassModifiers.java
* @compile/ref=ClassModifiers.out -XDdumpmodifiers=ci ClassModifiers.java
*
*/
......
......@@ -26,7 +26,7 @@
* @bug 4249112 4785453
* @summary Verify that implicit member modifiers are set correctly.
*
* @compile/ref=MemberModifiers.out -XDstdout -source 1.4 -target 1.4.2 -XDdumpmodifiers=cfm MemberModifiers.java
* @compile/ref=MemberModifiers.out -source 1.4 -target 1.4.2 -XDdumpmodifiers=cfm MemberModifiers.java
*/
// Currently, we check only that members of final classes are not final.
......
......@@ -4,7 +4,7 @@
* @summary Test that recursive 'extends' and 'implements' clauses are detected
* and disallowed.
*
* @compile/fail/ref=CyclicInheritance.out -XDrawDiagnostics -XDstdout CyclicInheritance.java
* @compile/fail/ref=CyclicInheritance.out -XDrawDiagnostics CyclicInheritance.java
*/
......
......@@ -2,7 +2,7 @@
* @test /nodynamiccopyright/
* @bug 6183529
* @summary javac gives warnings instead of errors on non-ASCII digits
* @compile/fail/ref=Digits.out -XDstdout -XDrawDiagnostics Digits.java
* @compile/fail/ref=Digits.out -XDrawDiagnostics Digits.java
*/
class Digits
......
......@@ -3,7 +3,7 @@
* @bug 4336282 4785453
* @summary Verify that extending an erray class does not crash the compiler.
*
* @compile/fail/ref=ExtendArray.out -XDstdout -XDrawDiagnostics ExtendArray.java
* @compile/fail/ref=ExtendArray.out -XDrawDiagnostics ExtendArray.java
*/
// Note that an error is expected, but not a crash.
......
......@@ -3,7 +3,7 @@
* @bug 4087314 4087314 4785453
* @summary Test access checking within 'extends' and 'implements' clause.
* @author William Maddox (maddox)
* @compile/fail/ref=ExtendsAccess.out -XDrawDiagnostics -XDstdout ExtendsAccess.java
* @compile/fail/ref=ExtendsAccess.out -XDrawDiagnostics ExtendsAccess.java
*/
/*
......
......@@ -4,7 +4,7 @@
* @summary strictfp may not be used with constructors
* @author David Stoutamire (dps)
*
* @compile/fail/ref=BadConstructorModifiers.out -XDrawDiagnostics -XDstdout BadConstructorModifiers.java
* @compile/fail/ref=BadConstructorModifiers.out -XDrawDiagnostics BadConstructorModifiers.java
*/
public class BadConstructorModifiers {
......
......@@ -4,7 +4,7 @@
* @summary javac crash when declare an annotation type illegally
*
* @compile/fail IllegalAnnotation.java
* @compile/fail/ref=IllegalAnnotation.out -XDdev -XDrawDiagnostics -XDstdout IllegalAnnotation.java
* @compile/fail/ref=IllegalAnnotation.out -XDdev -XDrawDiagnostics IllegalAnnotation.java
*/
class IllegalAnnotation {
{
......
......@@ -4,7 +4,7 @@
* @summary Verify rejection of illegal static variables in inner classes.
* @author William Maddox (maddox)
*
* @compile/fail/ref=InnerNamedConstant_2.out -XDrawDiagnostics -XDstdout InnerNamedConstant_2.java
* @compile/fail/ref=InnerNamedConstant_2.out -XDrawDiagnostics InnerNamedConstant_2.java
*/
public class InnerNamedConstant_2 {
......
......@@ -4,7 +4,7 @@
* @summary Verify that invalid access modifiers on interface members don't cause crash.
* @author maddox
*
* @compile/fail/ref=InterfaceMemberClassModifiers.out -XDstdout -XDdiags=%b:%l:%_%m InterfaceMemberClassModifiers.java
* @compile/fail/ref=InterfaceMemberClassModifiers.out -XDdiags=%b:%l:%_%m InterfaceMemberClassModifiers.java
*/
public interface InterfaceMemberClassModifiers {
......
......@@ -4,7 +4,7 @@
* @summary Verify that a local class cannot be redefined within its scope.
* @author William Maddox (maddox)
*
* @compile/fail/ref=LocalClasses_2.out -XDrawDiagnostics -XDstdout LocalClasses_2.java
* @compile/fail/ref=LocalClasses_2.out -XDrawDiagnostics LocalClasses_2.java
*/
class LocalClasses_2 {
......
......@@ -4,7 +4,7 @@
* @summary Interface names for classes in the same scope should not
* cause the compiler to crash.
*
* @compile/fail/ref=NameCollision.out -XDrawDiagnostics -XDstdout NameCollision.java
* @compile/fail/ref=NameCollision.out -XDrawDiagnostics NameCollision.java
*/
// The test fails if the compiler crashes.
......
......@@ -4,7 +4,7 @@
* @summary Verify that an inner class cannot have the same simple name as an enclosing one.
* @author William Maddox (maddox)
*
* @compile/fail/ref=NestedInnerClassNames.out -XDrawDiagnostics -XDstdout NestedInnerClassNames.java
* @compile/fail/ref=NestedInnerClassNames.out -XDrawDiagnostics NestedInnerClassNames.java
*/
/*
......
......@@ -3,7 +3,7 @@
@author dps
@summary field: instance access through types is not allowed
@compile/fail/ref=NonStaticFieldExpr1.out -XDrawDiagnostics -XDstdout NonStaticFieldExpr1.java
@compile/fail/ref=NonStaticFieldExpr1.out -XDrawDiagnostics NonStaticFieldExpr1.java
*/
class NonStaticFieldExpr1 {
public int x;
......
......@@ -3,7 +3,7 @@
@author dps
@summary method: instance access through types is not allowed
@compile/fail/ref=NonStaticFieldExpr2.out -XDrawDiagnostics -XDstdout NonStaticFieldExpr2.java
@compile/fail/ref=NonStaticFieldExpr2.out -XDrawDiagnostics NonStaticFieldExpr2.java
*/
class NonStaticFieldExpr2 {
......
......@@ -3,7 +3,7 @@
@author dps
@summary class: instance access through types is not allowed
@compile/fail/ref=NonStaticFieldExpr3.out -XDrawDiagnostics -XDstdout NonStaticFieldExpr3.java
@compile/fail/ref=NonStaticFieldExpr3.out -XDrawDiagnostics NonStaticFieldExpr3.java
*/
class NonStaticFieldExpr3 {
......
......@@ -4,7 +4,7 @@
* @summary "attemping to assign weaker access" message doesn't give method line number
* @author Neal Gafter
*
* @compile/fail/ref=OverridePosition.out -XDstdout -XDrawDiagnostics OverridePosition.java
* @compile/fail/ref=OverridePosition.out -XDrawDiagnostics OverridePosition.java
*/
package T4524388;
......
......@@ -7,7 +7,7 @@
*
* @compile pack1/P1.java
* @compile pack1/P2.java
* @compile/fail/ref=QualifiedAccess_1.out -XDrawDiagnostics -XDstdout QualifiedAccess_1.java
* @compile/fail/ref=QualifiedAccess_1.out -XDrawDiagnostics QualifiedAccess_1.java
*/
import pack1.P1;
......
......@@ -7,7 +7,7 @@
*
* @compile pack1/P1.java
* @compile pack1/P2.java
* @compile/fail/ref=QualifiedAccess_2.out -XDrawDiagnostics -XDstdout QualifiedAccess_2.java
* @compile/fail/ref=QualifiedAccess_2.out -XDrawDiagnostics QualifiedAccess_2.java
*/
import pack1.P1;
......
......@@ -5,7 +5,7 @@
* the type to which a component member belongs be accessible in qualified
* names.
*
* @compile/fail/ref=QualifiedAccess_3.out -XDrawDiagnostics -XDstdout QualifiedAccess_3.java
* @compile/fail/ref=QualifiedAccess_3.out -XDrawDiagnostics QualifiedAccess_3.java
*/
import pack1.P1;
......
......@@ -3,7 +3,7 @@
* @bug 6827009
* @summary Check for case labels of different types.
* @compile/fail -source 6 BadlyTypedLabel1.java
* @compile/fail/ref=BadlyTypedLabel1.out -XDstdout -XDrawDiagnostics BadlyTypedLabel1.java
* @compile/fail/ref=BadlyTypedLabel1.out -XDrawDiagnostics BadlyTypedLabel1.java
*/
class BadlyTypedLabel1 {
String m(String s) {
......
......@@ -3,7 +3,7 @@
* @bug 6827009
* @summary Check for case lables of different types.
* @compile/fail -source 6 BadlyTypedLabel2.java
* @compile/fail/ref=BadlyTypedLabel2.out -XDstdout -XDrawDiagnostics BadlyTypedLabel2.java
* @compile/fail/ref=BadlyTypedLabel2.out -XDrawDiagnostics BadlyTypedLabel2.java
*/
import static java.math.RoundingMode.*;
......
......@@ -3,7 +3,7 @@
* @bug 6827009
* @summary Check for non-constant case labels.
* @compile/fail -source 6 NonConstantLabel.java
* @compile/fail/ref=NonConstantLabel.out -XDstdout -XDrawDiagnostics NonConstantLabel.java
* @compile/fail/ref=NonConstantLabel.out -XDrawDiagnostics NonConstantLabel.java
*/
class NonConstantLabel {
String m(String s) {
......
......@@ -3,7 +3,7 @@
* @bug 6827009
* @summary Check for repeated string case labels.
* @compile/fail -source 6 RepeatedStringCaseLabels1.java
* @compile/fail/ref=RSCL1.out -XDstdout -XDrawDiagnostics RepeatedStringCaseLabels1.java
* @compile/fail/ref=RSCL1.out -XDrawDiagnostics RepeatedStringCaseLabels1.java
*/
class RepeatedStringCaseLabels1 {
String m(String s) {
......
......@@ -3,7 +3,7 @@
* @bug 6827009
* @summary Check for repeated string case labels.
* @compile/fail -source 6 RepeatedStringCaseLabels2.java
* @compile/fail/ref=RSCL2.out -XDstdout -XDrawDiagnostics RepeatedStringCaseLabels2.java
* @compile/fail/ref=RSCL2.out -XDrawDiagnostics RepeatedStringCaseLabels2.java
*/
class RepeatedStringCaseLabels2 {
String m(String s) {
......
......@@ -3,7 +3,7 @@
@summary Verify that ClassModifier "synchronized" is not allowed.
@author dps
@compile/fail/ref=SynchronizedClass.out -XDrawDiagnostics -XDstdout SynchronizedClass.java
@compile/fail/ref=SynchronizedClass.out -XDrawDiagnostics SynchronizedClass.java
*/
public synchronized class SynchronizedClass { } // ERROR
......@@ -3,7 +3,7 @@
* @bug 4093617
* @summary Object has no superclass
* @author Peter von der Ah\u00e9
* @compile/fail/ref=T4093617.out -XDstdout -XDrawDiagnostics T4093617.java
* @compile/fail/ref=T4093617.out -XDrawDiagnostics T4093617.java
*/
package java.lang;
......
......@@ -2,7 +2,7 @@
* @test /nodynamiccopyright/
* @bug 4906100
* @summary detect empty statement after if
* @compile/ref=T4906100.out -XDstdout -XDrawDiagnostics -Xlint:empty T4906100.java
* @compile/ref=T4906100.out -XDrawDiagnostics -Xlint:empty T4906100.java
*/
class T4906100 {
......
......@@ -3,7 +3,7 @@
* @bug 4994049
* @summary Improved diagnostics while parsing enums
* @author Peter von der Ah\u00e9
* @compile/fail/ref=T4994049.out -XDstdout -XDrawDiagnostics T4994049.java
* @compile/fail/ref=T4994049.out -XDrawDiagnostics T4994049.java
*/
public enum T4994049 {
......
......@@ -3,7 +3,7 @@
* @bug 5003235
* @summary Private inner class accessible from subclasses
* @author Peter von der Ah\u00e9
* @compile/fail/ref=T5003235a.out -XDstdout -XDdiags=%b:%l:%_%m T5003235a.java
* @compile/fail/ref=T5003235a.out -XDdiags=%b:%l:%_%m T5003235a.java
*/
class Super {
......
......@@ -3,7 +3,7 @@
* @bug 5003235
* @summary Accessibility of private inner class
* @author Peter von der Ah\u00e9
* @compile/fail/ref=T5003235b.out -XDstdout -XDdiags=%b:%l:%_%m T5003235b.java
* @compile/fail/ref=T5003235b.out -XDdiags=%b:%l:%_%m T5003235b.java
*/
class Outer {
......
......@@ -3,7 +3,7 @@
* @bug 5003235
* @summary Access to private inner classes
* @author Peter von der Ah\u00e9
* @compile/fail/ref=T5003235c.out -XDstdout -XDrawDiagnostics T5003235c.java
* @compile/fail/ref=T5003235c.out -XDrawDiagnostics T5003235c.java
*/
class T5003235c {
......
......@@ -3,7 +3,7 @@
* @bug 5024091
* @summary AssertionError shouldn't be thrown
* @author Wei Tao
* @compile/fail/ref=T5024091.out -XDfailcomplete=java.lang.StringBuilder -XDdev -XDstdout -XDrawDiagnostics T5024091.java
* @compile/fail/ref=T5024091.out -XDfailcomplete=java.lang.StringBuilder -XDdev -XDrawDiagnostics T5024091.java
*/
public class T5024091 {
......
/*
* @test /nodynamiccopyright/
* @bug 5048776
* @compile/ref=T5048776a.out -XDstdout -XDrawDiagnostics T5048776.java
* @compile/ref=T5048776b.out -XDstdout -XDrawDiagnostics -Xlint:all,-path T5048776.java
* @compile/ref=T5048776a.out -XDrawDiagnostics T5048776.java
* @compile/ref=T5048776b.out -XDrawDiagnostics -Xlint:all,-path T5048776.java
*/
class A1 {
void foo(Object[] args) { }
......
......@@ -2,8 +2,8 @@
* @test /nodynamiccopyright/
* @bug 6214885
* @summary This test exercises features provided by the new internal Diagnostics API
* @compile/fail/ref=T6214885a.out -XDstdout -XDdiags=%b:%l%_%t%m|%p%m T6214885.java
* @compile/fail/ref=T6214885b.out -XDstdout -XDdiags=%b:%l:%c%_%t%m|%p%m T6214885.java
* @compile/fail/ref=T6214885a.out -XDdiags=%b:%l%_%t%m|%p%m T6214885.java
* @compile/fail/ref=T6214885b.out -XDdiags=%b:%l:%c%_%t%m|%p%m T6214885.java
*/
class T6214885
{
......
......@@ -3,7 +3,7 @@
* @bug 6224167
* @summary misleading error message when both array and varargs
* methods are defined
* @compile/fail/ref=T6224167.out -XDstdout -XDrawDiagnostics T6224167.java
* @compile/fail/ref=T6224167.out -XDrawDiagnostics T6224167.java
*/
class T6224167
{
......
......@@ -3,7 +3,7 @@
* @bug 6227617
* @summary Lint option for redundant casts
* @compile -Werror T6227617.java
* @compile/ref=T6227617.out -XDstdout -XDrawDiagnostics -Xlint:cast T6227617.java
* @compile/ref=T6227617.out -XDrawDiagnostics -Xlint:cast T6227617.java
*/
import java.util.HashMap;
import java.util.Map;
......
/*
* @test /nodynamiccopyright/
* @bug 6230128
* @compile/fail/ref=T6230128.out -XDstdout -XDrawDiagnostics T6230128.java
* @compile/fail/ref=T6230128.out -XDrawDiagnostics T6230128.java
*/
class A1 {
public void foo(Object[] args) { }
......
......@@ -4,7 +4,7 @@
* @summary Crash in com.sun.tools.javac.comp.Attr.visitNewClass:1352
* @author Peter von der Ah\u00e9
* @compile/fail -XDdev T6231847.java
* @compile/fail/ref=T6231847.out -XDdev -XDrawDiagnostics -XDstdout T6231847.java
* @compile/fail/ref=T6231847.out -XDdev -XDrawDiagnostics T6231847.java
*/
class T6231847 {
......
......@@ -2,7 +2,7 @@
* @test /nodynamiccopyright/
* @bug 6241723
* @summary compiler can miss some references to at-Deprecated classes
* @compile/fail/ref=T6241723.out -XDstdout -XDrawDiagnostics -Xlint:deprecation -Werror T6241723.java
* @compile/fail/ref=T6241723.out -XDrawDiagnostics -Xlint:deprecation -Werror T6241723.java
*/
@Deprecated class A1
......
/*
* @test /nodynamiccopyright/
* @bug 6245591
* @compile/ref=T6245591.out -XDstdout -XDrawDiagnostics -Xlint:all,-path T6245591.java
* @compile/ref=T6245591.out -XDrawDiagnostics -Xlint:all,-path T6245591.java
*/
enum Season {
/** @deprecated */
......
/*
* @test /nodynamiccopyright/
* @bug 6247324
* @compile/fail/ref=T6247324.out -XDrawDiagnostics -XDstdout -Xlint -Xlint:-path T6247324.java
* @compile/fail/ref=T6247324.out -XDrawDiagnostics -Xlint -Xlint:-path T6247324.java
*/
class Pair<X,Y> {
private X x;
......
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test 6403456
* @summary javax.tools.JavaCompilerTool.getStandardFileManager().list() includes directories
*/
import javax.tools.*;
import java.util.*;
import java.io.*;
import static javax.tools.JavaFileObject.Kind;
public class T6340549 {
public static void main(String... args) throws Exception {
// Ensure a directory exists
File dir = new File("temp" + args.hashCode());
if (!dir.exists())
dir.mkdir();
if (!dir.isDirectory())
throw new AssertionError("Not a directory " + dir);
try {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager jfm = compiler.getStandardFileManager(null, null, null);
jfm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(new File(".")));
for (JavaFileObject jfo : jfm.list(StandardLocation.CLASS_PATH,
"", EnumSet.of(Kind.OTHER), false)) {
if (new File(jfo.getName()).isDirectory()) {
throw new AssertionError("Found directory: " + jfo);
}
}
} finally {
dir.delete(); // cleanup
}
}
}
......@@ -3,13 +3,13 @@
* @bug 6394563
* @summary javac ignores -nowarn switch in 1.5.0_06 for deprecation warnings
*
* @compile/ref=T6394563.note.out -XDstdout -XDrawDiagnostics -nowarn T6394563.java
* @compile/ref=T6394563.note.out -XDstdout -XDrawDiagnostics -nowarn -source 1.5 T6394563.java
* @compile/ref=T6394563.empty.out -XDstdout -XDrawDiagnostics -nowarn -source 1.4 T6394563.java
* @compile/ref=T6394563.note.out -XDrawDiagnostics -nowarn T6394563.java
* @compile/ref=T6394563.note.out -XDrawDiagnostics -nowarn -source 1.5 T6394563.java
* @compile/ref=T6394563.empty.out -XDrawDiagnostics -nowarn -source 1.4 T6394563.java
*
* @compile/ref=T6394563.warn.out -XDstdout -XDrawDiagnostics -Xlint -nowarn T6394563.java
* @compile/ref=T6394563.warn.out -XDstdout -XDrawDiagnostics -Xlint -nowarn -source 1.5 T6394563.java
* @compile/ref=T6394563.empty.out -XDstdout -XDrawDiagnostics -Xlint -nowarn -source 1.4 T6394563.java
* @compile/ref=T6394563.warn.out -XDrawDiagnostics -Xlint -nowarn T6394563.java
* @compile/ref=T6394563.warn.out -XDrawDiagnostics -Xlint -nowarn -source 1.5 T6394563.java
* @compile/ref=T6394563.empty.out -XDrawDiagnostics -Xlint -nowarn -source 1.4 T6394563.java
*/
class T6394563 {
......
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6972327
* @summary JCTree.pos incorrect for annotations without modifiers and package
*/
import com.sun.source.tree.*;
import com.sun.source.util.Trees;
import com.sun.tools.javac.api.*;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.*;
import java.net.URI;
import java.util.Arrays;
import javax.tools.*;
public class T6972327 {
public static void main(String[] args) throws Exception {
final String bootPath = System.getProperty("sun.boot.class.path"); //NOI18N
final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
assert tool != null;
String code = "\n@interface Test {}";
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null,
Arrays.asList("-bootclasspath", bootPath, "-Xjcov"), null, Arrays.asList(new MyFileObject(code)));
CompilationUnitTree cut = ct.parse().iterator().next();
ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
Trees t = Trees.instance(ct);
long pos = t.getSourcePositions().getStartPosition(cut, clazz);
if (pos != code.indexOf(code.trim()))
throw new IllegalStateException("Unexpected position=" + pos);
}
static class MyFileObject extends SimpleJavaFileObject {
private String text;
public MyFileObject(String text) {
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
this.text = text;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return text;
}
}
}
/*
* @test /nodynamiccopyright/
* @bug 6911256 6964740 6965277 6967065
* @author Joseph D. Darcy
* @summary Check that -Xlint:arm warnings are generated as expected
* @compile/ref=ArmLint.out -Xlint:arm,deprecation -XDrawDiagnostics ArmLint.java
*/
class ArmLint implements AutoCloseable {
private static void test1() {
try(ArmLint r1 = new ArmLint();
ArmLint r2 = new ArmLint();
ArmLint r3 = new ArmLint()) {
r1.close(); // The resource's close
r2.close(42); // *Not* the resource's close
// r3 not referenced
}
}
@SuppressWarnings("arm")
private static void test2() {
try(@SuppressWarnings("deprecation") AutoCloseable r4 =
new DeprecatedAutoCloseable()) {
// r4 not referenced
} catch(Exception e) {
;
}
}
/**
* The AutoCloseable method of a resource.
*/
@Override
public void close () {
return;
}
/**
* <em>Not</em> the AutoCloseable method of a resource.
*/
public void close (int arg) {
return;
}
}
@Deprecated
class DeprecatedAutoCloseable implements AutoCloseable {
public DeprecatedAutoCloseable(){super();}
@Override
public void close () {
return;
}
}
ArmLint.java:14:15: compiler.warn.twr.explicit.close.call
ArmLint.java:13:13: compiler.warn.automatic.resource.not.referenced: r3
2 warnings
/*
* @test /nodynamiccopyright/
* @bug 6911256 6964740
* @author Joseph D. Darcy
* @summary Verify bad TWRs don't compile
* @compile/fail -source 6 TwrFlow.java
* @compile/fail/ref=BadTwr.out -XDrawDiagnostics BadTwr.java
*/
public class BadTwr implements AutoCloseable {
public static void main(String... args) {
// illegal repeated name
try(BadTwr r1 = new BadTwr(); BadTwr r1 = new BadTwr()) {
System.out.println(r1.toString());
}
// illegal duplicate name of method argument
try(BadTwr args = new BadTwr()) {
System.out.println(args.toString());
final BadTwr thatsIt = new BadTwr();
thatsIt = null;
}
try(BadTwr name = new BadTwr()) {
// illegal duplicate name of enclosing try
try(BadTwr name = new BadTwr()) {
System.out.println(name.toString());
}
}
}
public void close() {
;
}
}
BadTwr.java:13:39: compiler.err.already.defined: r1, main(java.lang.String...)
BadTwr.java:18:13: compiler.err.already.defined: args, main(java.lang.String...)
BadTwr.java:21:13: compiler.err.cant.assign.val.to.final.var: thatsIt
BadTwr.java:26:17: compiler.err.already.defined: name, main(java.lang.String...)
4 errors
/*
* @test /nodynamiccopyright/
* @bug 6911256 6964740
* @author Joseph D. Darcy
* @summary Verify bad TWRs don't compile
* @compile/fail -source 6 BadTwrSyntax.java
* @compile/fail/ref=BadTwrSyntax.out -XDrawDiagnostics BadTwrSyntax.java
*/
import java.io.IOException;
public class BadTwrSyntax implements AutoCloseable {
public static void main(String... args) throws Exception {
// illegal semicolon ending resources
try(BadTwr twrflow = new BadTwr();) {
System.out.println(twrflow.toString());
}
}
public void close() {
;
}
}
BadTwrSyntax.java:14:43: compiler.err.illegal.start.of.expr
1 error
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6911256 6964740 6965277
* @author Maurizio Cimadamore
* @summary Check that lowered arm block does not end up creating resource twice
*/
import java.util.ArrayList;
public class DuplicateResource {
static class TestResource implements AutoCloseable {
TestResource() {
resources.add(this);
}
boolean isClosed = false;
public void close() throws Exception {
isClosed = true;
}
}
static ArrayList<TestResource> resources = new ArrayList<TestResource>();
public static void main(String[] args) {
try(new TestResource()) {
//do something
} catch (Exception e) {
throw new AssertionError("Shouldn't reach here", e);
}
check();
}
public static void check() {
if (resources.size() != 1) {
throw new AssertionError("Expected one resource, found: " + resources.size());
}
TestResource resource = resources.get(0);
if (!resource.isClosed) {
throw new AssertionError("Resource used in ARM block has not been automatically closed");
}
}
}
/*
* @test /nodynamiccopyright/
* @bug 6911256 6964740 6965277
* @author Maurizio Cimadamore
* @summary Check that resource variable is not accessible from catch/finally clause
* @compile/fail/ref=DuplicateResourceDecl.out -XDrawDiagnostics DuplicateResourceDecl.java
*/
class DuplicateResourceDecl {
public static void main(String[] args) {
try(MyResource c = new MyResource();MyResource c = new MyResource()) {
//do something
} catch (Exception e) { }
}
static class MyResource implements AutoCloseable {
public void close() throws Exception {}
}
}
DuplicateResourceDecl.java:12:45: compiler.err.already.defined: c, main(java.lang.String[])
1 error
/*
* @test /nodynamiccopyright/
* @bug 6911256 6964740 6965277
* @author Maurizio Cimadamore
* @summary Test that resource variables are implicitly final
* @compile/fail/ref=ImplicitFinal.out -XDrawDiagnostics ImplicitFinal.java
*/
import java.io.IOException;
class ImplicitFinal implements AutoCloseable {
public static void main(String... args) {
try(ImplicitFinal r = new ImplicitFinal()) {
r = null; //disallowed
} catch (IOException ioe) { // Not reachable
throw new AssertionError("Shouldn't reach here", ioe);
}
}
// A close method, but the class is <em>not</em> Closeable or
// AutoCloseable.
public void close() throws IOException {
throw new IOException();
}
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册