Hi All, Currently, GenModuleInfoSource.java does not allow you to merge extra module-info files into the primary module-info file (for a given module) at build time.
Put simply; I think it should have this functionality. Can committers please review and opine? You can already see this code change in action while compiling OpenJDK with OpenJ9, so we know it works. I've included the "diff -u" output for the proposed code change in this email's P.S. Best Regards Adam Farley P.S. Code diff: --- original_GenModuleInfoSource.java 2017-12-06 15:46:43.000000000 +0000 +++ improved_GenModuleInfoSource.java 2017-12-06 15:49:04.000000000 +0000 @@ -1,4 +1,10 @@ /* + * =========================================================================== + * (c) Copyright IBM Corp. 2015, 2017 All Rights Reserved + * =========================================================================== + */ + +/* * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -156,12 +162,12 @@ } // requires - for (String l : lines) { - if (l.trim().startsWith("requires")) - writer.println(l); - } + //for (String l : lines) { + // if (l.trim().startsWith("requires")) + // writer.println(l); + //} - // write exports, opens, uses, and provides + // write requires, exports, opens, uses, and provides moduleInfo.print(writer); // close @@ -171,12 +177,13 @@ class ModuleInfo { + final Map<String, Statement> requires = new HashMap<>(); final Map<String, Statement> exports = new HashMap<>(); final Map<String, Statement> opens = new HashMap<>(); final Map<String, Statement> uses = new HashMap<>(); final Map<String, Statement> provides = new HashMap<>(); - Statement getStatement(String directive, String name) { + Statement getStatement(String directive, String qualifier, String name) { switch (directive) { case "exports": if (moduleInfo.exports.containsKey(name) && @@ -205,6 +212,10 @@ return uses.computeIfAbsent(name, _n -> new Statement("uses", "", name)); + case "requires": + return uses.computeIfAbsent(name, + _n -> new Statement("requires", qualifier, name)); + case "provides": return provides.computeIfAbsent(name, _n -> new Statement("provides", "with", name, true)); @@ -233,7 +244,7 @@ .stream() .filter(e -> !exports.containsKey(e.getKey()) && e.getValue().filter(modules)) - .forEach(e -> addTargets(getStatement("exports", e.getKey()), + .forEach(e -> addTargets(getStatement("exports", null, e.getKey()), e.getValue(), modules)); @@ -251,7 +262,7 @@ .stream() .filter(e -> !opens.containsKey(e.getKey()) && e.getValue().filter(modules)) - .forEach(e -> addTargets(getStatement("opens", e.getKey()), + .forEach(e -> addTargets(getStatement("opens", null, e.getKey()), e.getValue(), modules)); @@ -272,6 +283,12 @@ .stream() .filter(service -> !uses.containsKey(service)) .forEach(service -> uses.put(service, extraFiles.uses.get(service))); + + // requires + extraFiles.requires.keySet() + .stream() + .filter(require -> !requires.containsKey(require)) + .forEach(require -> requires.put(require, extraFiles.requires.get(require))); } // add qualified exports or opens to known modules only @@ -324,6 +341,11 @@ void print(PrintWriter writer) { + // requires + requires.entrySet().stream() + .sorted(Map.Entry.comparingByKey()) + .forEach(e -> writer.println(e.getValue())); + // print unqualified exports exports.entrySet().stream() .filter(e -> e.getValue().targets.isEmpty()) @@ -418,27 +440,45 @@ String keyword = s[0].trim(); String name = s.length > 1 ? s[1].trim() : null; + String requiresModifiedName1 = s.length > 2 ? s[2].trim() : null; + String requiresModifiedName2 = s.length > 3 ? s[3].trim() : null; trace("%d: %s index=%d len=%d%n", lineNumber, l, index, l.length()); switch (keyword) { case "module": - case "requires": case "}": index = l.length(); // skip to the end continue; + case "requires": case "exports": case "opens": case "provides": case "uses": + String requiresQualifier = null; // assume name immediately after exports, opens, provides, uses - statement = getStatement(keyword, name); + if (keyword.equals("requires")) { + if (requiresModifiedName2 != null) { // 2 modifiers specified + if ((name.equals("transitive") || name.equals("static")) && + (requiresModifiedName1.equals("transitive") || requiresModifiedName1.equals("static"))) { + requiresQualifier = "static transitive"; + name = requiresModifiedName2; + } + } else if (requiresModifiedName1 != null) { // 1 modifier specified + if (name.equals("transitive") || name.equals("static")) { + requiresQualifier = name; + name = requiresModifiedName1; + } + } + } + + statement = getStatement(keyword, requiresQualifier, name); hasTargets = false; int i = l.indexOf(name, keyword.length()+1) + name.length() + 1; l = i < l.length() ? l.substring(i, l.length()).trim() : ""; index = 0; - if (s.length >= 3) { + if (!keyword.equals("requires") && s.length >= 3) { if (!s[2].trim().equals(statement.qualifier)) { throw new RuntimeException(sourcefile + ", line " + lineNumber + ", is malformed: " + s[2]); @@ -594,17 +634,25 @@ @Override public String toString() { StringBuilder sb = new StringBuilder(" "); - sb.append(directive).append(" ").append(name); - if (targets.isEmpty()) { - sb.append(";"); - } else if (targets.size() == 1) { - sb.append(" ").append(qualifier) - .append(orderedTargets().collect(joining(",", " ", ";"))); + if (directive.equals("requires")) { + if (qualifier != null) { + sb.append(directive).append(" ").append(qualifier).append(" ").append(name).append(";"); + } else { + sb.append(directive).append(" ").append(name).append(";"); + } } else { - sb.append(" ").append(qualifier) - .append(orderedTargets() - .map(target -> String.format(" %s", target)) - .collect(joining(",\n", "\n", ";"))); + sb.append(directive).append(" ").append(name); + if (targets.isEmpty()) { + sb.append(";"); + } else if (targets.size() == 1) { + sb.append(" ").append(qualifier) + .append(orderedTargets().collect(joining(",", " ", ";"))); + } else { + sb.append(" ").append(qualifier) + .append(orderedTargets() + .map(target -> String.format(" %s", target)) + .collect(joining(",\n", "\n", ";"))); + } } return sb.toString(); } @@ -620,4 +668,4 @@ System.out.format(fmt, params); } } -} +} \ No newline at end of file Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU