# HG changeset patch # User lana # Date 1278988999 25200 # Node ID 3978912e09a71f906fd9c8cabb73f11eb6acfae8 # Parent 2548ac036b8fca3326d058d758e6df8355a42469# Parent 03b276d8e6a6468667facaf6ed2b5eba07e9b596 Merge diff -r 2548ac036b8f -r 3978912e09a7 langtools/src/share/classes/com/sun/tools/javac/code/Kinds.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Kinds.java Wed Jul 05 17:17:22 2017 +0200 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Kinds.java Mon Jul 12 19:43:19 2010 -0700 @@ -92,7 +92,7 @@ public static final int ABSENT_TYP = ERRONEOUS+8; // missing type public enum KindName implements Formattable { - ANNOTATION("kindname.interface"), + ANNOTATION("kindname.annotation"), CONSTRUCTOR("kindname.constructor"), INTERFACE("kindname.interface"), ENUM("kindname.enum"), diff -r 2548ac036b8f -r 3978912e09a7 langtools/src/share/classes/com/sun/tools/javac/comp/Check.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Jul 05 17:17:22 2017 +0200 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Mon Jul 12 19:43:19 2010 -0700 @@ -563,7 +563,7 @@ while (args.nonEmpty()) { if (args.head.tag == WILDCARD) return typeTagError(pos, - Log.getLocalizedString("type.req.exact"), + diags.fragment("type.req.exact"), args.head); args = args.tail; } diff -r 2548ac036b8f -r 3978912e09a7 langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Wed Jul 05 17:17:22 2017 +0200 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Mon Jul 12 19:43:19 2010 -0700 @@ -674,6 +674,40 @@ return rs.resolveInternalField(pos, attrEnv, qual, name); } + /** Anon inner classes are used as access constructor tags. + * accessConstructorTag will use an existing anon class if one is available, + * and synthethise a class (with makeEmptyClass) if one is not available. + * However, there is a small possibility that an existing class will not + * be generated as expected if it is inside a conditional with a constant + * expression. If that is found to be the case, create an empty class here. + */ + private void checkAccessConstructorTags() { + for (List l = accessConstrTags; l.nonEmpty(); l = l.tail) { + ClassSymbol c = l.head; + if (isTranslatedClassAvailable(c)) + continue; + // Create class definition tree. + JCClassDecl cdef = make.ClassDef( + make.Modifiers(STATIC | SYNTHETIC), names.empty, + List.nil(), + null, List.nil(), List.nil()); + cdef.sym = c; + cdef.type = c.type; + // add it to the list of classes to be generated + translated.append(cdef); + } + } + // where + private boolean isTranslatedClassAvailable(ClassSymbol c) { + for (JCTree tree: translated) { + if (tree.getTag() == JCTree.CLASSDEF + && ((JCClassDecl) tree).sym == c) { + return true; + } + } + return false; + } + /************************************************************************** * Access methods *************************************************************************/ @@ -718,6 +752,10 @@ */ private Map accessConstrs; + /** A list of all class symbols used for access constructor tags. + */ + private List accessConstrTags; + /** A queue for all accessed symbols. */ private ListBuffer accessed; @@ -1138,6 +1176,8 @@ ClassSymbol ctag = chk.compiled.get(flatname); if (ctag == null) ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass); + // keep a record of all tags, to verify that all are generated as required + accessConstrTags = accessConstrTags.prepend(ctag); return ctag; } @@ -3394,6 +3434,7 @@ accessNums = new HashMap(); accessSyms = new HashMap(); accessConstrs = new HashMap(); + accessConstrTags = List.nil(); accessed = new ListBuffer(); translate(cdef, (JCExpression)null); for (List l = accessed.toList(); l.nonEmpty(); l = l.tail) @@ -3401,6 +3442,7 @@ for (EnumMapping map : enumSwitchMap.values()) map.translate(); checkConflicts(this.translated.toList()); + checkAccessConstructorTags(); translated = this.translated; } finally { // note that recursive invocations of this method fail hard @@ -3420,6 +3462,7 @@ accessNums = null; accessSyms = null; accessConstrs = null; + accessConstrTags = null; accessed = null; enumSwitchMap.clear(); } diff -r 2548ac036b8f -r 3978912e09a7 langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Jul 05 17:17:22 2017 +0200 +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Mon Jul 12 19:43:19 2010 -0700 @@ -111,14 +111,14 @@ try { versionRB = ResourceBundle.getBundle(versionRBName); } catch (MissingResourceException e) { - return Log.getLocalizedString("version.resource.missing", System.getProperty("java.version")); + return Log.getLocalizedString("version.not.available"); } } try { return versionRB.getString(key); } catch (MissingResourceException e) { - return Log.getLocalizedString("version.unknown", System.getProperty("java.version")); + return Log.getLocalizedString("version.not.available"); } } diff -r 2548ac036b8f -r 3978912e09a7 langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java --- a/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java Wed Jul 05 17:17:22 2017 +0200 +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java Mon Jul 12 19:43:19 2010 -0700 @@ -419,7 +419,7 @@ putChar(ch); } else { if (!allowUnderscoresInLiterals) { - lexError("unsupported.underscore", source.name); + lexError("unsupported.underscore.lit", source.name); allowUnderscoresInLiterals = true; } } diff -r 2548ac036b8f -r 3978912e09a7 langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Jul 05 17:17:22 2017 +0200 +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Mon Jul 12 19:43:19 2010 -0700 @@ -637,6 +637,9 @@ compiler.misc.count.warn.plural=\ {0} warnings +compiler.misc.version.not.available=\ + (version info not available) + ## extra output when using -verbose (JavaCompiler) compiler.misc.verbose.checking.attribution=\ @@ -1036,7 +1039,7 @@ ## diagnostics whose key ends in ".1" compiler.misc.undetermined.type=\ undetermined type -ncompiler.misc.type.variable.has.undetermined.type=\ +compiler.misc.type.variable.has.undetermined.type=\ type variable {0} has undetermined type compiler.misc.no.unique.maximal.instance.exists=\ no unique maximal instance exists for type variable {0} with upper bounds {1} @@ -1122,6 +1125,8 @@ @interface compiler.misc.kindname.constructor=\ constructor +compiler.misc.kindname.enum=\ + enum compiler.misc.kindname.interface=\ interface compiler.misc.kindname.static=\ @@ -1256,6 +1261,10 @@ enums are not supported in -source {0}\n\ (use -source 5 or higher to enable enums) +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) + compiler.err.multicatch.not.supported.in.source=\ multi-catch statement is not supported in -source {0}\n\ (use -source 7 or higher to enable multi-catch statement) diff -r 2548ac036b8f -r 3978912e09a7 langtools/src/share/classes/javax/lang/model/element/ElementKind.java --- a/langtools/src/share/classes/javax/lang/model/element/ElementKind.java Wed Jul 05 17:17:22 2017 +0200 +++ b/langtools/src/share/classes/javax/lang/model/element/ElementKind.java Mon Jul 12 19:43:19 2010 -0700 @@ -88,7 +88,13 @@ * An implementation-reserved element. This is not the element * you are looking for. */ - OTHER; + OTHER, + + /** + * A resource variable. + * @since 1.7 + */ + RESOURCE_VARIABLE; /** diff -r 2548ac036b8f -r 3978912e09a7 langtools/test/tools/javac/6917288/GraphicalInstaller.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6917288/GraphicalInstaller.java Mon Jul 12 19:43:19 2010 -0700 @@ -0,0 +1,55 @@ +/* + * 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. + */ + +/** + * Complex example for the "access constructor tags" issue. + * This test causes Lower to evaluate all classes defined in installNext + * before they are lowered, thus preventing the use of Lower.classdefs + * as a way of determining whether a class has been translated or not. + */ +class GraphicalInstaller { + private BackgroundInstaller backgroundInstaller; + + private void installNext() { + final Integer x = 0; + class X { + Object o = new Object() { int y = x; }; + }; + new X(); + if (false) { + new Runnable(){ + public void run() { + } + }; + } + } + + private void installSuiteCommon() { + backgroundInstaller = new BackgroundInstaller(); + } + + private static class BackgroundInstaller { + private BackgroundInstaller() { + } + } +} diff -r 2548ac036b8f -r 3978912e09a7 langtools/test/tools/javac/6917288/GraphicalInstallerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6917288/GraphicalInstallerTest.java Mon Jul 12 19:43:19 2010 -0700 @@ -0,0 +1,106 @@ +/* + * 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 6917288 + * @summary Unnamed nested class is not generated + */ + +import java.io.*; +import java.util.*; + +public class GraphicalInstallerTest { + public static void main(String... args) throws Exception { + new GraphicalInstallerTest().run(); + } + + void run() throws Exception { + File testSrc = new File(System.getProperty("test.src")); + File classes = new File("classes"); + classes.mkdirs(); + List opts = Arrays.asList("-d", classes.getPath()); + int rc = compile(opts, new File(testSrc, "GraphicalInstaller.java")); + if (rc != 0) { + error("compilation failed: rc=" + rc); + return; + } + + check(classes, + "GraphicalInstaller$1.class", + "GraphicalInstaller$1X$1.class", + "GraphicalInstaller$1X.class", + "GraphicalInstaller$BackgroundInstaller.class", + "GraphicalInstaller.class"); + + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } + + /** + * Compile files with given options. + * Display any output from compiler, and return javac return code. + */ + int compile(List opts, File... files) { + List args = new ArrayList(); + args.addAll(opts); + for (File f: files) + args.add(f.getPath()); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), pw); + pw.close(); + String out = sw.toString(); + if (out.length() > 0) + System.err.println(out); + return rc; + } + + /** + * Check that a directory contains the expected files. + */ + void check(File dir, String... paths) { + Set found = new TreeSet(Arrays.asList(dir.list())); + Set expect = new TreeSet(Arrays.asList(paths)); + if (found.equals(expect)) + return; + for (String f: found) { + if (!expect.contains(f)) + error("Unexpected file found: " + f); + } + for (String e: expect) { + if (!found.contains(e)) + error("Expected file not found: " + e); + } + } + + /** + * Record an error message. + */ + void error(String msg) { + System.err.println(msg); + errors++; + } + + int errors; +} diff -r 2548ac036b8f -r 3978912e09a7 langtools/test/tools/javac/6917288/T6917288.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6917288/T6917288.java Mon Jul 12 19:43:19 2010 -0700 @@ -0,0 +1,158 @@ +/* + * 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 6917288 + * @summary Unnamed nested class is not generated + */ + +import java.io.*; +import java.util.*; + +public class T6917288 { + // refers to kind of reference to an anon inner class that may be generated + enum Kind { NONE, FALSE, TRUE, ALWAYS }; + + public static void main(String... args) throws Exception { + new T6917288().run(); + } + + void run() throws Exception { + for (Kind k: Kind.values()) { + test(k); + } + + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } + + /** + * Run a test case for Kind k. + */ + void test(Kind k) throws Exception { + System.err.println("Test " + (++count) + ": " + k); + File testDir = new File("test" + count); + File srcDir = new File(testDir, "src"); + srcDir.mkdirs(); + File classesDir = new File(testDir, "classes"); + classesDir.mkdirs(); + + List opts = new ArrayList(); + opts.add("-d"); + opts.add(classesDir.getPath()); + + File f = writeFile(srcDir, k); + int rc = compile(opts, f); + if (rc != 0) { + error("compilation failed: rc=" + rc); + return; + } + + check(classesDir, "Test.class", "Test$Inner.class", "Test$1.class"); + } + + /** + * Compile files with given options. + * Display any output from compiler, and return javac return code. + */ + int compile(List opts, File... files) { + List args = new ArrayList(); + args.addAll(opts); + for (File f: files) + args.add(f.getPath()); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), pw); + pw.close(); + String out = sw.toString(); + if (out.length() > 0) + System.err.println(out); + return rc; + } + + /** + * Check that a directory contains the expected files. + */ + void check(File dir, String... paths) { + Set found = new TreeSet(Arrays.asList(dir.list())); + Set expect = new TreeSet(Arrays.asList(paths)); + if (found.equals(expect)) + return; + for (String f: found) { + if (!expect.contains(f)) + error("Unexpected file found: " + f); + } + for (String e: expect) { + if (!found.contains(e)) + error("Expected file not found: " + e); + } + } + + /** + * Write source file for test case k. + */ + File writeFile(File dir, Kind k) throws Exception { + StringBuilder sb = new StringBuilder(); + sb.append("public class Test {\n"); + sb.append(" private Inner inner;\n"); + + // generate different cases of an anon inner class + if (k != Kind.NONE) { + sb.append(" private void m() {\n"); + sb.append(" "); + switch (k) { + case FALSE: case TRUE: + sb.append("if (" + k.toString().toLowerCase() + ") "); + } + sb.append("new Runnable() { public void run() { } };\n"); + sb.append(" }\n"); + } + + sb.append(" private void init() {\n"); + sb.append(" inner = new Inner();\n"); + sb.append(" }\n"); + sb.append("\n"); + sb.append(" private static class Inner {\n"); + sb.append(" private Inner() {\n"); + sb.append(" }\n"); + sb.append(" }\n"); + sb.append("}\n"); + + File f = new File(dir, "Test.java"); + FileWriter w = new FileWriter(f); + w.write(sb.toString()); + w.close(); + return f; + } + + /** + * Record an error message. + */ + void error(String msg) { + System.err.println(msg); + errors++; + } + + int count; + int errors; +} diff -r 2548ac036b8f -r 3978912e09a7 langtools/test/tools/javac/diags/CheckResourceKeys.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/CheckResourceKeys.java Mon Jul 12 19:43:19 2010 -0700 @@ -0,0 +1,362 @@ +/* + * 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 6964768 6964461 6964469 6964487 6964460 6964481 + * @summary need test program to validate javac resource bundles + */ + +import java.io.*; +import java.util.*; +import javax.tools.*; +import com.sun.tools.classfile.*; + +/** + * Compare string constants in javac classes against keys in javac resource bundles. + */ +public class CheckResourceKeys { + /** + * Main program. + * Options: + * -finddeadkeys + * look for keys in resource bundles that are no longer required + * -findmissingkeys + * look for keys in resource bundles that are missing + * + * @throws Exception if invoked by jtreg and errors occur + */ + public static void main(String... args) throws Exception { + CheckResourceKeys c = new CheckResourceKeys(); + if (c.run(args)) + return; + + if (is_jtreg()) + throw new Exception(c.errors + " errors occurred"); + else + System.exit(1); + } + + static boolean is_jtreg() { + return (System.getProperty("test.src") != null); + } + + /** + * Main entry point. + */ + boolean run(String... args) throws Exception { + boolean findDeadKeys = false; + boolean findMissingKeys = false; + + if (args.length == 0) { + if (is_jtreg()) { + findDeadKeys = true; + findMissingKeys = true; + } else { + System.err.println("Usage: java CheckResourceKeys "); + System.err.println("where options include"); + System.err.println(" -finddeadkeys find keys in resource bundles which are no longer required"); + System.err.println(" -findmissingkeys find keys in resource bundles that are required but missing"); + return true; + } + } else { + for (String arg: args) { + if (arg.equalsIgnoreCase("-finddeadkeys")) + findDeadKeys = true; + else if (arg.equalsIgnoreCase("-findmissingkeys")) + findMissingKeys = true; + else + error("bad option: " + arg); + } + } + + if (errors > 0) + return false; + + Set codeStrings = getCodeStrings(); + Set resourceKeys = getResourceKeys(); + + if (findDeadKeys) + findDeadKeys(codeStrings, resourceKeys); + + if (findMissingKeys) + findMissingKeys(codeStrings, resourceKeys); + + return (errors == 0); + } + + /** + * Find keys in resource bundles which are probably no longer required. + * A key is probably required if there is a string fragment in the code + * that is part of the resource key, or if the key is well-known + * according to various pragmatic rules. + */ + void findDeadKeys(Set codeStrings, Set resourceKeys) { + String[] prefixes = { + "compiler.err.", "compiler.warn.", "compiler.note.", "compiler.misc.", + "javac." + }; + for (String rk: resourceKeys) { + // some keys are used directly, without a prefix. + if (codeStrings.contains(rk)) + continue; + + // remove standard prefix + String s = null; + for (int i = 0; i < prefixes.length && s == null; i++) { + if (rk.startsWith(prefixes[i])) { + s = rk.substring(prefixes[i].length()); + } + } + if (s == null) { + error("Resource key does not start with a standard prefix: " + rk); + continue; + } + + if (codeStrings.contains(s)) + continue; + + // keys ending in .1 are often synthesized + if (s.endsWith(".1") && codeStrings.contains(s.substring(0, s.length() - 2))) + continue; + + // verbose keys are generated by ClassReader.printVerbose + if (s.startsWith("verbose.") && codeStrings.contains(s.substring(8))) + continue; + + // mandatory warning messages are synthesized with no characteristic substring + if (isMandatoryWarningString(s)) + continue; + + // check known (valid) exceptions + if (knownRequired.contains(rk)) + continue; + + // check known suspects + if (needToInvestigate.contains(rk)) + continue; + + error("Resource key not found in code: " + rk); + } + } + + /** + * The keys for mandatory warning messages are all synthesized and do not + * have a significant recognizable substring to look for. + */ + private boolean isMandatoryWarningString(String s) { + String[] bases = { "deprecated", "unchecked", "varargs", "sunapi" }; + String[] tails = { ".filename", ".filename.additional", ".plural", ".plural.additional", ".recompile" }; + for (String b: bases) { + if (s.startsWith(b)) { + String tail = s.substring(b.length()); + for (String t: tails) { + if (tail.equals(t)) + return true; + } + } + } + return false; + } + + Set knownRequired = new TreeSet(Arrays.asList( + // See Resolve.getErrorKey + "compiler.err.cant.resolve.args", + "compiler.err.cant.resolve.args.params", + "compiler.err.cant.resolve.location.args", + "compiler.err.cant.resolve.location.args.params", + // JavaCompiler, reports #errors and #warnings + "compiler.misc.count.error", + "compiler.misc.count.error.plural", + "compiler.misc.count.warn", + "compiler.misc.count.warn.plural", + // Used for LintCategory + "compiler.warn.lintOption", + // Other + "compiler.misc.base.membership" // (sic) + )); + + + Set needToInvestigate = new TreeSet(Arrays.asList( + "compiler.err.cant.read.file", // UNUSED + "compiler.err.illegal.self.ref", // UNUSED + "compiler.err.io.exception", // UNUSED + "compiler.err.limit.pool.in.class", // UNUSED + "compiler.err.name.reserved.for.internal.use", // UNUSED + "compiler.err.no.match.entry", // UNUSED + "compiler.err.not.within.bounds.explain", // UNUSED + "compiler.err.signature.doesnt.match.intf", // UNUSED + "compiler.err.signature.doesnt.match.supertype", // UNUSED + "compiler.err.type.var.more.than.once", // UNUSED + "compiler.err.type.var.more.than.once.in.result", // UNUSED + "compiler.misc.ccf.found.later.version", // UNUSED + "compiler.misc.non.denotable.type", // UNUSED + "compiler.misc.unnamed.package", // should be required, CR 6964147 + "compiler.misc.verbose.retro", // UNUSED + "compiler.misc.verbose.retro.with", // UNUSED + "compiler.misc.verbose.retro.with.list", // UNUSED + "compiler.warn.proc.type.already.exists", // TODO in JavacFiler + "javac.err.invalid.arg", // UNUSED ?? + "javac.opt.arg.class", // UNUSED ?? + "javac.opt.arg.pathname", // UNUSED ?? + "javac.opt.moreinfo", // option commented out + "javac.opt.nogj", // UNUSED + "javac.opt.printflat", // option commented out + "javac.opt.printsearch", // option commented out + "javac.opt.prompt", // option commented out + "javac.opt.retrofit", // UNUSED + "javac.opt.s", // option commented out + "javac.opt.scramble", // option commented out + "javac.opt.scrambleall" // option commented out + )); + + /** + * For all strings in the code that look like they might be fragments of + * a resource key, verify that a key exists. + */ + void findMissingKeys(Set codeStrings, Set resourceKeys) { + for (String cs: codeStrings) { + if (cs.matches("[A-Za-z][^.]*\\..*")) { + // ignore filenames (i.e. in SourceFile attribute + if (cs.matches(".*\\.java")) + continue; + // ignore package and class names + if (cs.matches("(com|java|javax|sun)\\.[A-Za-z.]+")) + continue; + // explicit known exceptions + if (noResourceRequired.contains(cs)) + continue; + // look for matching resource + if (hasMatch(resourceKeys, cs)) + continue; + error("no match for \"" + cs + "\""); + } + } + } + // where + private Set noResourceRequired = new HashSet(Arrays.asList( + // system properties + "application.home", // in Paths.java + "env.class.path", + "line.separator", + "user.dir", + // file names + "ct.sym", + "rt.jar", + "tools.jar", + // -XD option names + "process.packages", + "ignore.symbol.file", + // prefix/embedded strings + "compiler.", + "compiler.misc.", + "count.", + "illegal.", + "javac.", + "verbose." + )); + + /** + * Look for a resource that ends in this string fragment. + */ + boolean hasMatch(Set resourceKeys, String s) { + for (String rk: resourceKeys) { + if (rk.endsWith(s)) + return true; + } + return false; + } + + /** + * Get the set of strings from (most of) the javac classfiles. + */ + Set getCodeStrings() throws IOException { + Set results = new TreeSet(); + JavaCompiler c = ToolProvider.getSystemJavaCompiler(); + JavaFileManager fm = c.getStandardFileManager(null, null, null); + String[] pkgs = { + "javax.annotation.processing", + "javax.lang.model", + "javax.tools", + "com.sun.source", + "com.sun.tools.javac" + }; + for (String pkg: pkgs) { + for (JavaFileObject fo: fm.list(StandardLocation.PLATFORM_CLASS_PATH, + pkg, EnumSet.of(JavaFileObject.Kind.CLASS), true)) { + String name = fo.getName(); + // ignore resource files, and files which are not really part of javac + if (name.contains("resources") + || name.contains("Launcher.class") + || name.contains("CreateSymbols.class")) + continue; + scan(fo, results); + } + } + return results; + } + + /** + * Get the set of strings from a class file. + * Only strings that look like they might be a resource key are returned. + */ + void scan(JavaFileObject fo, Set results) throws IOException { + InputStream in = fo.openInputStream(); + try { + ClassFile cf = ClassFile.read(in); + for (ConstantPool.CPInfo cpinfo: cf.constant_pool.entries()) { + if (cpinfo.getTag() == ConstantPool.CONSTANT_Utf8) { + String v = ((ConstantPool.CONSTANT_Utf8_info) cpinfo).value; + if (v.matches("[A-Za-z0-9-_.]+")) + results.add(v); + } + } + } catch (ConstantPoolException ignore) { + } finally { + in.close(); + } + } + + /** + * Get the set of keys from the javac resource bundles. + */ + Set getResourceKeys() { + Set results = new TreeSet(); + for (String name : new String[]{"javac", "compiler"}) { + ResourceBundle b = + ResourceBundle.getBundle("com.sun.tools.javac.resources." + name); + results.addAll(b.keySet()); + } + return results; + } + + /** + * Report an error. + */ + void error(String msg) { + System.err.println("Error: " + msg); + errors++; + } + + int errors; +} diff -r 2548ac036b8f -r 3978912e09a7 langtools/test/tools/javac/generics/6946618/T6946618c.java --- a/langtools/test/tools/javac/generics/6946618/T6946618c.java Wed Jul 05 17:17:22 2017 +0200 +++ b/langtools/test/tools/javac/generics/6946618/T6946618c.java Mon Jul 12 19:43:19 2010 -0700 @@ -1,6 +1,6 @@ /* * @test /nodynamiccopyright/ - * @bug 6946618 + * @bug 6946618 6968497 * @summary sqe test fails: javac/generics/NewOnTypeParm in pit jdk7 b91 in all platforms. * @author mcimadamore * @compile/fail/ref=T6946618c.out -XDrawDiagnostics T6946618c.java diff -r 2548ac036b8f -r 3978912e09a7 langtools/test/tools/javac/generics/6946618/T6946618c.out --- a/langtools/test/tools/javac/generics/6946618/T6946618c.out Wed Jul 05 17:17:22 2017 +0200 +++ b/langtools/test/tools/javac/generics/6946618/T6946618c.out Mon Jul 12 19:43:19 2010 -0700 @@ -1,4 +1,4 @@ -T6946618c.java:13:24: compiler.err.type.found.req: ? extends java.lang.String, class or interface without bounds -T6946618c.java:14:24: compiler.err.type.found.req: ? super java.lang.String, class or interface without bounds -T6946618c.java:15:24: compiler.err.type.found.req: ?, class or interface without bounds +T6946618c.java:13:24: compiler.err.type.found.req: ? extends java.lang.String, (compiler.misc.type.req.exact) +T6946618c.java:14:24: compiler.err.type.found.req: ? super java.lang.String, (compiler.misc.type.req.exact) +T6946618c.java:15:24: compiler.err.type.found.req: ?, (compiler.misc.type.req.exact) 3 errors diff -r 2548ac036b8f -r 3978912e09a7 langtools/test/tools/javac/literals/BadUnderscoreLiterals.6.out --- a/langtools/test/tools/javac/literals/BadUnderscoreLiterals.6.out Wed Jul 05 17:17:22 2017 +0200 +++ b/langtools/test/tools/javac/literals/BadUnderscoreLiterals.6.out Mon Jul 12 19:43:19 2010 -0700 @@ -1,4 +1,4 @@ -BadUnderscoreLiterals.java:14:17: compiler.err.unsupported.underscore: 1.6 +BadUnderscoreLiterals.java:14:17: compiler.err.unsupported.underscore.lit: 1.6 BadUnderscoreLiterals.java:18:15: compiler.err.illegal.underscore BadUnderscoreLiterals.java:22:19: compiler.err.illegal.underscore BadUnderscoreLiterals.java:25:14: compiler.err.unsupported.binary.lit: 1.6