<property name="default.javac.source" value="9"/>
<property name="default.javac.target" value="9"/>
</target>
- <target depends="-pre-init,-init-private,-init-user" name="-init-project">
+ <target depends="-pre-init,-init-private,-init-user" name="-init-pre-project">
<property file="nbproject/configs/${config}.properties"/>
<property file="nbproject/project.properties"/>
+ <property name="netbeans.modular.tasks.version" value="1"/>
+ <property location="${build.dir}/tasks/${netbeans.modular.tasks.version}" name="netbeans.modular.tasks.dir"/>
+ </target>
+ <target depends="-init-pre-project" name="-check-netbeans-tasks">
+ <condition property="netbeans.tasks.compiled">
+ <available file="${netbeans.modular.tasks.dir}/out/netbeans/ModuleInfoSelector.class"/>
+ </condition>
+ </target>
+ <target depends="-init-pre-project,-check-netbeans-tasks" name="-init-compile-netbeans-tasks" unless="netbeans.tasks.compiled">
+ <echo file="${netbeans.modular.tasks.dir}/src/netbeans/CoalesceKeyvalue.java">
+
+package netbeans;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+public class CoalesceKeyvalue extends Task {
+ private String property;
+
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+ private String value;
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ private String valueSep;
+
+ public void setValueSep(String valueSep) {
+ this.valueSep = valueSep;
+ }
+
+ private String entrySep;
+
+ public void setEntrySep(String entrySep) {
+ this.entrySep = entrySep;
+ }
+
+ private String multiSep;
+
+ public void setMultiSep(String multiSep) {
+ this.multiSep = multiSep;
+ }
+
+ private String outSep;
+
+ public void setOutSep(String outSep) {
+ this.outSep = outSep;
+ }
+
+ @Override
+ public void execute() throws BuildException {
+ List<String> result = new ArrayList<>();
+ Map<String, List<String>> module2Paths = new HashMap<>();
+
+ for (String entry : value.split(Pattern.quote(entrySep))) {
+ String[] keyValue = entry.split(Pattern.quote(valueSep), 2);
+ if (keyValue.length == 1) {
+ result.add(keyValue[0]);
+ } else {
+ module2Paths.computeIfAbsent(keyValue[0], s -> new ArrayList<>())
+ .add(keyValue[1].trim());
+ }
+ }
+ module2Paths.entrySet()
+ .stream()
+ .forEach(e -> result.add(e.getKey() + valueSep + e.getValue().stream().collect(Collectors.joining(multiSep))));
+ getProject().setProperty(property, result.stream().collect(Collectors.joining(" " + entrySep)));
+ }
+
+}
+
+ </echo>
+ <echo file="${netbeans.modular.tasks.dir}/src/netbeans/ModsourceRegexp.java">
+
+package netbeans;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+public class ModsourceRegexp extends Task {
+ private String property;
+
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+ private String filePattern;
+
+ public void setFilePattern(String filePattern) {
+ this.filePattern = filePattern;
+ }
+
+ private String modsource;
+
+ public void setModsource(String modsource) {
+ this.modsource = modsource;
+ }
+
+ private List<String> expandGroup(String grp) {
+ List<String> exp = new ArrayList<>();
+ String item = "";
+ int depth = 0;
+
+ for (int i = 0; i < grp.length(); i++) {
+ char c = grp.charAt(i);
+ switch (c) {
+ case '{':
+ if (depth++ == 0) {
+ continue;
+ }
+ break;
+ case '}':
+ if (--depth == 0) {
+ exp.add(item);
+ continue;
+ }
+ break;
+ case ',':
+ if (depth == 1) {
+ exp.add(item);
+ item = "";
+ continue;
+ }
+ default:
+ break;
+ }
+ item = item + c;
+ }
+ return exp;
+ }
+
+ private List<String> pathVariants(String spec) {
+ return pathVariants(spec, new ArrayList<>());
+ }
+
+ private List<String> pathVariants(String spec, List<String> res) {
+ int start = spec.indexOf('{');
+ if (start == -1) {
+ res.add(spec);
+ return res;
+ }
+ int depth = 1;
+ int end;
+ for (end = start + 1; end < spec.length() && depth > 0; end++) {
+ char c = spec.charAt(end);
+ switch (c) {
+ case '{': depth++; break;
+ case '}': depth--; break;
+ }
+ }
+ String prefix = spec.substring(0, start);
+ String suffix = spec.substring(end);
+ expandGroup(spec.substring(start, end)).stream().forEach(item -> {
+ pathVariants(prefix + item + suffix, res);
+ });
+ return res;
+ }
+
+ private String toRegexp2(String spec, String filepattern, String separator) {
+ List<String> prefixes = new ArrayList<>();
+ List<String> suffixes = new ArrayList<>();
+ pathVariants(spec).forEach(item -> {
+ suffixes.add(item);
+ });
+ String tail = "";
+ String separatorString = separator;
+ if ("\\".equals(separatorString)) {
+ separatorString = "\\\\";
+ }
+ if (filepattern != null && !Objects.equals(filepattern, tail)) {
+ tail = separatorString + filepattern;
+ }
+ return "([^" + separatorString +"]+)\\Q" + separator + "\\E(" + suffixes.stream().collect(Collectors.joining("|")) + ")" + tail;
+ }
+
+ @Override
+ public void execute() throws BuildException {
+ getProject().setProperty(property, toRegexp2(modsource, filePattern, getProject().getProperty("file.separator")));
+ }
+
+}
+
+ </echo>
+ <echo file="${netbeans.modular.tasks.dir}/src/netbeans/ModuleInfoSelector.java">
+
+package netbeans;
+
+import java.io.File;
+import java.util.Arrays;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.selectors.BaseExtendSelector;
+
+public class ModuleInfoSelector extends BaseExtendSelector {
+
+ @Override
+ public boolean isSelected(File basedir, String filename, File file) throws BuildException {
+ String extension = Arrays.stream(getParameters())
+ .filter(p -> "extension".equals(p.getName()))
+ .map(p -> p.getValue())
+ .findAny()
+ .get();
+ return !new File(file, "module-info." + extension).exists();
+ }
+
+}
+
+ </echo>
+ <mkdir dir="${netbeans.modular.tasks.dir}/out"/>
+ <javac classpath="${ant.core.lib}" destdir="${netbeans.modular.tasks.dir}/out" srcdir="${netbeans.modular.tasks.dir}/src"/>
+ </target>
+ <target depends="-init-pre-project,-init-compile-netbeans-tasks" name="-init-project">
+ <taskdef classname="netbeans.CoalesceKeyvalue" classpath="${netbeans.modular.tasks.dir}/out" name="coalesce_keyvalue" uri="http://www.netbeans.org/ns/j2se-modular-project/1"/>
+ <taskdef classname="netbeans.ModsourceRegexp" classpath="${netbeans.modular.tasks.dir}/out" name="modsource_regexp" uri="http://www.netbeans.org/ns/j2se-modular-project/1"/>
</target>
<target name="-init-source-module-properties">
<property name="javac.modulepath" value=""/>
<j2semodularproject1:modsource_regexp xmlns:j2semodularproject1="http://www.netbeans.org/ns/j2se-modular-project/1" modsource="${test.src.dir.path}" property="have.tests.test.src.dir.regexp"/>
<dirset dir="${basedir}/${test.src.dir}" id="have.tests.test.src.dir.patchset" includes="*/*">
<filename regex="${have.tests.test.src.dir.regexp}"/>
- <scriptselector language="javascript">
- self.setSelected(!new java.io.File(file, "module-info.java").exists());
- </scriptselector>
</dirset>
<union id="have.tests.patchset">
<dirset refid="have.tests.test.src.dir.patchset"/>
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
- <scriptdef language="javascript" name="coalesce_keyvalue" uri="http://www.netbeans.org/ns/j2se-modular-project/1">
- <attribute name="property"/>
- <attribute name="value"/>
- <attribute name="value-sep"/>
- <attribute name="entry-sep"/>
- <attribute name="multi-sep"/>
- <attribute name="out-sep"/>
-
-
- function coalesce(input, keyValueSeparator, multiSeparator, entrySeparator) {
- var result = [];
- var values = {};
-
- (typeof input === "string" ? input.split(entrySeparator) : input).forEach(function(entry) {
- var idx = entry.indexOf(keyValueSeparator);
- if (idx < 1) {
- result.push(entry);
- } else {
- var key = entry.substring(0, idx);
- var val = entry.substring(idx + 1);
- if (!values[key]) {
- values[key] = [];
- }
- values[key].push(val.trim());
- }
- });
- Object.keys(values).sort().forEach(function(k) {
- result.push(k + keyValueSeparator + values[k].join(multiSeparator));
- });
- return result.join(" " + entrySeparator);
- }
- self.project.setProperty(attributes.get("property"),
- coalesce(attributes.get("value"),
- attributes.get("value-sep"),
- attributes.get("entry-sep"),
- attributes.get("multi-sep")
- ));
-
-
-
- </scriptdef>
- <scriptdef language="javascript" name="modsource_regexp" uri="http://www.netbeans.org/ns/j2se-modular-project/1">
- <attribute name="property"/>
- <attribute name="filePattern"/>
- <attribute name="modsource"/>
- function expandGroup(grp) {
- var exp = [];
- var item = "";
- var depth = 0;
-
- for (i = 0; i < grp.length; i++) {
- var c = grp[i];
- switch (c) {
- case '{':
- if (depth++ === 0) {
- continue;
- }
- break;
- case '}':
- if (--depth === 0) {
- exp.push(item);
- continue;
- }
- break;
- case ',':
- if (depth === 1) {
- exp.push(item);
- item = "";
- continue;
- }
- default:
- break;
- }
- item = item + c;
- }
- return exp;
- }
-
- function pathVariants(spec, res) {
- res = res || [];
- var start = spec.indexOf('{');
- if (start === -1) {
- res.push(spec);
- return res;
- }
- var depth = 1;
- var end;
- for (end = start + 1; end < spec.length && depth > 0; end++) {
- var c = spec[end];
- switch (c) {
- case '{': depth++; break;
- case '}': depth--; break;
- }
- }
- var prefix = spec.substring(0, start);
- var suffix = spec.substring(end);
- expandGroup(spec.slice(start, end)).forEach(function (item) {
- pathVariants(prefix + item + suffix, res);
- })
- return res;
- }
-
- function toRegexp2(spec, filepattern, separator) {
- var prefixes = [];
- var suffixes = [];
- pathVariants(spec).forEach(function(item) {
- suffixes.push(item);
- });
- var tail = "";
- var separatorString = separator;
- if (separatorString == "\\") {
- separatorString = "\\\\";
- }
- if (filepattern && filepattern != tail) {
- tail = separatorString + filepattern;
- }
- return "([^" + separatorString +"]+)\\Q" + separator + "\\E(" + suffixes.join("|") + ")" + tail;
- }
- self.project.setProperty(attributes.get("property"),
- toRegexp2(attributes.get("modsource"), attributes.get("filepattern"), self.project.getProperty("file.separator")));
-
-
-
-
- </scriptdef>
<target if="do.depend.true" name="-compile-depend">
<pathconvert property="build.generated.subdirs">
<dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
<target depends="-pre-single-jar" if="module.jar.filename" name="-make-single-jar">
<jar basedir="${module.dir}" compress="${jar.compress}" destfile="${dist.dir}/${module.jar.filename}" excludes="${dist.archive.excludes}" manifestencoding="UTF-8"/>
</target>
- <target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive" name="-do-jar-jar" unless="do.mkdist">
+ <target depends="init,compile,-pre-pre-jar,-pre-jar,-main-module-check-condition" if="do.archive" name="-do-jar-jar" unless="do.mkdist">
<property location="${build.modules.dir}" name="build.modules.dir.resolved"/>
<dirset dir="${build.modules.dir.resolved}" id="do.jar.dirs" includes="*"/>
<pathconvert property="do.jar.dir.list" refid="do.jar.dirs">
<param location="${entry}" name="module.dir"/>
</antcall>
</j2semodularproject1:for-paths>
+ <condition property="named.module.internal">
+ <and>
+ <isset property="module.name"/>
+ <length length="0" string="${module.name}" when="greater"/>
+ </and>
+ </condition>
+ <condition property="unnamed.module.internal">
+ <not>
+ <isset property="named.module.internal"/>
+ </not>
+ </condition>
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<property location="${dist.jar}" name="dist.jar.resolved"/>
<pathconvert property="run.classpath.with.dist.jar">
<path path="${run.modulepath}"/>
<map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
</pathconvert>
- <condition else="" property="jar.usage.message.module.path" value=" -modulepath ${run.modulepath.with.dist.jar}">
+ <condition else="" property="jar.usage.message.module.path" value=" --module-path ${run.modulepath.with.dist.jar}">
<and>
<isset property="modules.supported.internal"/>
<length length="0" string="${run.modulepath.with.dist.jar}" when="greater"/>
</condition>
</fail>
</target>
+ <target depends="-main-module-set" if="main.class.available" name="-main-module-check-condition">
+ <fail message="Could not determine module of the main class and module.name is not set">
+ <condition>
+ <or>
+ <not>
+ <isset property="module.name"/>
+ </not>
+ <length length="0" string="${module.name}" when="equal"/>
+ </or>
+ </condition>
+ </fail>
+ </target>
<target name="-do-not-recompile">
<property name="javac.includes.binary" value=""/>
</target>
</pathconvert>
<pathconvert pathsep=" " property="run.test.patchmodules.list">
<dirset dir="${build.test.modules.dir}" includes="*">
- <scriptselector language="javascript">
- self.setSelected(!new java.io.File(file, "module-info.class").exists());
- </scriptselector>
+ <custom classname="netbeans.ModuleInfoSelector" classpath="${netbeans.modular.tasks.dir}/out">
+ <param name="extension" value="class"/>
+ </custom>
</dirset>
<chainedmapper>
<filtermapper>
<regexpmapper from=".*\Q${file.separator}\E([^${file.separator.string}]+)$" to="--patch-module \1=\0"/>
</chainedmapper>
</pathconvert>
- <j2semodularproject1:coalesce_keyvalue xmlns:j2semodularproject1="http://www.netbeans.org/ns/j2se-modular-project/1" entry-sep="${path.separator}" multi-sep="--patch-module " property="run.test.patchmodules" value="${run.test.patchmodules.list}" value-sep="="/>
+ <j2semodularproject1:coalesce_keyvalue xmlns:j2semodularproject1="http://www.netbeans.org/ns/j2se-modular-project/1" entrySep="--patch-module " multiSep="${path.separator}" property="run.test.patchmodules" value="${run.test.patchmodules.list}" valueSep="="/>
<condition else="" property="run.test.addmodules.internal" value="--add-modules ${run.test.addmodules.list}">
<isset property="run.test.addmodules.list"/>
</condition>
</filtermapper>
</chainedmapper>
</pathconvert>
- <j2semodularproject1:coalesce_keyvalue xmlns:j2semodularproject1="http://www.netbeans.org/ns/j2se-modular-project/1" entry-sep="${path.separator}" multi-sep="--patch-module " property="compile.test.patchmodules" value="${compile.test.patchmodule.internal}" value-sep="="/>
+ <j2semodularproject1:coalesce_keyvalue xmlns:j2semodularproject1="http://www.netbeans.org/ns/j2se-modular-project/1" entrySep="--patch-module " multiSep="${path.separator}" property="compile.test.patchmodules" value="${compile.test.patchmodule.internal}" valueSep="="/>
<property name="javac.test.moduleargs" value="${compile.test.patchmodules} ${compile.test.addreads}"/>
</target>
<target depends="-init-test-javac-module-properties" name="-init-test-module-properties">
</target>
<target depends="init,compile-test-single,-init-test-run-module-properties,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
<target depends="init,compile-test-single,-init-test-run-module-properties,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>
+ <target depends="debug-test-method" name="debug-single-method"/>
<target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
<property name="debug.modules.dir" value="${build.test.modules.dir}"/>
<j2semodularproject1:nbjpdareload xmlns:j2semodularproject1="http://www.netbeans.org/ns/j2se-modular-project/1"/>
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
- <target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
+ <target name="-recompile-netbeans-tasks-after-clean">
+ <antcall inheritall="false" target="-init-compile-netbeans-tasks"/>
+ </target>
+ <target depends="init,deps-clean,-do-clean,-recompile-netbeans-tasks-after-clean,-post-clean" description="Clean build products." name="clean"/>
<target name="-check-call-dep">
<property file="${call.built.properties}" prefix="already.built."/>
<condition property="should.call.dep">