# HG changeset patch # User lana # Date 1478281931 0 # Node ID 4e7ef9667ea660a325210038629d4847c666bb92 # Parent 394bc7b2237fec118da9936af00bcbeb6ce3eb61# Parent 8e66bf10fcec5c67aa87ecd87417ebc01a2d2c51 Merge diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/make/build.xml --- a/langtools/make/build.xml Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/make/build.xml Fri Nov 04 17:52:11 2016 +0000 @@ -84,17 +84,21 @@ - + - + - + @@ -207,7 +211,9 @@ - + + + diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Fri Nov 04 17:52:11 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, 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 @@ -101,6 +101,8 @@ @Override public Main.Result call() throws Exception { prepareCompiler(false); + if (compiler.errorCount() > 0) + return Main.Result.ERROR; compiler.compile(args.getFileObjects(), args.getClassNames(), processors); return (compiler.errorCount() > 0) ? Main.Result.ERROR : Main.Result.OK; // FIXME? } diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Fri Nov 04 17:52:11 2016 +0000 @@ -36,7 +36,6 @@ import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import java.util.function.Consumer; import java.util.function.Predicate; @@ -59,6 +58,7 @@ import com.sun.tools.javac.code.Directive.UsesDirective; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Kinds; +import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.code.ModuleFinder; import com.sun.tools.javac.code.Source; import com.sun.tools.javac.code.Symbol; @@ -131,6 +131,7 @@ private final Types types; private final JavaFileManager fileManager; private final ModuleFinder moduleFinder; + private final Source source; private final boolean allowModules; public final boolean multiModuleMode; @@ -151,6 +152,8 @@ private final String limitModsOpt; private final Set extraLimitMods = new HashSet<>(); + private final boolean lintOptions; + private Set rootModules = null; public static Modules instance(Context context) { @@ -170,9 +173,12 @@ moduleFinder = ModuleFinder.instance(context); types = Types.instance(context); fileManager = context.get(JavaFileManager.class); - allowModules = Source.instance(context).allowModules(); + source = Source.instance(context); + allowModules = source.allowModules(); Options options = Options.instance(context); + lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option); + moduleOverride = options.get(Option.XMODULE); multiModuleMode = fileManager.hasLocation(StandardLocation.MODULE_SOURCE_PATH); @@ -487,7 +493,7 @@ ModuleSymbol msym = moduleFinder.findModule((ModuleSymbol) sym); if (msym.kind == Kinds.Kind.ERR) { - log.error(Errors.CantFindModule(msym)); + log.error(Errors.ModuleNotFound(msym)); //make sure the module is initialized: msym.directives = List.nil(); msym.exports = List.nil(); @@ -684,15 +690,10 @@ } private ModuleSymbol lookupModule(JCExpression moduleName) { - try { Name name = TreeInfo.fullName(moduleName); ModuleSymbol msym = moduleFinder.findModule(name); TreeInfo.setSymbol(moduleName, msym); return msym; - } catch (Throwable t) { - System.err.println("Module " + sym + "; lookup export " + moduleName); - throw t; - } } } @@ -884,6 +885,8 @@ Set limitMods = new HashSet<>(); if (limitModsOpt != null) { for (String limit : limitModsOpt.split(",")) { + if (!isValidName(limit)) + continue; limitMods.add(syms.enterModule(names.fromString(limit))); } } @@ -892,6 +895,14 @@ } observable = computeTransitiveClosure(limitMods, null); observable.addAll(rootModules); + if (lintOptions) { + for (ModuleSymbol msym : limitMods) { + if (!observable.contains(msym)) { + log.warning(LintCategory.OPTIONS, + Warnings.ModuleForOptionNotFound(Option.LIMIT_MODULES, msym)); + } + } + } } Predicate observablePred = sym -> observable == null || observable.contains(sym); @@ -944,6 +955,8 @@ .filter(systemModulePred.negate().and(observablePred)); break; default: + if (!isValidName(added)) + continue; modules = Stream.of(syms.enterModule(names.fromString(added))); break; } @@ -1141,8 +1154,9 @@ addVisiblePackages(msym, seen, rm, rm.exports); } - for (Entry> addExportsEntry : addExports.entrySet()) - addVisiblePackages(msym, seen, addExportsEntry.getKey(), addExportsEntry.getValue()); + addExports.forEach((exportsFrom, exports) -> { + addVisiblePackages(msym, seen, exportsFrom, exports); + }); } private void addVisiblePackages(ModuleSymbol msym, @@ -1180,12 +1194,11 @@ return; addExports = new LinkedHashMap<>(); + Set unknownModules = new HashSet<>(); if (addExportsOpt == null) return; -// System.err.println("Modules.addExports:\n " + addExportsOpt.replace("\0", "\n ")); - Pattern ep = Pattern.compile("([^/]+)/([^=]+)=(.*)"); for (String s: addExportsOpt.split("\0+")) { if (s.isEmpty()) @@ -1203,7 +1216,15 @@ String packageName = em.group(2); String targetNames = em.group(3); + if (!isValidName(moduleName)) + continue; + ModuleSymbol msym = syms.enterModule(names.fromString(moduleName)); + if (!isKnownModule(msym, unknownModules)) + continue; + + if (!isValidName(packageName)) + continue; PackageSymbol p = syms.enterPackage(msym, names.fromString(packageName)); p.modle = msym; // TODO: do we need this? @@ -1213,11 +1234,11 @@ if (toModule.equals("ALL-UNNAMED")) { m = syms.unnamedModule; } else { - if (!SourceVersion.isName(toModule)) { - // TODO: error: invalid module name + if (!isValidName(toModule)) continue; - } m = syms.enterModule(names.fromString(toModule)); + if (!isKnownModule(m, unknownModules)) + continue; } targetModules = targetModules.prepend(m); } @@ -1228,6 +1249,21 @@ } } + private boolean isKnownModule(ModuleSymbol msym, Set unknownModules) { + if (allModules.contains(msym)) { + return true; + } + + if (!unknownModules.contains(msym)) { + if (lintOptions) { + log.warning(LintCategory.OPTIONS, + Warnings.ModuleForOptionNotFound(Option.ADD_EXPORTS, msym)); + } + unknownModules.add(msym); + } + return false; + } + private void initAddReads() { if (addReads != null) return; @@ -1237,8 +1273,6 @@ if (addReadsOpt == null) return; -// System.err.println("Modules.addReads:\n " + addReadsOpt.replace("\0", "\n ")); - Pattern rp = Pattern.compile("([^=]+)=(.*)"); for (String s : addReadsOpt.split("\0+")) { if (s.isEmpty()) @@ -1249,26 +1283,40 @@ } // Terminology comes from - // --add-reads target-module=source-module,... + // --add-reads source-module=target-module,... // Compare to - // module target-module { requires source-module; ... } - String targetName = rm.group(1); - String sources = rm.group(2); + // module source-module { requires target-module; ... } + String sourceName = rm.group(1); + String targetNames = rm.group(2); + + if (!isValidName(sourceName)) + continue; - ModuleSymbol msym = syms.enterModule(names.fromString(targetName)); - for (String source : sources.split("[ ,]+")) { - ModuleSymbol sourceModule; - if (source.equals("ALL-UNNAMED")) { - sourceModule = syms.unnamedModule; + ModuleSymbol msym = syms.enterModule(names.fromString(sourceName)); + if (!allModules.contains(msym)) { + if (lintOptions) { + log.warning(Warnings.ModuleForOptionNotFound(Option.ADD_READS, msym)); + } + continue; + } + + for (String targetName : targetNames.split("[ ,]+", -1)) { + ModuleSymbol targetModule; + if (targetName.equals("ALL-UNNAMED")) { + targetModule = syms.unnamedModule; } else { - if (!SourceVersion.isName(source)) { - // TODO: error: invalid module name + if (!isValidName(targetName)) + continue; + targetModule = syms.enterModule(names.fromString(targetName)); + if (!allModules.contains(targetModule)) { + if (lintOptions) { + log.warning(LintCategory.OPTIONS, Warnings.ModuleForOptionNotFound(Option.ADD_READS, targetModule)); + } continue; } - sourceModule = syms.enterModule(names.fromString(source)); } addReads.computeIfAbsent(msym, m -> new HashSet<>()) - .add(new RequiresDirective(sourceModule, EnumSet.of(RequiresFlag.EXTRA))); + .add(new RequiresDirective(targetModule, EnumSet.of(RequiresFlag.EXTRA))); } } } @@ -1301,6 +1349,10 @@ } } + private boolean isValidName(CharSequence name) { + return SourceVersion.isName(name, Source.toSourceVersion(source)); + } + // DEBUG private String toString(ModuleSymbol msym) { return msym.name + "[" diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Nov 04 17:52:11 2016 +0000 @@ -1328,7 +1328,7 @@ } else { ((ClassType)sym.type).setEnclosingType(Type.noType); } - enterTypevars(self); + enterTypevars(self, self.type); if (!missingTypeVariables.isEmpty()) { ListBuffer typeVars = new ListBuffer<>(); for (Type typevar : missingTypeVariables) { @@ -2353,19 +2353,17 @@ /** Enter type variables of this classtype and all enclosing ones in * `typevars'. */ - protected void enterTypevars(Type t) { - if (t.getEnclosingType() != null && t.getEnclosingType().hasTag(CLASS)) - enterTypevars(t.getEnclosingType()); - for (List xs = t.getTypeArguments(); xs.nonEmpty(); xs = xs.tail) + protected void enterTypevars(Symbol sym, Type t) { + if (t.getEnclosingType() != null) { + if (!t.getEnclosingType().hasTag(TypeTag.NONE)) { + enterTypevars(sym.owner, t.getEnclosingType()); + } + } else if (sym.kind == MTH && !sym.isStatic()) { + enterTypevars(sym.owner, sym.owner.type); + } + for (List xs = t.getTypeArguments(); xs.nonEmpty(); xs = xs.tail) { typevars.enter(xs.head.tsym); - } - - protected void enterTypevars(Symbol sym) { - if (sym.owner.kind == MTH) { - enterTypevars(sym.owner); - enterTypevars(sym.owner.owner); } - enterTypevars(sym.type); } protected ClassSymbol enterClass(Name name) { @@ -2388,7 +2386,7 @@ // prepare type variable table typevars = typevars.dup(currentOwner); if (ct.getEnclosingType().hasTag(CLASS)) - enterTypevars(ct.getEnclosingType()); + enterTypevars(c.owner, ct.getEnclosingType()); // read flags, or skip if this is an inner class long f = nextChar(); @@ -2545,6 +2543,11 @@ types.subst(ct.supertype_field, missing, found); ct.interfaces_field = types.subst(ct.interfaces_field, missing, found); + ct.typarams_field = + types.substBounds(ct.typarams_field, missing, found); + for (List types = ct.typarams_field; types.nonEmpty(); types = types.tail) { + types.head.tsym.type = types.head; + } } else if (missingTypeVariables.isEmpty() != foundTypeVariables.isEmpty()) { Name name = missingTypeVariables.head.tsym.name; diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java Fri Nov 04 17:52:11 2016 +0000 @@ -43,6 +43,7 @@ import java.util.regex.Pattern; import java.util.stream.Stream; +import javax.lang.model.SourceVersion; import javax.tools.JavaFileManager; import javax.tools.JavaFileManager.Location; import javax.tools.JavaFileObject; @@ -400,7 +401,7 @@ /** * Validates the overall consistency of the options and operands * processed by processOptions. - * @return true if all args are successfully validating; false otherwise. + * @return true if all args are successfully validated; false otherwise. * @throws IllegalStateException if a problem is found and errorMode is set to * ILLEGAL_STATE */ @@ -610,62 +611,143 @@ if (obsoleteOptionFound) log.warning(LintCategory.OPTIONS, "option.obsolete.suppression"); + SourceVersion sv = Source.toSourceVersion(source); + validateAddExports(sv); + validateAddModules(sv); + validateAddReads(sv); + validateLimitModules(sv); + + return !errors && (log.nerrors == 0); + } + + private void validateAddExports(SourceVersion sv) { String addExports = options.get(Option.ADD_EXPORTS); if (addExports != null) { - // Each entry must be of the form module/package=target-list where target-list is a - // comma-separated list of module or ALL-UNNAMED. - // All module/package pairs must be unique. - Pattern p = Pattern.compile("([^/]+)/([^=]+)=(.*)"); - Map> map = new LinkedHashMap<>(); - for (String e: addExports.split("\0")) { + // Each entry must be of the form sourceModule/sourcePackage=target-list where + // target-list is a comma separated list of module or ALL-UNNAMED. + // Empty items in the target-list are ignored. + // There must be at least one item in the list; this is handled in Option.ADD_EXPORTS. + Pattern p = Option.ADD_EXPORTS.getPattern(); + for (String e : addExports.split("\0")) { Matcher m = p.matcher(e); - if (!m.matches()) { - log.error(Errors.XaddexportsMalformedEntry(e)); - continue; + if (m.matches()) { + String sourceModuleName = m.group(1); + if (!SourceVersion.isName(sourceModuleName, sv)) { + // syntactically invalid source name: e.g. --add-exports m!/p1=m2 + log.warning(Warnings.BadNameForOption(Option.ADD_EXPORTS, sourceModuleName)); + } + String sourcePackageName = m.group(2); + if (!SourceVersion.isName(sourcePackageName, sv)) { + // syntactically invalid source name: e.g. --add-exports m1/p!=m2 + log.warning(Warnings.BadNameForOption(Option.ADD_EXPORTS, sourcePackageName)); + } + + String targetNames = m.group(3); + for (String targetName : targetNames.split(",")) { + switch (targetName) { + case "": + case "ALL-UNNAMED": + break; + + default: + if (!SourceVersion.isName(targetName, sv)) { + // syntactically invalid target name: e.g. --add-exports m1/p1=m! + log.warning(Warnings.BadNameForOption(Option.ADD_EXPORTS, targetName)); + } + break; + } + } } - String eModule = m.group(1); // TODO: check a valid dotted identifier - String ePackage = m.group(2); // TODO: check a valid dotted identifier - String eTargets = m.group(3); // TODO: check a valid list of dotted identifier or ALL-UNNAMED - String eModPkg = eModule + '/' + ePackage; - List l = map.get(eModPkg); - map.put(eModPkg, (l == null) ? List.of(eTargets) : l.prepend(eTargets)); } - map.forEach((key, value) -> { - if (value.size() > 1) { - log.error(Errors.XaddexportsTooMany(key)); - // TODO: consider adding diag fragments for the entries - } - }); } + } + private void validateAddReads(SourceVersion sv) { String addReads = options.get(Option.ADD_READS); if (addReads != null) { - // Each entry must be of the form module=source-list where source-list is a - // comma separated list of module or ALL-UNNAMED. - // All target modules (i.e. on left of '=') must be unique. - Pattern p = Pattern.compile("([^=]+)=(.*)"); - Map> map = new LinkedHashMap<>(); - for (String e: addReads.split("\0")) { + // Each entry must be of the form source=target-list where target-list is a + // comma-separated list of module or ALL-UNNAMED. + // Empty items in the target list are ignored. + // There must be at least one item in the list; this is handled in Option.ADD_READS. + Pattern p = Option.ADD_READS.getPattern(); + for (String e : addReads.split("\0")) { Matcher m = p.matcher(e); - if (!m.matches()) { - log.error(Errors.XaddreadsMalformedEntry(e)); - continue; + if (m.matches()) { + String sourceName = m.group(1); + if (!SourceVersion.isName(sourceName, sv)) { + // syntactically invalid source name: e.g. --add-reads m!=m2 + log.warning(Warnings.BadNameForOption(Option.ADD_READS, sourceName)); + } + + String targetNames = m.group(2); + for (String targetName : targetNames.split(",", -1)) { + switch (targetName) { + case "": + case "ALL-UNNAMED": + break; + + default: + if (!SourceVersion.isName(targetName, sv)) { + // syntactically invalid target name: e.g. --add-reads m1=m! + log.warning(Warnings.BadNameForOption(Option.ADD_READS, targetName)); + } + break; + } + } } - String eModule = m.group(1); // TODO: check a valid dotted identifier - String eSources = m.group(2); // TODO: check a valid list of dotted identifier or ALL-UNNAMED - List l = map.get(eModule); - map.put(eModule, (l == null) ? List.of(eSources) : l.prepend(eSources)); } - map.forEach((key, value) -> { - if (value.size() > 1) { - log.error(Errors.XaddreadsTooMany(key)); - // TODO: consider adding diag fragments for the entries + } + } + + private void validateAddModules(SourceVersion sv) { + String addModules = options.get(Option.ADD_MODULES); + if (addModules != null) { + // Each entry must be of the form target-list where target-list is a + // comma separated list of module names, or ALL-DEFAULT, ALL-SYSTEM, + // or ALL-MODULE_PATH. + // Empty items in the target list are ignored. + // There must be at least one item in the list; this is handled in Option.ADD_MODULES. + for (String moduleName : addModules.split(",")) { + switch (moduleName) { + case "": + case "ALL-DEFAULT": + case "ALL-SYSTEM": + case "ALL-MODULE-PATH": + break; + + default: + if (!SourceVersion.isName(moduleName, sv)) { + // syntactically invalid module name: e.g. --add-modules m1,m! + log.warning(Warnings.BadNameForOption(Option.ADD_MODULES, moduleName)); + } + break; } - }); + } } + } + private void validateLimitModules(SourceVersion sv) { + String limitModules = options.get(Option.LIMIT_MODULES); + if (limitModules != null) { + // Each entry must be of the form target-list where target-list is a + // comma separated list of module names, or ALL-DEFAULT, ALL-SYSTEM, + // or ALL-MODULE_PATH. + // Empty items in the target list are ignored. + // There must be at least one item in the list; this is handled in Option.LIMIT_EXPORTS. + for (String moduleName : limitModules.split(",")) { + switch (moduleName) { + case "": + break; - return !errors; + default: + if (!SourceVersion.isName(moduleName, sv)) { + // syntactically invalid module name: e.g. --limit-modules m1,m! + log.warning(Warnings.BadNameForOption(Option.LIMIT_MODULES, moduleName)); + } + break; + } + } + } } /** diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java Fri Nov 04 17:52:11 2016 +0000 @@ -43,6 +43,7 @@ import java.util.ServiceLoader; import java.util.Set; import java.util.TreeSet; +import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.StreamSupport; @@ -556,18 +557,44 @@ ADD_EXPORTS("--add-exports", "opt.arg.addExports", "opt.addExports", EXTENDED, BASIC) { @Override public boolean process(OptionHelper helper, String option, String arg) { - String prev = helper.get(ADD_EXPORTS); - helper.put(ADD_EXPORTS.primaryName, (prev == null) ? arg : prev + '\0' + arg); - return false; + if (arg.isEmpty()) { + helper.error("err.no.value.for.option", option); + return true; + } else if (getPattern().matcher(arg).matches()) { + String prev = helper.get(ADD_EXPORTS); + helper.put(ADD_EXPORTS.primaryName, (prev == null) ? arg : prev + '\0' + arg); + return false; + } else { + helper.error("err.bad.value.for.option", option, arg); + return true; + } + } + + @Override + public Pattern getPattern() { + return Pattern.compile("([^/]+)/([^=]+)=(,*[^,].*)"); } }, ADD_READS("--add-reads", "opt.arg.addReads", "opt.addReads", EXTENDED, BASIC) { @Override public boolean process(OptionHelper helper, String option, String arg) { - String prev = helper.get(ADD_READS); - helper.put(ADD_READS.primaryName, (prev == null) ? arg : prev + '\0' + arg); - return false; + if (arg.isEmpty()) { + helper.error("err.no.value.for.option", option); + return true; + } else if (getPattern().matcher(arg).matches()) { + String prev = helper.get(ADD_READS); + helper.put(ADD_READS.primaryName, (prev == null) ? arg : prev + '\0' + arg); + return false; + } else { + helper.error("err.bad.value.for.option", option, arg); + return true; + } + } + + @Override + public Pattern getPattern() { + return Pattern.compile("([^=]+)=(,*[^,].*)"); } }, @@ -577,6 +604,7 @@ String prev = helper.get(XMODULE); if (prev != null) { helper.error("err.option.too.many", XMODULE.primaryName); + return true; } helper.put(XMODULE.primaryName, arg); return false; @@ -585,9 +613,50 @@ MODULE("--module -m", "opt.arg.m", "opt.m", STANDARD, BASIC), - ADD_MODULES("--add-modules", "opt.arg.addmods", "opt.addmods", STANDARD, BASIC), + ADD_MODULES("--add-modules", "opt.arg.addmods", "opt.addmods", STANDARD, BASIC) { + @Override + public boolean process(OptionHelper helper, String option, String arg) { + if (arg.isEmpty()) { + helper.error("err.no.value.for.option", option); + return true; + } else if (getPattern().matcher(arg).matches()) { + String prev = helper.get(ADD_MODULES); + // since the individual values are simple names, we can simply join the + // values of multiple --add-modules options with ',' + helper.put(ADD_MODULES.primaryName, (prev == null) ? arg : prev + ',' + arg); + return false; + } else { + helper.error("err.bad.value.for.option", option, arg); + return true; + } + } - LIMIT_MODULES("--limit-modules", "opt.arg.limitmods", "opt.limitmods", STANDARD, BASIC), + @Override + public Pattern getPattern() { + return Pattern.compile(",*[^,].*"); + } + }, + + LIMIT_MODULES("--limit-modules", "opt.arg.limitmods", "opt.limitmods", STANDARD, BASIC) { + @Override + public boolean process(OptionHelper helper, String option, String arg) { + if (arg.isEmpty()) { + helper.error("err.no.value.for.option", option); + return true; + } else if (getPattern().matcher(arg).matches()) { + helper.put(LIMIT_MODULES.primaryName, arg); // last one wins + return false; + } else { + helper.error("err.bad.value.for.option", option, arg); + return true; + } + } + + @Override + public Pattern getPattern() { + return Pattern.compile(",*[^,].*"); + } + }, // This option exists only for the purpose of documenting itself. // It's actually implemented by the CommandLine class. @@ -963,20 +1032,24 @@ */ public boolean handleOption(OptionHelper helper, String arg, Iterator rest) { if (hasArg()) { + String option; String operand; int sep = findSeparator(arg); if (getArgKind() == Option.ArgKind.ADJACENT) { + option = primaryName; // aliases not supported operand = arg.substring(primaryName.length()); } else if (sep > 0) { + option = arg.substring(0, sep); operand = arg.substring(sep + 1); } else { if (!rest.hasNext()) { helper.error("err.req.arg", arg); return false; } + option = arg; operand = rest.next(); } - return !process(helper, arg, operand); + return !process(helper, option, operand); } else { return !process(helper, arg); } @@ -1033,6 +1106,15 @@ } /** + * Returns a pattern to analyze the value for an option. + * @return the pattern + * @throws UnsupportedOperationException if an option does not provide a pattern. + */ + public Pattern getPattern() { + throw new UnsupportedOperationException(); + } + + /** * Scans a word to find the first separator character, either colon or equals. * @param word the word to be scanned * @return the position of the first':' or '=' character in the word, diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Nov 04 17:52:11 2016 +0000 @@ -2844,21 +2844,13 @@ compiler.err.duplicate.module.on.path=\ duplicate module on {0}\nmodule in {1} -# 0: string -compiler.err.xaddexports.malformed.entry=\ - bad value for --add-exports {0} - -# 0: string -compiler.err.xaddexports.too.many=\ - multiple --add-exports options for {0} - -# 0: string -compiler.err.xaddreads.malformed.entry=\ - bad value for --add-reads {0} - -# 0: string -compiler.err.xaddreads.too.many=\ - multiple --add-reads options for {0} +# 0: option name, 1: string +compiler.warn.bad.name.for.option=\ + bad name in value for {0} option: ''{1}'' + +# 0: option name, 1: symbol +compiler.warn.module.for.option.not.found=\ + module name in {0} option not found: {1} compiler.err.addmods.all.module.path.invalid=\ --add-modules ALL-MODULE-PATH can only be used when compiling the unnamed module @@ -2878,10 +2870,6 @@ compiler.misc.cant.resolve.modules=\ cannot resolve modules -# 0: symbol -compiler.err.cant.find.module=\ - cannot find module: {0} - # 0: string compiler.err.invalid.module.specifier=\ module specifier not allowed: {0} diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties Fri Nov 04 17:52:11 2016 +0000 @@ -357,6 +357,10 @@ not a file: {0} javac.err.cannot.access.runtime.env=\ cannot access runtime environment +javac.err.bad.value.for.option=\ + bad value for {0} option: ''{1}'' +javac.err.no.value.for.option=\ + no value for {0} option ## messages diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java Fri Nov 04 17:52:11 2016 +0000 @@ -48,6 +48,7 @@ import com.sun.tools.javac.code.Type.CapturedType; import com.sun.tools.javac.file.PathFileObject; import com.sun.tools.javac.jvm.Profile; +import com.sun.tools.javac.main.Option; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.Pretty; @@ -204,6 +205,9 @@ else if (arg instanceof Profile) { return ((Profile)arg).name; } + else if (arg instanceof Option) { + return ((Option)arg).primaryName; + } else if (arg instanceof Formattable) { return ((Formattable)arg).toString(l, messages); } diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Fri Nov 04 17:52:11 2016 +0000 @@ -29,7 +29,6 @@ import jdk.jshell.SourceCodeAnalysis.QualifiedNames; import jdk.jshell.SourceCodeAnalysis.Suggestion; -import java.awt.event.ActionListener; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; @@ -171,10 +170,10 @@ return anchor[0]; } }); - bind(DOCUMENTATION_SHORTCUT, (ActionListener) evt -> documentation(repl)); + bind(DOCUMENTATION_SHORTCUT, (Runnable) () -> documentation(repl)); for (FixComputer computer : FIX_COMPUTERS) { for (String shortcuts : SHORTCUT_FIXES) { - bind(shortcuts + computer.shortcut, (ActionListener) evt -> fixes(computer)); + bind(shortcuts + computer.shortcut, (Runnable) () -> fixes(computer)); } } try { diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/EditPad.java --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/EditPad.java Fri Nov 04 17:24:26 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2015, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -package jdk.internal.jshell.tool; - -import java.awt.BorderLayout; -import java.awt.FlowLayout; -import java.awt.event.KeyEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.util.concurrent.CountDownLatch; -import java.util.function.Consumer; -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; -import javax.swing.SwingUtilities; - -/** - * A minimal Swing editor as a fallback when the user does not specify an - * external editor. - */ -@SuppressWarnings("serial") // serialVersionUID intentionally omitted -public class EditPad extends JFrame implements Runnable { - private final Consumer errorHandler; // For possible future error handling - private final String initialText; - private final CountDownLatch closeLock; - private final Consumer saveHandler; - - EditPad(Consumer errorHandler, String initialText, - CountDownLatch closeLock, Consumer saveHandler) { - super("JShell Edit Pad"); - this.errorHandler = errorHandler; - this.initialText = initialText; - this.closeLock = closeLock; - this.saveHandler = saveHandler; - } - - @Override - public void run() { - addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - EditPad.this.dispose(); - closeLock.countDown(); - } - }); - setLocationRelativeTo(null); - setLayout(new BorderLayout()); - JTextArea textArea = new JTextArea(initialText); - add(new JScrollPane(textArea), BorderLayout.CENTER); - add(buttons(textArea), BorderLayout.SOUTH); - - setSize(800, 600); - setVisible(true); - } - - private JPanel buttons(JTextArea textArea) { - FlowLayout flow = new FlowLayout(); - flow.setHgap(35); - JPanel buttons = new JPanel(flow); - JButton cancel = new JButton("Cancel"); - cancel.setMnemonic(KeyEvent.VK_C); - JButton accept = new JButton("Accept"); - accept.setMnemonic(KeyEvent.VK_A); - JButton exit = new JButton("Exit"); - exit.setMnemonic(KeyEvent.VK_X); - buttons.add(cancel); - buttons.add(accept); - buttons.add(exit); - - cancel.addActionListener(e -> { - close(); - }); - accept.addActionListener(e -> { - saveHandler.accept(textArea.getText()); - }); - exit.addActionListener(e -> { - saveHandler.accept(textArea.getText()); - close(); - }); - - return buttons; - } - - private void close() { - setVisible(false); - dispose(); - closeLock.countDown(); - } - - public static void edit(Consumer errorHandler, String initialText, - Consumer saveHandler) { - CountDownLatch closeLock = new CountDownLatch(1); - SwingUtilities.invokeLater( - new EditPad(errorHandler, initialText, closeLock, saveHandler)); - do { - try { - closeLock.await(); - break; - } catch (InterruptedException ex) { - // ignore and loop - } - } while (true); - } -} diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ExternalEditor.java --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ExternalEditor.java Fri Nov 04 17:24:26 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2015, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -package jdk.internal.jshell.tool; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.file.ClosedWatchServiceException; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.WatchKey; -import java.nio.file.WatchService; -import java.util.Arrays; -import java.util.Scanner; -import java.util.function.Consumer; -import java.util.stream.Collectors; -import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; -import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE; -import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; - -/** - * Wrapper for controlling an external editor. - */ -public class ExternalEditor { - private final Consumer errorHandler; - private final Consumer saveHandler; - private final Consumer printHandler; - private final IOContext input; - private final boolean wait; - - private WatchService watcher; - private Thread watchedThread; - private Path dir; - private Path tmpfile; - - ExternalEditor(Consumer errorHandler, Consumer saveHandler, - IOContext input, boolean wait, Consumer printHandler) { - this.errorHandler = errorHandler; - this.saveHandler = saveHandler; - this.printHandler = printHandler; - this.input = input; - this.wait = wait; - } - - private void edit(String[] cmd, String initialText) { - try { - setupWatch(initialText); - launch(cmd); - } catch (IOException ex) { - errorHandler.accept(ex.getMessage()); - } - } - - /** - * Creates a WatchService and registers the given directory - */ - private void setupWatch(String initialText) throws IOException { - this.watcher = FileSystems.getDefault().newWatchService(); - this.dir = Files.createTempDirectory("jshelltemp"); - this.tmpfile = Files.createTempFile(dir, null, ".java"); - Files.write(tmpfile, initialText.getBytes(Charset.forName("UTF-8"))); - dir.register(watcher, - ENTRY_CREATE, - ENTRY_DELETE, - ENTRY_MODIFY); - watchedThread = new Thread(() -> { - for (;;) { - WatchKey key; - try { - key = watcher.take(); - } catch (ClosedWatchServiceException ex) { - // The watch service has been closed, we are done - break; - } catch (InterruptedException ex) { - // tolerate an interrupt - continue; - } - - if (!key.pollEvents().isEmpty()) { - // Changes have occurred in temp edit directory, - // transfer the new sources to JShell (unless the editor is - // running directly in JShell's window -- don't make a mess) - if (!input.terminalEditorRunning()) { - saveFile(); - } - } - - boolean valid = key.reset(); - if (!valid) { - // The watch service has been closed, we are done - break; - } - } - }); - watchedThread.start(); - } - - private void launch(String[] cmd) throws IOException { - String[] params = Arrays.copyOf(cmd, cmd.length + 1); - params[cmd.length] = tmpfile.toString(); - ProcessBuilder pb = new ProcessBuilder(params); - pb = pb.inheritIO(); - - try { - input.suspend(); - Process process = pb.start(); - // wait to exit edit mode in one of these ways... - if (wait) { - // -wait option -- ignore process exit, wait for carriage-return - Scanner scanner = new Scanner(System.in); - printHandler.accept("jshell.msg.press.return.to.leave.edit.mode"); - scanner.nextLine(); - } else { - // wait for process to exit - process.waitFor(); - } - } catch (IOException ex) { - errorHandler.accept("process IO failure: " + ex.getMessage()); - } catch (InterruptedException ex) { - errorHandler.accept("process interrupt: " + ex.getMessage()); - } finally { - try { - watcher.close(); - watchedThread.join(); //so that saveFile() is finished. - saveFile(); - } catch (InterruptedException ex) { - errorHandler.accept("process interrupt: " + ex.getMessage()); - } finally { - input.resume(); - } - } - } - - private void saveFile() { - try { - saveHandler.accept(Files.lines(tmpfile).collect(Collectors.joining("\n", "", "\n"))); - } catch (IOException ex) { - errorHandler.accept("Failure in read edit file: " + ex.getMessage()); - } - } - - static void edit(String[] cmd, Consumer errorHandler, String initialText, - Consumer saveHandler, IOContext input, boolean wait, Consumer printHandler) { - ExternalEditor ed = new ExternalEditor(errorHandler, saveHandler, input, wait, printHandler); - ed.edit(cmd, initialText); - } -} diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java Fri Nov 04 17:52:11 2016 +0000 @@ -116,6 +116,10 @@ name, type, value, unresolved, errorLines); } + public String truncateVarValue(String value) { + return mode.truncateVarValue(value); + } + public String getPrompt(String nextId) { return mode.getPrompt(nextId); } @@ -416,6 +420,45 @@ return sb.toString(); } + String truncateVarValue(String value) { + return truncateValue(value, + bits(FormatCase.VARVALUE, FormatAction.ADDED, + FormatWhen.PRIMARY, FormatResolve.OK, + FormatUnresolved.UNRESOLVED0, FormatErrors.ERROR0)); + } + + String truncateValue(String value, long bits) { + if (value==null) { + return ""; + } else { + // Retrieve the truncation length + String truncField = format(TRUNCATION_FIELD, bits); + if (truncField.isEmpty()) { + // No truncation set, use whole value + return value; + } else { + // Convert truncation length to int + // this is safe since it has been tested before it is set + int trunc = Integer.parseUnsignedInt(truncField); + int len = value.length(); + if (len > trunc) { + if (trunc <= 13) { + // Very short truncations have no room for "..." + return value.substring(0, trunc); + } else { + // Normal truncation, make total length equal truncation length + int endLen = trunc / 3; + int startLen = trunc - 5 - endLen; + return value.substring(0, startLen) + " ... " + value.substring(len -endLen); + } + } else { + // Within truncation length, use whole value + return value; + } + } + } + } + // Compute the display output given full context and values String format(FormatCase fc, FormatAction fa, FormatWhen fw, FormatResolve fr, FormatUnresolved fu, FormatErrors fe, @@ -425,33 +468,7 @@ String fname = name==null? "" : name; String ftype = type==null? "" : type; // Compute the representation of value - String fvalue; - if (value==null) { - fvalue = ""; - } else { - // Retrieve the truncation length - String truncField = format(TRUNCATION_FIELD, bits); - if (truncField.isEmpty()) { - // No truncation set, use whole value - fvalue = value; - } else { - // Convert truncation length to int - // this is safe since it has been tested before it is set - int trunc = Integer.parseUnsignedInt(truncField); - if (value.length() > trunc) { - if (trunc <= 5) { - // Very short truncations have no room for "..." - fvalue = value.substring(0, trunc); - } else { - // Normal truncation, make total length equal truncation length - fvalue = value.substring(0, trunc - 4) + " ..."; - } - } else { - // Within truncation length, use whole value - fvalue = value; - } - } - } + String fvalue = truncateValue(value, bits); String funresolved = unresolved==null? "" : unresolved; String errors = errorLines.stream() .map(el -> String.format( diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Fri Nov 04 17:52:11 2016 +0000 @@ -89,6 +89,7 @@ import java.util.MissingResourceException; import java.util.Optional; import java.util.ResourceBundle; +import java.util.ServiceLoader; import java.util.Spliterators; import java.util.function.Function; import java.util.function.Supplier; @@ -99,6 +100,8 @@ import jdk.internal.jshell.tool.Feedback.FormatResolve; import jdk.internal.jshell.tool.Feedback.FormatUnresolved; import jdk.internal.jshell.tool.Feedback.FormatWhen; +import jdk.internal.editor.spi.BuildInEditorProvider; +import jdk.internal.editor.external.ExternalEditor; import static java.util.Arrays.asList; import static java.util.Arrays.stream; import static java.util.stream.Collectors.joining; @@ -323,7 +326,7 @@ } /** - * Print using resource bundle look-up and adding prefix and postfix + * Resource bundle look-up * * @param key the resource key */ @@ -523,7 +526,7 @@ runFile(loadFile, "jshell"); } - if (regenerateOnDeath) { + if (regenerateOnDeath && feedback.shouldDisplayCommandFluff()) { hardmsg("jshell.msg.welcome", version()); } @@ -1978,20 +1981,59 @@ Consumer saveHandler = new SaveHandler(src, srcSet); Consumer errorHandler = s -> hard("Edit Error: %s", s); if (editor == BUILT_IN_EDITOR) { - try { - EditPad.edit(errorHandler, src, saveHandler); - } catch (RuntimeException ex) { - errormsg("jshell.err.cant.launch.editor", ex); - fluffmsg("jshell.msg.try.set.editor"); - return false; + return builtInEdit(src, saveHandler, errorHandler); + } else { + // Changes have occurred in temp edit directory, + // transfer the new sources to JShell (unless the editor is + // running directly in JShell's window -- don't make a mess) + String[] buffer = new String[1]; + Consumer extSaveHandler = s -> { + if (input.terminalEditorRunning()) { + buffer[0] = s; + } else { + saveHandler.accept(s); + } + }; + ExternalEditor.edit(editor.cmd, src, + errorHandler, extSaveHandler, + () -> input.suspend(), + () -> input.resume(), + editor.wait, + () -> hardrb("jshell.msg.press.return.to.leave.edit.mode")); + if (buffer[0] != null) { + saveHandler.accept(buffer[0]); } - } else { - ExternalEditor.edit(editor.cmd, errorHandler, src, saveHandler, input, - editor.wait, this::hardrb); } return true; } //where + // start the built-in editor + private boolean builtInEdit(String initialText, + Consumer saveHandler, Consumer errorHandler) { + try { + ServiceLoader sl + = ServiceLoader.load(BuildInEditorProvider.class); + // Find the highest ranking provider + BuildInEditorProvider provider = null; + for (BuildInEditorProvider p : sl) { + if (provider == null || p.rank() > provider.rank()) { + provider = p; + } + } + if (provider != null) { + provider.edit(getResourceString("jshell.label.editpad"), + initialText, saveHandler, errorHandler); + return true; + } else { + errormsg("jshell.err.no.builtin.editor"); + } + } catch (RuntimeException ex) { + errormsg("jshell.err.cant.launch.editor", ex); + } + fluffmsg("jshell.msg.try.set.editor"); + return false; + } + //where // receives editor requests to save private class SaveHandler implements Consumer { @@ -2198,7 +2240,7 @@ stream.forEachOrdered(vk -> { String val = state.status(vk) == Status.VALID - ? state.varValue(vk) + ? feedback.truncateVarValue(state.varValue(vk)) : getResourceString("jshell.msg.vars.not.active"); hard(" %s %s = %s", vk.typeName(), vk.name(), val); }); diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Fri Nov 04 17:52:11 2016 +0000 @@ -54,10 +54,12 @@ jshell.err.command.ambiguous = Command: ''{0}'' is ambiguous: {1} jshell.msg.set.editor.set = Editor set to: {0} jshell.msg.set.editor.retain = Editor setting retained: {0} -jshell.err.cant.launch.editor = Cannot launch editor -- unexpected exception: {0} -jshell.msg.try.set.editor = Try /set editor to use external editor. +jshell.err.no.builtin.editor = Built-in editor not available. +jshell.err.cant.launch.editor = Cannot launch built-in editor -- unexpected exception: {0} +jshell.msg.try.set.editor = See ''/help /set editor'' to use external editor. jshell.msg.press.return.to.leave.edit.mode = Press return to leave edit mode. jshell.err.wait.applies.to.external.editor = -wait applies to external editors +jshell.label.editpad = JShell Edit Pad jshell.err.setting.to.retain.must.be.specified = The setting to retain must be specified -- {0} jshell.msg.set.show.mode.settings = \nTo show mode settings use ''/set prompt'', ''/set truncation'', ...\n\ @@ -336,7 +338,7 @@ Reset and replay the valid history between the previous and most\n\t\ recent time that jshell was entered, or a /reset, or /reload\n\t\ command was executed. This can thus be used to restore a previous\n\t\ - jshell tool sesson.\n\n\ + jshell tool session.\n\n\ /reload [-restore] -quiet\n\t\ With the '-quiet' argument the replay is not shown. Errors will display. diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/src/jdk.jshell/share/classes/module-info.java --- a/langtools/src/jdk.jshell/share/classes/module-info.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/src/jdk.jshell/share/classes/module-info.java Fri Nov 04 17:52:11 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, 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 @@ -30,14 +30,16 @@ */ module jdk.jshell { requires public java.compiler; - requires java.desktop; requires java.prefs; requires jdk.compiler; requires jdk.internal.le; + requires jdk.internal.ed; requires jdk.internal.opt; requires jdk.jdi; exports jdk.jshell; exports jdk.jshell.spi; exports jdk.jshell.execution; + + uses jdk.internal.editor.spi.BuildInEditorProvider; } diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/jdk/jshell/EditorPadTest.java --- a/langtools/test/jdk/jshell/EditorPadTest.java Fri Nov 04 17:24:26 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,246 +0,0 @@ -/* - * Copyright (c) 2015, 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 8139872 - * @summary Testing built-in editor. - * @modules java.desktop/java.awt - * jdk.jshell/jdk.internal.jshell.tool - * @build ReplToolTesting EditorTestBase - * @run testng EditorPadTest - */ - -import java.awt.AWTException; -import java.awt.Component; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.Frame; -import java.awt.GraphicsEnvironment; -import java.awt.Point; -import java.awt.Robot; -import java.awt.event.InputEvent; -import java.awt.event.WindowEvent; -import java.lang.reflect.InvocationTargetException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.function.Consumer; - -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; -import javax.swing.JViewport; -import javax.swing.SwingUtilities; - -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -public class EditorPadTest extends EditorTestBase { - - private static final int DELAY = 500; - - private static Robot robot; - private static JFrame frame = null; - private static JTextArea area = null; - private static JButton cancel = null; - private static JButton accept = null; - private static JButton exit = null; - - // Do not actually run if we are headless - @Override - public void testEditor(boolean defaultStartup, String[] args, ReplTest... tests) { - if (!GraphicsEnvironment.isHeadless()) { - test(defaultStartup, args, tests); - } - } - - @BeforeClass - public static void setUpEditorPadTest() { - if (!GraphicsEnvironment.isHeadless()) { - try { - robot = new Robot(); - robot.setAutoWaitForIdle(true); - robot.setAutoDelay(DELAY); - } catch (AWTException e) { - throw new ExceptionInInitializerError(e); - } - } - } - - @AfterClass - public static void shutdown() { - executorShutdown(); - } - - @Override - public void writeSource(String s) { - SwingUtilities.invokeLater(() -> area.setText(s)); - } - - @Override - public String getSource() { - try { - String[] s = new String[1]; - SwingUtilities.invokeAndWait(() -> s[0] = area.getText()); - return s[0]; - } catch (InvocationTargetException | InterruptedException e) { - throw new RuntimeException(e); - } - } - - @Override - public void accept() { - clickOn(accept); - } - - @Override - public void exit() { - clickOn(exit); - } - - @Override - public void cancel() { - clickOn(cancel); - } - - @Override - public void shutdownEditor() { - SwingUtilities.invokeLater(this::clearElements); - waitForIdle(); - } - - @Test - public void testShuttingDown() { - testEditor( - (a) -> assertEditOutput(a, "/ed", "", this::shutdownEditor) - ); - } - - private void waitForIdle() { - robot.waitForIdle(); - robot.delay(DELAY); - } - - private Future task; - @Override - public void assertEdit(boolean after, String cmd, - Consumer checkInput, Consumer checkOutput, Action action) { - if (!after) { - setCommandInput(cmd + "\n"); - task = getExecutor().submit(() -> { - try { - waitForIdle(); - SwingUtilities.invokeLater(this::seekElements); - waitForIdle(); - checkInput.accept(getSource()); - action.accept(); - } catch (Throwable e) { - shutdownEditor(); - if (e instanceof AssertionError) { - throw (AssertionError) e; - } - throw new RuntimeException(e); - } - }); - } else { - try { - task.get(); - waitForIdle(); - checkOutput.accept(getCommandOutput()); - } catch (ExecutionException e) { - if (e.getCause() instanceof AssertionError) { - throw (AssertionError) e.getCause(); - } - throw new RuntimeException(e); - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - shutdownEditor(); - } - } - } - - private void seekElements() { - for (Frame f : Frame.getFrames()) { - if (f.getTitle().contains("Edit Pad")) { - frame = (JFrame) f; - // workaround - frame.setLocation(0, 0); - Container root = frame.getContentPane(); - for (Component c : root.getComponents()) { - if (c instanceof JScrollPane) { - JScrollPane scrollPane = (JScrollPane) c; - for (Component comp : scrollPane.getComponents()) { - if (comp instanceof JViewport) { - JViewport view = (JViewport) comp; - area = (JTextArea) view.getComponent(0); - } - } - } - if (c instanceof JPanel) { - JPanel p = (JPanel) c; - for (Component comp : p.getComponents()) { - if (comp instanceof JButton) { - JButton b = (JButton) comp; - switch (b.getText()) { - case "Cancel": - cancel = b; - break; - case "Exit": - exit = b; - break; - case "Accept": - accept = b; - break; - } - } - } - } - } - } - } - } - - private void clearElements() { - if (frame != null) { - frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING)); - frame = null; - } - area = null; - accept = null; - cancel = null; - exit = null; - } - - private void clickOn(JButton button) { - waitForIdle(); - Point p = button.getLocationOnScreen(); - Dimension d = button.getSize(); - robot.mouseMove(p.x + d.width / 2, p.y + d.height / 2); - robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); - } -} diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/jdk/jshell/ToolFormatTest.java --- a/langtools/test/jdk/jshell/ToolFormatTest.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/test/jdk/jshell/ToolFormatTest.java Fri Nov 04 17:52:11 2016 +0000 @@ -23,7 +23,7 @@ /* * @test - * @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261 8163840 + * @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261 8163840 8166637 8161969 * @summary Tests for output customization * @library /tools/lib * @modules jdk.compiler/com.sun.tools.javac.api @@ -220,8 +220,8 @@ test( (a) -> assertCommandOutputStartsWith(a, "/set feedback normal", ""), (a) -> assertCommand(a, "String s = java.util.stream.IntStream.range(65, 74)"+ - ".mapToObj(i -> \"\"+(char)i).reduce((a,b) -> a + b + a).get()", - "s ==> \"ABACABADABACABAEABACABADABACABAFABACABADABACABAEABACABADABACABAGABACABADABA ..."), + ".mapToObj(i -> \"\"+(char)i).reduce((a,b) -> a + b + a).get() + \"XYZ\"", + "s ==> \"ABACABADABACABAEABACABADABACABAFABACABADABACABAE ... BACABAEABACABADABACABAXYZ\""), (a) -> assertCommandOutputStartsWith(a, "/set mode test -quiet", ""), (a) -> assertCommandOutputStartsWith(a, "/set feedback test", ""), (a) -> assertCommand(a, "/set format test display '{type}:{value}' primary", ""), @@ -234,8 +234,9 @@ "/set truncation test 10 varvalue"), (a) -> assertCommandOutputContains(a, "/set truncation test", "/set truncation test 10 varvalue"), - (a) -> assertCommand(a, "String r = s", "String:\"ABACABADABACABA ..."), - (a) -> assertCommand(a, "r", "String:\"ABACA ..."), + (a) -> assertCommand(a, "/var", "| String s = \"ABACABADA"), + (a) -> assertCommand(a, "String r = s", "String:\"ABACABAD ... BAXYZ\""), + (a) -> assertCommand(a, "r", "String:\"ABACABADA"), (a) -> assertCommand(a, "r=s", "String:\"AB") ); } finally { diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/jdk/jshell/ToolRetainTest.java --- a/langtools/test/jdk/jshell/ToolRetainTest.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/test/jdk/jshell/ToolRetainTest.java Fri Nov 04 17:52:11 2016 +0000 @@ -23,13 +23,14 @@ /* * @test - * @bug 8157200 8163840 + * @bug 8157200 8163840 8154513 * @summary Tests of what information is retained across jshell tool runs * @modules jdk.jshell/jdk.internal.jshell.tool * @build ToolRetainTest ReplToolTesting * @run testng ToolRetainTest */ +import java.util.Locale; import org.testng.annotations.Test; @Test @@ -62,14 +63,14 @@ (a) -> assertCommand(a, "/set mode -retain trm1", ""), (a) -> assertCommand(a, "/exit", "") ); - test( + test(Locale.ROOT, true, new String[0], "", (a) -> assertCommand(a, "/set mode trm2 -quiet", ""), (a) -> assertCommand(a, "/set format trm2 display '{name}={value}'", ""), (a) -> assertCommand(a, "int x = 45", "x:45"), (a) -> assertCommand(a, "/set mode -retain trm2", ""), (a) -> assertCommand(a, "/exit", "") ); - test( + test(Locale.ROOT, true, new String[0], "", (a) -> assertCommandOutputContains(a, "/set mode trm1", "/set format trm1 display \"{name}:{value}\""), (a) -> assertCommand(a, "/set format trm2 display", diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/jdk/jshell/ToolSimpleTest.java --- a/langtools/test/jdk/jshell/ToolSimpleTest.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/test/jdk/jshell/ToolSimpleTest.java Fri Nov 04 17:52:11 2016 +0000 @@ -23,7 +23,7 @@ /* * @test - * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 + * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513 * @summary Simple jshell tool tests * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main @@ -35,6 +35,7 @@ import java.util.Arrays; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -465,14 +466,14 @@ } public void testOptionQ() { - test(new String[]{"-q", "--no-startup"}, + test(Locale.ROOT, false, new String[]{"-q", "--no-startup"}, "", (a) -> assertCommand(a, "1+1", "$1 ==> 2"), (a) -> assertCommand(a, "int x = 5", "") ); } public void testOptionS() { - test(new String[]{"-s", "--no-startup"}, + test(Locale.ROOT, false, new String[]{"-s", "--no-startup"}, "", (a) -> assertCommand(a, "1+1", "") ); } @@ -486,7 +487,7 @@ } public void testOptionFeedback() { - test(new String[]{"--feedback", "concise", "--no-startup"}, + test(Locale.ROOT, false, new String[]{"--feedback", "concise", "--no-startup"}, "", (a) -> assertCommand(a, "1+1", "$1 ==> 2"), (a) -> assertCommand(a, "int x = 5", "") ); @@ -498,17 +499,17 @@ .filter(l -> !l.isEmpty()) .count(), "Expected no lines: " + s); }; - test(new String[]{"-nq"}, + test(Locale.ROOT, false, new String[]{"-nq"}, "", (a) -> assertCommandCheckOutput(a, "/list -all", confirmNoStartup), (a) -> assertCommand(a, "1+1", "$1 ==> 2"), (a) -> assertCommand(a, "int x = 5", "") ); - test(new String[]{"-qn"}, + test(Locale.ROOT, false, new String[]{"-qn"}, "", (a) -> assertCommandCheckOutput(a, "/list -all", confirmNoStartup), (a) -> assertCommand(a, "1+1", "$1 ==> 2"), (a) -> assertCommand(a, "int x = 5", "") ); - test(new String[]{"-ns"}, + test(Locale.ROOT, false, new String[]{"-ns"}, "", (a) -> assertCommandCheckOutput(a, "/list -all", confirmNoStartup), (a) -> assertCommand(a, "1+1", "") ); diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/doclint/moduleTests/bad/module-info.java --- a/langtools/test/tools/doclint/moduleTests/bad/module-info.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/test/tools/doclint/moduleTests/bad/module-info.java Fri Nov 04 17:52:11 2016 +0000 @@ -6,7 +6,7 @@ * @modules jdk.compiler/com.sun.tools.doclint * @build DocLintTester * @run main DocLintTester -ref module-info.out module-info.java - * @compile/fail/ref=module-info.javac.out -XDrawDiagnostics -Werror -Xdoclint:all module-info.java + * @compile/fail/ref=module-info.javac.out -XDrawDiagnostics -Werror -Xlint:-options -Xdoclint:all module-info.java */ // missing doc comment diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/doclint/moduleTests/good/module-info.java --- a/langtools/test/tools/doclint/moduleTests/good/module-info.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/test/tools/doclint/moduleTests/good/module-info.java Fri Nov 04 17:52:11 2016 +0000 @@ -29,7 +29,7 @@ * @modules jdk.compiler/com.sun.tools.doclint * @build DocLintTester * @run main DocLintTester module-info.java - * @compile -Xdoclint:all -Werror module-info.java + * @compile -Xdoclint:all -Werror -Xlint:-options module-info.java */ /** good module */ diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/PackageClassAmbiguity/util.out diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/T5003235/T5003235a.java diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/T5003235/T5003235a.out diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/T5003235/T5003235b.java diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/T5003235/T5003235b.out diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/T6403466.java --- a/langtools/test/tools/javac/T6403466.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/test/tools/javac/T6403466.java Fri Nov 04 17:52:11 2016 +0000 @@ -58,9 +58,7 @@ fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrcDir, self + ".java"))); Iterable options = Arrays.asList( - "--add-exports", - "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED," - + "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", "--processor-path", testClassDir, "-processor", self, "-s", ".", diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/diags/Example.java diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/diags/RunExamples.java diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/diags/examples.not-yet.txt diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/diags/examples/BadNameForOption.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/BadNameForOption.java Fri Nov 04 17:52:11 2016 +0000 @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016, 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. + */ + +// key: compiler.warn.bad.name.for.option +// options: --add-exports Bad!Name/p=java.base + +class BadNameForOption { } + diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/diags/examples/CantFindModule/CantFindModule.java --- a/langtools/test/tools/javac/diags/examples/CantFindModule/CantFindModule.java Fri Nov 04 17:24:26 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2016, 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. - */ - -// key: compiler.err.cant.find.module -// key: compiler.err.doesnt.exist - -// options: --add-exports undef/undef=ALL-UNNAMED - -import undef.Any; - -class Test {} diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/diags/examples/ModuleForOptionNotFound.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/ModuleForOptionNotFound.java Fri Nov 04 17:52:11 2016 +0000 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016, 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. + */ + +// key: compiler.warn.module.for.option.not.found +// key: compiler.err.doesnt.exist + +// options: --add-exports undefModule/undefPackage=ALL-UNNAMED + +import undefPackage.Any; + +class Test {} + diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/diags/examples/XaddexportsMalformedEntry.java --- a/langtools/test/tools/javac/diags/examples/XaddexportsMalformedEntry.java Fri Nov 04 17:24:26 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016, 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. - */ - -// key: compiler.err.xaddexports.malformed.entry -// options: --add-exports jdk.compiler/com.sun.tools.javac.util - -public class XaddexportsMalformedEntry { -} diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/diags/examples/XaddexportsTooMany.java --- a/langtools/test/tools/javac/diags/examples/XaddexportsTooMany.java Fri Nov 04 17:24:26 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016, 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. - */ - -// key: compiler.err.xaddexports.too.many -// options: --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED - -public class XaddexportsTooMany { -} diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/diags/examples/XaddreadsMalformedEntry.java --- a/langtools/test/tools/javac/diags/examples/XaddreadsMalformedEntry.java Fri Nov 04 17:24:26 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016, 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. - */ - -// key: compiler.err.xaddreads.malformed.entry -// options: --add-reads jdk.compiler - -public class XaddreadsMalformedEntry { -} diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/diags/examples/XaddreadsTooMany.java --- a/langtools/test/tools/javac/diags/examples/XaddreadsTooMany.java Fri Nov 04 17:24:26 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016, 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. - */ - -// key: compiler.err.xaddreads.too.many -// options: --add-reads jdk.compiler=ALL-UNNAMED --add-reads jdk.compiler=ALL-UNNAMED - -public class XaddreadsTooMany { -} diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/modules/AddExportsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/modules/AddExportsTest.java Fri Nov 04 17:52:11 2016 +0000 @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2015, 2016, 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 + * @summary Test the --add-exports option + * @library /tools/lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase + * @run main AddExportsTest + */ + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Set; + +import toolbox.JavacTask; +import toolbox.Task; +import toolbox.ToolBox; + +public class AddExportsTest extends ModuleTestBase { + + public static void main(String... args) throws Exception { + new AddExportsTest().runTests(); + } + + @Test + public void testEmpty(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "class Dummy { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + testEmpty(src, classes, "--add-exports", ""); + testEmpty(src, classes, "--add-exports="); + } + + private void testEmpty(Path src, Path classes, String... options) throws Exception { + String log = new JavacTask(tb, Task.Mode.CMDLINE) + .options(options) + .outdir(classes) + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "javac: no value for --add-exports option"); + } + + @Test + public void testEmptyItem(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { }", + "package p1; public class C1 { }"); + Path src_m2 = src.resolve("m2"); + tb.writeJavaFiles(src_m2, + "module m2 { }", + "package p2; class C2 { p1.C1 c1; }"); + Path src_m3 = src.resolve("m3"); + tb.writeJavaFiles(src_m3, + "module m3 { }", + "package p3; class C3 { p1.C1 c1; }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + testEmptyItem(src, classes, "m1/p1=,m2,m3"); + testEmptyItem(src, classes, "m1/p1=m2,,m3"); + testEmptyItem(src, classes, "m1/p1=m2,m3,"); + } + + void testEmptyItem(Path src, Path classes, String option) throws Exception { + new JavacTask(tb) + .options("--module-source-path", src.toString(), + "--add-exports", option) + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll(); + } + + @Test + public void testEmptyList(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { exports p1; }", + "package p1; public class C1 { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + testEmptyList(src, classes, "m1/p1="); + testEmptyList(src, classes, "m1/p1=,"); + } + + void testEmptyList(Path src, Path classes, String option) throws Exception { + String log = new JavacTask(tb, Task.Mode.CMDLINE) + .options("--module-source-path", src.toString(), + "--add-exports", option) + .outdir(classes) + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "javac: bad value for --add-exports option: '" + option + "'"); + } + + @Test + public void testMissingSourceParts(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { exports p1; }", + "package p1; public class C1 { }"); + Path src_m2 = src.resolve("m2"); + tb.writeJavaFiles(src_m2, + "module m2 { }", + "package p2; class C2 { p1.C1 c1; }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + testMissingSourcePart(src, classes, "=m2"); + testMissingSourcePart(src, classes, "/=m2"); + testMissingSourcePart(src, classes, "m1/=m2"); + testMissingSourcePart(src, classes, "/p1=m2"); + testMissingSourcePart(src, classes, "m1p1=m2"); + } + + private void testMissingSourcePart(Path src, Path classes, String option) throws Exception { + String log = new JavacTask(tb, Task.Mode.CMDLINE) + .options("--module-source-path", src.toString(), + "--add-exports", option) + .outdir(classes) + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "javac: bad value for --add-exports option: '" + option + "'"); + } + + @Test + public void testBadSourceParts(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { exports p1; }", + "package p1; public class C1 { }"); + Path src_m2 = src.resolve("m2"); + tb.writeJavaFiles(src_m2, + "module m2 { }", + "package p2; class C2 { p1.C1 c1; }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + testBadSourcePart(src, classes, "m!/p1=m2", "m!"); + testBadSourcePart(src, classes, "m1/p!=m2", "p!"); + } + + private void testBadSourcePart(Path src, Path classes, String option, String badName) + throws Exception { + String log = new JavacTask(tb, Task.Mode.CMDLINE) + .options("-XDrawDiagnostics", + "--module-source-path", src.toString(), + "--add-exports", option) + .outdir(classes) + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "- compiler.warn.bad.name.for.option: --add-exports, " + badName); + } + + @Test + public void testBadTarget(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { exports p1; }", + "package p1; public class C1 { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + String log = new JavacTask(tb, Task.Mode.CMDLINE) + .options("-XDrawDiagnostics", + "--module-source-path", src.toString(), + "--add-exports", "m1/p1=m!") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "- compiler.warn.bad.name.for.option: --add-exports, m!"); + } + + @Test + public void testSourceNotFound(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + String log = new JavacTask(tb, Task.Mode.CMDLINE) + .options("-XDrawDiagnostics", + "--module-source-path", src.toString(), + "--add-exports", "DoesNotExist/p=m1") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "- compiler.warn.module.for.option.not.found: --add-exports, DoesNotExist"); + } + + @Test + public void testTargetNotFound(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { }", + "package p1; class C1 { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + String log = new JavacTask(tb, Task.Mode.CMDLINE) + .options("-XDrawDiagnostics", + "--module-source-path", src.toString(), + "--add-exports", "m1/p1=DoesNotExist") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "- compiler.warn.module.for.option.not.found: --add-exports, DoesNotExist"); + } + + @Test + public void testDuplicate(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { }", + "package p1; public class C1 { }"); + Path src_m2 = src.resolve("m2"); + tb.writeJavaFiles(src_m2, + "module m2 { }", + "package p2; class C2 { p1.C1 c1; }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + new JavacTask(tb) + .options("--module-source-path", src.toString(), + "--add-exports", "m1/p1=m2,m2") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll(); + } + + @Test + public void testRepeated_SameTarget(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { }", + "package p1; public class C1 { }"); + Path src_m2 = src.resolve("m2"); + tb.writeJavaFiles(src_m2, + "module m2 { }", + "package p2; class C2 { p1.C1 c1; }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + new JavacTask(tb) + .options("--module-source-path", src.toString(), + "--add-exports", "m1/p1=m2", + "--add-exports", "m1/p1=m2") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll(); + } + + @Test + public void testRepeated_DifferentTarget(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { }", + "package p1; public class C1 { }"); + Path src_m2 = src.resolve("m2"); + tb.writeJavaFiles(src_m2, + "module m2 { }", + "package p2; class C2 { p1.C1 c1; }"); + Path src_m3 = src.resolve("m3"); + tb.writeJavaFiles(src_m3, + "module m3 { }", + "package p3; class C3 { p1.C1 c1; }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + new JavacTask(tb) + .options("--module-source-path", src.toString(), + "--add-exports", "m1/p1=m2", + "--add-exports", "m1/p1=m3") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll(); + } +} diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/modules/AddLimitMods.java diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/modules/AddModulesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/modules/AddModulesTest.java Fri Nov 04 17:52:11 2016 +0000 @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2015, 2016, 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 + * @summary Test the --add-modules option + * @library /tools/lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase + * @run main AddModulesTest + */ + + +import java.nio.file.Path; + +import toolbox.JavacTask; +import toolbox.Task; +import toolbox.ToolBox; + +public class AddModulesTest extends ModuleTestBase { + public static void main(String... args) throws Exception { + new AddModulesTest().runTests(); + } + + @Test + public void testEmpty(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "class Dummy { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + testEmpty(src, classes, "--add-modules", ""); + testEmpty(src, classes, "--add-modules="); + } + + private void testEmpty(Path src, Path classes, String... options) throws Exception { + String log = new JavacTask(tb, Task.Mode.CMDLINE) + .options(options) + .outdir(classes) + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "javac: no value for --add-modules option"); + } + + @Test + public void testEmptyItem(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { }"); + Path src_m2 = src.resolve("m2"); + tb.writeJavaFiles(src_m2, + "module m2 { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + testEmptyItem(src, classes, ",m1"); + testEmptyItem(src, classes, "m1,,m2"); + testEmptyItem(src, classes, "m1,"); + } + + private void testEmptyItem(Path src, Path classes, String option) throws Exception { + new JavacTask(tb) + .options("--module-source-path", src.toString(), + "--add-modules", option) + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll(); + } + + @Test + public void testEmptyList(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "class Dummy { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + String log = new JavacTask(tb, Task.Mode.CMDLINE) + .options("--module-source-path", src.toString(), + "--add-modules", ",") + .outdir(classes) + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "javac: bad value for --add-modules option"); + } + + @Test + public void testInvalidName(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "class Dummy { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + String log = new JavacTask(tb) + .options("-XDrawDiagnostics", + "--add-modules", "BadModule!") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "- compiler.warn.bad.name.for.option: --add-modules, BadModule!"); + } + + @Test + public void testUnknownName(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "class Dummy { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + String log = new JavacTask(tb) + .options("-XDrawDiagnostics", + "--add-modules", "DoesNotExist") + .outdir(classes) + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "- compiler.err.module.not.found: DoesNotExist"); + } + + @Test + public void testDuplicate(Path base) throws Exception { + Path src = base.resolve("src"); + + // setup a utility module + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { exports p1; }", + "package p1; public class C1 { }"); + Path modules = base.resolve("modules"); + tb.createDirectories(modules); + + new JavacTask(tb) + .options("--module-source-path", src.toString()) + .outdir(modules) + .files(findJavaFiles(src)) + .run() + .writeAll(); + + // now test access to the module + Path src2 = base.resolve("src2"); + tb.writeJavaFiles(src2, + "class Dummy { p1.C1 c1; }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + new JavacTask(tb) + .options("--module-path", modules.toString(), + "--add-modules", "m1,m1") + .outdir(classes) + .files(findJavaFiles(src2)) + .run() + .writeAll(); + } + + @Test + public void testRepeatable(Path base) throws Exception { + Path src = base.resolve("src"); + + // setup some utility modules + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { exports p1; }", + "package p1; public class C1 { }"); + Path src_m2 = src.resolve("m2"); + tb.writeJavaFiles(src_m2, + "module m2 { exports p2; }", + "package p2; public class C2 { }"); + Path modules = base.resolve("modules"); + tb.createDirectories(modules); + + new JavacTask(tb) + .options("--module-source-path", src.toString()) + .outdir(modules) + .files(findJavaFiles(src)) + .run() + .writeAll(); + + // now test access to the modules + Path src2 = base.resolve("src2"); + tb.writeJavaFiles(src2, + "class Dummy { p1.C1 c1; p2.C2 c2; }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + new JavacTask(tb) + .options("--module-path", modules.toString(), + "--add-modules", "m1", + "--add-modules", "m2") + .outdir(classes) + .files(findJavaFiles(src2)) + .run() + .writeAll(); + } +} + diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/modules/AddReadsTest.java --- a/langtools/test/tools/javac/modules/AddReadsTest.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/test/tools/javac/modules/AddReadsTest.java Fri Nov 04 17:52:11 2016 +0000 @@ -28,6 +28,7 @@ * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.jdeps/com.sun.tools.javap + * java.desktop * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask toolbox.JavapTask ModuleTestBase * @run main AddReadsTest */ @@ -49,7 +50,6 @@ import toolbox.JavacTask; import toolbox.JavapTask; import toolbox.Task; -import toolbox.ToolBox; public class AddReadsTest extends ModuleTestBase { @@ -80,8 +80,8 @@ .writeAll() .getOutput(Task.OutputKind.DIRECT); - if (!log.contains("Test.java:1:44: compiler.err.not.def.access.package.cant.access: api.Api, api")) - throw new Exception("expected output not found"); + checkOutputContains(log, + "Test.java:1:44: compiler.err.not.def.access.package.cant.access: api.Api, api"); //test add dependencies: new JavacTask(tb) @@ -104,7 +104,8 @@ //cyclic dependencies OK when created through addReads: new JavacTask(tb) - .options("--add-reads", "m2=m1,m1=m2", + .options("--add-reads", "m2=m1", + "--add-reads", "m1=m2", "--module-source-path", src.toString()) .outdir(classes) .files(findJavaFiles(src)) @@ -233,7 +234,8 @@ "package impl; public class Impl { javax.swing.JButton b; }"); new JavacTask(tb) - .options("--add-reads", "java.base=java.desktop", + .options("--add-modules", "java.desktop", + "--add-reads", "java.base=java.desktop", "-Xmodule:java.base") .outdir(classes) .files(findJavaFiles(src)) @@ -308,4 +310,356 @@ .run() .writeAll(); } + + @Test + public void testAddSelf(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { exports p1; }", + "package p1; public class C1 { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + new JavacTask(tb) + .options("--module-source-path", src.toString(), + "--add-reads", "m1=m1") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll(); + } + + @Test + public void testEmpty(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "class Dummy { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + testEmpty(src, classes, "--add-reads", ""); + testEmpty(src, classes, "--add-reads="); + } + + private void testEmpty(Path src, Path classes, String... options) throws Exception { + String log = new JavacTask(tb, Task.Mode.CMDLINE) + .options(options) + .outdir(classes) + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "javac: no value for --add-reads option"); + } + + @Test + public void testEmptyItem(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { exports p1; }", + "package p1; public class C1 { }"); + Path src_m2 = src.resolve("m2"); + tb.writeJavaFiles(src_m2, + "module m2 { }", + "package p2; class C2 { }"); + Path src_m3 = src.resolve("m3"); + tb.writeJavaFiles(src_m3, + "module m3 { }", + "package p3; class C3 { p1.C1 c1; }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + testEmptyItem(src, classes, "m3=,m1"); + testEmptyItem(src, classes, "m3=m1,,m2"); + testEmptyItem(src, classes, "m3=m1,"); + } + + private void testEmptyItem(Path src, Path classes, String option) throws Exception { + new JavacTask(tb) + .options("--module-source-path", src.toString(), + "--add-reads", option) + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll(); + } + + @Test + public void testEmptyList(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { exports p1; }", + "package p1; public class C1 { }"); + Path src_m2 = src.resolve("m2"); + tb.writeJavaFiles(src_m2, + "module m2 { }", + "package p2; class C2 { }"); + Path src_m3 = src.resolve("m3"); + tb.writeJavaFiles(src_m3, + "module m3 { }", + "package p3; class C3 { p1.C1 c1; }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + testEmptyList(src, classes, "m3="); + testEmptyList(src, classes, "m3=,"); + } + + private void testEmptyList(Path src, Path classes, String option) throws Exception { + String log = new JavacTask(tb, Task.Mode.CMDLINE) + .options("--module-source-path", src.toString(), + "--add-reads", option) + .outdir(classes) + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "javac: bad value for --add-reads option: '" + option + "'"); + } + + @Test + public void testMultipleAddReads_DifferentModules(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { exports p1; }", + "package p1; public class C1 { }"); + Path src_m2 = src.resolve("m2"); + tb.writeJavaFiles(src_m2, + "module m2 { }", + "package p2; class C2 { p1.C1 c1; }"); + Path src_m3 = src.resolve("m3"); + tb.writeJavaFiles(src_m3, + "module m3 { }", + "package p3; class C3 { p1.C1 c1; }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + new JavacTask(tb) + .options("--module-source-path", src.toString(), + "--add-reads", "m2=m1", + "--add-reads", "m3=m1") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll(); + } + + @Test + public void testMultipleAddReads_SameModule(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { exports p1; }", + "package p1; public class C1 { }"); + Path src_m2 = src.resolve("m2"); + tb.writeJavaFiles(src_m2, + "module m2 { exports p2; }", + "package p2; public class C2 { }"); + Path src_m3 = src.resolve("m3"); + tb.writeJavaFiles(src_m3, + "module m3 { }", + "package p3; class C3 { p1.C1 c1; p2.C2 c2; }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + new JavacTask(tb) + .options("--module-source-path", src.toString(), + "--add-reads", "m3=m1", + "--add-reads", "m3=m2") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll(); + } + + @Test + public void testDuplicateAddReads_SameOption(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { exports p1; }", + "package p1; public class C1 { }"); + Path src_m2 = src.resolve("m2"); + tb.writeJavaFiles(src_m2, + "module m2 { exports p2; }", + "package p2; class C2 { p1.C1 c1; }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + new JavacTask(tb) + .options("--module-source-path", src.toString(), + "--add-reads", "m2=m1,m1") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll(); + } + + @Test + public void testDuplicateAddReads_MultipleOptions(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { exports p1; }", + "package p1; public class C1 { }"); + Path src_m2 = src.resolve("m2"); + tb.writeJavaFiles(src_m2, + "module m2 { }", + "package p2; class C2 { p1.C1 c1; }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + new JavacTask(tb) + .options("--module-source-path", src.toString(), + "--add-reads", "m2=m1", + "--add-reads", "m2=m1") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll(); + } + + @Test + public void testRepeatedAddReads(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { exports p1; }", + "package p1; public class C1 { }"); + Path src_m2 = src.resolve("m2"); + tb.writeJavaFiles(src_m2, + "module m2 { exports p2; }", + "package p2; public class C2 { }"); + Path src_m3 = src.resolve("m3"); + tb.writeJavaFiles(src_m3, + "module m3 { }", + "package p3; class C3 { p1.C1 c1; p2.C2 c2; }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + new JavacTask(tb) + .options("--module-source-path", src.toString(), + "--add-reads", "m3=m1", + "--add-reads", "m3=m2") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll(); + } + + @Test + public void testNoEquals(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "class Dummy { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + String log = new JavacTask(tb, Task.Mode.CMDLINE) + .options("-XDrawDiagnostics", + "--add-reads", "m1:m2") + .outdir(classes) + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "javac: bad value for --add-reads option: 'm1:m2'"); + } + + @Test + public void testBadSourceName(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "class Dummy { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + String log = new JavacTask(tb) + .options("-XDrawDiagnostics", + "--add-reads", "bad*Source=m2") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "- compiler.warn.bad.name.for.option: --add-reads, bad*Source"); + } + + @Test + public void testBadTargetName(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { }", + "package p1; class C1 { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + String log = new JavacTask(tb) + .options("-XDrawDiagnostics", + "--add-reads", "m1=badTarget!") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "- compiler.warn.bad.name.for.option: --add-reads, badTarget!"); + } + + @Test + public void testSourceNameNotFound(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { exports p1; }", + "package p1; public class C1 { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + String log = new JavacTask(tb) + .options("-XDrawDiagnostics", + "--add-reads", "missingSource=m1") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "- compiler.warn.module.for.option.not.found: --add-reads, missingSource"); + } + + @Test + public void testTargetNameNotFound(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { exports p1; }", + "package p1; public class C1 { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + String log = new JavacTask(tb) + .options("-XDrawDiagnostics", + "--add-reads", "m1=missingTarget") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutputContains(log, + "- compiler.warn.module.for.option.not.found: --add-reads, missingTarget"); + } } diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/modules/AnnotationProcessorsInModulesTest.java --- a/langtools/test/tools/javac/modules/AnnotationProcessorsInModulesTest.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/test/tools/javac/modules/AnnotationProcessorsInModulesTest.java Fri Nov 04 17:52:11 2016 +0000 @@ -230,8 +230,7 @@ .run(Task.Expect.FAIL) .writeAll() .getOutputLines(Task.OutputKind.DIRECT); - if (!log.equals(Arrays.asList("- compiler.err.processorpath.no.processormodulepath", - "1 error"))) { + if (!log.equals(Arrays.asList("- compiler.err.processorpath.no.processormodulepath"))) { throw new AssertionError("Unexpected output: " + log); } } diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/modules/AutomaticModules.java diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/modules/EdgeCases.java --- a/langtools/test/tools/javac/modules/EdgeCases.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/test/tools/javac/modules/EdgeCases.java Fri Nov 04 17:52:11 2016 +0000 @@ -71,21 +71,22 @@ @Test public void testAddExportUndefinedModule(Path base) throws Exception { Path src = base.resolve("src"); - tb.writeJavaFiles(src, "package test; import undef.Any; public class Test {}"); + tb.writeJavaFiles(src, "package test; import undefPackage.Any; public class Test {}"); Path classes = base.resolve("classes"); tb.createDirectories(classes); List log = new JavacTask(tb) - .options("--add-exports", "undef/undef=ALL-UNNAMED", "-XDrawDiagnostics") + .options("--add-exports", "undefModule/undefPackage=ALL-UNNAMED", + "-XDrawDiagnostics") .outdir(classes) .files(findJavaFiles(src)) .run(Task.Expect.FAIL) .writeAll() .getOutputLines(Task.OutputKind.DIRECT); - List expected = Arrays.asList("- compiler.err.cant.find.module: undef", - "Test.java:1:27: compiler.err.doesnt.exist: undef", - "2 errors"); + List expected = Arrays.asList("- compiler.warn.module.for.option.not.found: --add-exports, undefModule", + "Test.java:1:34: compiler.err.doesnt.exist: undefPackage", + "1 error", "1 warning"); if (!expected.equals(log)) throw new Exception("expected output not found: " + log); diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/modules/GraphsTest.java diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/modules/LimitModulesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/modules/LimitModulesTest.java Fri Nov 04 17:52:11 2016 +0000 @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2015, 2016, 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 + * @summary Test the --limit-modules option + * @library /tools/lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase + * @run main LimitModulesTest + */ + + +import java.nio.file.Path; + +import toolbox.JavacTask; +import toolbox.Task; +import toolbox.ToolBox; + +public class LimitModulesTest extends ModuleTestBase { + public static void main(String... args) throws Exception { + new LimitModulesTest().runTests(); + } + + @Test + public void testEmpty(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "class Dummy { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + String log = new JavacTask(tb, Task.Mode.CMDLINE) + .options("--module-source-path", src.toString(), + "--limit-modules", "") + .outdir(classes) + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + if (!log.contains("javac: no value for --limit-modules option")) + throw new Exception("expected output not found"); + + log = new JavacTask(tb, Task.Mode.CMDLINE) + .options("--module-source-path", src.toString(), + "--limit-modules=") + .outdir(classes) + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + if (!log.contains("javac: no value for --limit-modules option")) + throw new Exception("expected output not found"); + } + + @Test + public void testEmptyItem(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + "module m1 { }"); + Path src_m2 = src.resolve("m2"); + tb.writeJavaFiles(src_m2, + "module m2 { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + new JavacTask(tb) + .options("--module-source-path", src.toString(), + "--limit-modules", ",m1") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll(); + + new JavacTask(tb) + .options("--module-source-path", src.toString(), + "--limit-modules", "m1,,m2") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll(); + + new JavacTask(tb) + .options("--module-source-path", src.toString(), + "--limit-modules", "m1,") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll(); + } + + @Test + public void testEmptyList(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "class Dummy { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + String log = new JavacTask(tb, Task.Mode.CMDLINE) + .options("--module-source-path", src.toString(), + "--limit-modules", ",") + .outdir(classes) + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + if (!log.contains("javac: bad value for --limit-modules option")) + throw new Exception("expected output not found"); + } + + @Test + public void testInvalidName(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "class Dummy { }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + String log = new JavacTask(tb) + .options("-XDrawDiagnostics", + "--limit-modules", "BadModule!") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + if (!log.contains("- compiler.warn.bad.name.for.option: --limit-modules, BadModule!")) + throw new Exception("expected output not found"); + } + + @Test + public void testLastOneWins(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, + "package p; class C { com.sun.tools.javac.Main main; }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + System.err.println("case 1:"); + new JavacTask(tb) + .options("-XDrawDiagnostics", + "--limit-modules", "java.base", + "--limit-modules", "jdk.compiler") + .outdir(classes) + .files(findJavaFiles(src)) + .run() + .writeAll(); + + System.err.println("case 2:"); + String log = new JavacTask(tb) + .options("-XDrawDiagnostics", + "--limit-modules", "jdk.compiler", + "--limit-modules", "java.base") + .outdir(classes) + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + if (!log.contains("C.java:1:41: compiler.err.doesnt.exist: com.sun.tools.javac")) + throw new Exception("expected output not found"); + } +} + diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/modules/ModuleTestBase.java --- a/langtools/test/tools/javac/modules/ModuleTestBase.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/test/tools/javac/modules/ModuleTestBase.java Fri Nov 04 17:52:11 2016 +0000 @@ -53,4 +53,12 @@ Path[] findJavaFiles(Path... paths) throws IOException { return tb.findJavaFiles(paths); } + + void checkOutputContains(String log, String... expect) throws Exception { + for (String e : expect) { + if (!log.contains(e)) { + throw new Exception("expected output not found: " + e); + } + } + } } diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/modules/PackageMultipleModules.java diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/modules/RequiresPublicTest.java diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/modules/ResolveTest.java diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/modules/UsesTest.java diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/modules/XModuleTest.java --- a/langtools/test/tools/javac/modules/XModuleTest.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/test/tools/javac/modules/XModuleTest.java Fri Nov 04 17:52:11 2016 +0000 @@ -223,8 +223,7 @@ .writeAll() .getOutputLines(Task.OutputKind.DIRECT); - List expected = Arrays.asList("- compiler.err.xmodule.no.module.sourcepath", - "1 error"); + List expected = Arrays.asList("- compiler.err.xmodule.no.module.sourcepath"); if (!expected.equals(log)) throw new Exception("expected output not found: " + log); diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/processing/model/nestedTypeVars/NestedTypeVars.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/model/nestedTypeVars/NestedTypeVars.java Fri Nov 04 17:52:11 2016 +0000 @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2016, 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 + * @modules jdk.compiler + * @build NestedTypeVars + * @compile/process/ref=NestedTypeVars.out -processor NestedTypeVars Test$1L1$L2$1L3$L4$L5 Test$1L1$CCheck Test$1L1 Test$1CCheck Test$CCheck Test + */ + +import java.util.Set; +import java.util.stream.Collectors; + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.TypeParameterElement; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.type.TypeVariable; +import javax.lang.model.util.ElementFilter; + +@SupportedAnnotationTypes("*") +public class NestedTypeVars extends AbstractProcessor{ + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + for (TypeElement te : ElementFilter.typesIn(roundEnv.getRootElements())) { + System.out.print(processingEnv.getElementUtils().getBinaryName(te)); + System.out.print("<"); + String separator = ""; + for (TypeParameterElement tp : te.getTypeParameters()) { + System.out.print(separator); + separator = ", "; + System.out.print(tp.getSimpleName()); + System.out.print(" extends "); + System.out.print(tp.getBounds().stream().map(b -> toString(b)).collect(Collectors.joining("&"))); + } + System.out.println(">"); + for (ExecutableElement m : ElementFilter.methodsIn(te.getEnclosedElements())) { + System.out.print(" <"); + separator = ""; + for (TypeParameterElement tp : m.getTypeParameters()) { + System.out.print(separator); + separator = ", "; + System.out.print(tp.getSimpleName()); + System.out.print(" extends "); + System.out.print(tp.getBounds(). + stream(). + map(b -> toString(b)). + collect(Collectors.joining("&"))); + } + System.out.print(">"); + System.out.println(m.getSimpleName()); + } + } + + return false; + } + + String toString(TypeMirror bound) { + if (bound.getKind() == TypeKind.TYPEVAR) { + TypeVariable var = (TypeVariable) bound; + return toString(var.asElement()); + } + return bound.toString(); + } + + String toString(Element el) { + switch (el.getKind()) { + case METHOD: + return toString(el.getEnclosingElement()) + "." + el.getSimpleName(); + case CLASS: + return processingEnv.getElementUtils().getBinaryName((TypeElement) el).toString(); + case TYPE_PARAMETER: + return toString(((TypeParameterElement) el).getGenericElement()) + "." + el.getSimpleName(); + default: + throw new IllegalStateException("Unexpected element: " + el + "(" + el.getKind() + ")"); + } + } + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latestSupported(); + } + + +} + +class Test { + void m() { + class L1 { + class L2 { + void m() { + class L3 { + class L4 { + class L5 {} + } + } + } + } + class CCheck {} + void test() {} + } + class CCheck {} + } + class CCheck {} + void test() {} +} diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/javac/processing/model/nestedTypeVars/NestedTypeVars.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/model/nestedTypeVars/NestedTypeVars.out Fri Nov 04 17:52:11 2016 +0000 @@ -0,0 +1,9 @@ +Test$1L1$L2$1L3$L4$L5 +Test$1L1$CCheck +Test$1L1 + test +Test$1CCheck +Test$CCheck +Test + m + test diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestLoad.java --- a/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestLoad.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestLoad.java Fri Nov 04 17:52:11 2016 +0000 @@ -23,6 +23,7 @@ /* * @test + * @bug 8145464 8164837 * @summary Test of jdeprscan tool loading and printing to aCSV file. * @modules jdk.jdeps/com.sun.tools.jdeprscan * @library ../../../cases diff -r 394bc7b2237f -r 4e7ef9667ea6 langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestScan.java --- a/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestScan.java Fri Nov 04 17:24:26 2016 +0000 +++ b/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestScan.java Fri Nov 04 17:52:11 2016 +0000 @@ -23,6 +23,7 @@ /* * @test + * @bug 8145464 8164837 8165646 * @summary Basic test of jdeprscan's scanning phase. * @modules jdk.jdeps/com.sun.tools.jdeprscan * @library ../../../cases