1 // -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // ---------------------------------------------------------------------------
10 package cc
.squirreljme
.plugin
.multivm
;
12 import cc
.squirreljme
.plugin
.SquirrelJMEPluginConfiguration
;
13 import cc
.squirreljme
.plugin
.general
.UpdateFossilJavaDoc
;
14 import cc
.squirreljme
.plugin
.multivm
.gdb
.GdbUtils
;
15 import cc
.squirreljme
.plugin
.multivm
.ident
.SourceTargetClassifier
;
16 import cc
.squirreljme
.plugin
.swm
.JavaMEMidlet
;
17 import cc
.squirreljme
.plugin
.tasks
.AdditionalManifestPropertiesTask
;
18 import cc
.squirreljme
.plugin
.tasks
.GenerateTestsListTask
;
19 import cc
.squirreljme
.plugin
.tasks
.JasminAssembleTask
;
20 import cc
.squirreljme
.plugin
.tasks
.MimeDecodeResourcesTask
;
21 import cc
.squirreljme
.plugin
.tasks
.TestsJarTask
;
24 import java
.nio
.file
.Path
;
25 import java
.util
.ArrayList
;
26 import java
.util
.Iterator
;
27 import java
.util
.LinkedHashMap
;
28 import java
.util
.List
;
30 import org
.gradle
.api
.GradleException
;
31 import org
.gradle
.api
.Project
;
32 import org
.gradle
.api
.Task
;
33 import org
.gradle
.api
.UnknownDomainObjectException
;
34 import org
.gradle
.api
.file
.FileCollection
;
35 import org
.gradle
.api
.internal
.AbstractTask
;
36 import org
.gradle
.api
.plugins
.JavaPluginConvention
;
37 import org
.gradle
.api
.provider
.Provider
;
38 import org
.gradle
.api
.tasks
.SourceSet
;
39 import org
.gradle
.api
.tasks
.TaskContainer
;
40 import org
.gradle
.api
.tasks
.javadoc
.Javadoc
;
41 import org
.gradle
.api
.tasks
.testing
.Test
;
42 import org
.gradle
.external
.javadoc
.CoreJavadocOptions
;
43 import org
.gradle
.external
.javadoc
.MinimalJavadocOptions
;
44 import org
.gradle
.jvm
.tasks
.Jar
;
47 * This is used to initialize the Gradle tasks for projects accordingly.
51 public final class TaskInitialization
53 /** Use legacy testing? */
54 public static final boolean LEGACY_TEST_FRAMEWORK
=
55 Boolean
.getBoolean("squirreljme.test.legacy");
57 /** Source sets that are used. */
58 private static final String
[] _SOURCE_SETS
=
59 new String
[]{SourceSet
.MAIN_SOURCE_SET_NAME
,
60 VMHelpers
.TEST_FIXTURES_SOURCE_SET_NAME
,
61 SourceSet
.TEST_SOURCE_SET_NAME
};
68 private TaskInitialization()
73 * Initializes the project for the tasks and such
75 * @param __project The project to initialize for.
76 * @throws NullPointerException On null arguments.
79 public static void initialize(Project __project
)
80 throws NullPointerException
82 if (__project
== null)
83 throw new NullPointerException("NARG");
85 // Disable the test task, since it is non-functional
86 // However this might fail
89 __project
.getTasks().replace("test", DefunctTestTask
.class);
91 catch (IllegalStateException
|GradleException e
)
93 __project
.getLogger().debug("Could not defunct test task.", e
);
96 // The "check" task also depends on "test" which we do not want to
98 Task check
= __project
.getTasks().getByName("check");
99 for (Iterator
<Object
> it
= check
.getDependsOn().iterator();
102 // Get the root item, if a provider of one
103 Object item
= it
.next();
104 if (item
instanceof Provider
)
105 item
= ((Provider
<?
>)item
).get();
107 // Only consider tasks
108 if (!(item
instanceof Task
))
111 // Remove the test task, since we do not want it to run here
112 if ("test".equals(((Task
)item
).getName()))
116 // Initialize or both main classes and such
117 for (String sourceSet
: TaskInitialization
._SOURCE_SETS
)
118 TaskInitialization
.initialize(__project
, sourceSet
);
122 * Initializes the source set for the given project.
124 * @param __project The project to initialize for.
125 * @param __sourceSet The source set to be initialized.
126 * @throws NullPointerException On null arguments.
129 public static void initialize(Project __project
, String __sourceSet
)
130 throws NullPointerException
132 if (__project
== null || __sourceSet
== null)
133 throw new NullPointerException("NARG");
135 // Used for Jasmin and Mime Decoding tasks
136 Task processResources
= __project
.getTasks()
137 .getByName(TaskInitialization
.task(
138 "process", __sourceSet
, "resources"));
140 // Make sure process resources is run after any cleans so output is
141 // not destroyed after it is processed
142 Task clean
= __project
.getTasks().getByName("clean");
143 processResources
.mustRunAfter(clean
);
145 // Generate the list of tests that are available (only tests)
146 if (__sourceSet
.equals(SourceSet
.TEST_SOURCE_SET_NAME
))
147 __project
.getTasks().create("generateTestsList",
148 GenerateTestsListTask
.class,
149 processResources
, clean
);
151 // The current Jar Task
152 String jarTaskName
= TaskInitialization
.task(
153 "", __sourceSet
, "jar");
154 Jar jarTask
= (Jar
)__project
.getTasks()
155 .findByName(jarTaskName
);
157 // We need to know how to make the classes
158 Task classes
= __project
.getTasks()
159 .getByName(TaskInitialization
.task(
160 "", __sourceSet
, "classes"));
162 // If it does not exist, create it
164 jarTask
= (Jar
)__project
.getTasks()
165 .create("testJar", TestsJarTask
.class,
166 classes
, processResources
);
168 // Correct name of the Jar archive
169 String normalJarName
;
170 if (__sourceSet
.equals(SourceSet
.MAIN_SOURCE_SET_NAME
))
171 normalJarName
= __project
.getName() + ".jar";
173 normalJarName
= __project
.getName() + "-" + __sourceSet
+ ".jar";
174 jarTask
.getArchiveFileName().set(normalJarName
);
177 __project
.getTasks().create(TaskInitialization
.task(
178 "assemble", __sourceSet
, "jasmin"),
179 JasminAssembleTask
.class,
180 __sourceSet
, processResources
, clean
);
183 __project
.getTasks().create(TaskInitialization
.task(
184 "mimeDecode", __sourceSet
, "resources"),
185 MimeDecodeResourcesTask
.class,
186 __sourceSet
, processResources
, clean
);
188 // Add SquirrelJME properties to the manifest
189 __project
.getTasks().create(TaskInitialization
.task(
190 "additional", __sourceSet
, "jarProperties"),
191 AdditionalManifestPropertiesTask
.class,
192 jarTask
, processResources
, __sourceSet
, clean
);
194 // Initialize for each VM
195 for (VMType vmType
: VMType
.values())
196 TaskInitialization
.initialize(__project
, __sourceSet
, vmType
);
200 * Initializes the virtual machine for the given project's sourceset.
202 * @param __project The project to initialize for.
203 * @param __sourceSet The source set.
204 * @param __vmType The virtual machine type.
205 * @throws NullPointerException On null arguments.
208 public static void initialize(Project __project
, String __sourceSet
,
209 VMSpecifier __vmType
)
210 throws NullPointerException
212 if (__project
== null || __sourceSet
== null || __vmType
== null)
213 throw new NullPointerException("NARG");
215 for (ClutterLevel clutterLevel
: ClutterLevel
.values())
217 // Only allow debug targets for this?
218 if (__vmType
.allowOnlyDebug() && !clutterLevel
.isDebug())
222 for (BangletVariant variant
: __vmType
.banglets())
223 TaskInitialization
.initialize(__project
,
224 new SourceTargetClassifier(__sourceSet
, __vmType
, variant
,
230 * Initializes the virtual machine for the given project's sourceset.
232 * @param __project The project to initialize for.
233 * @param __classifier The classifier used.
234 * @throws NullPointerException On null arguments.
237 public static void initialize(Project __project
,
238 SourceTargetClassifier __classifier
)
239 throws NullPointerException
241 if (__project
== null || __classifier
== null)
242 throw new NullPointerException("NARG");
244 // Everything will be working on these tasks
245 TaskContainer tasks
= __project
.getTasks();
247 // Make sure the source set exists first
250 __project
.getConvention().getPlugin(JavaPluginConvention
.class)
251 .getSourceSets().getByName(__classifier
.getSourceSet());
253 catch (UnknownDomainObjectException e
)
255 __project
.getLogger().debug(String
.format(
256 "Could not find sourceSet %s in project %s (available: %s)",
257 __classifier
.getSourceSet(), __project
.getPath(),
259 __project
.getConvention()
260 .getPlugin(JavaPluginConvention
.class).getSourceSets())),
264 // The source library task depends on whether we are debugging or not
265 Jar sourceJar
= VMHelpers
.jarTask(__project
,
266 __classifier
.getSourceSet());
267 AbstractTask usedSourceJar
;
269 // If we are debugging, then we keep everything... otherwise we just
270 // strip everything out that we can to minimize the size as much as
272 // Or it is just disabled completely
273 if (__classifier
.getTargetClassifier().getClutterLevel().isDebug())
274 usedSourceJar
= sourceJar
;
276 // Otherwise set up a new task to compact the Jar and remove any
277 // debugging information and unneeded symbols for execution.
280 // Look for that task first
281 String checkName
= TaskInitialization
.task("compactLib",
282 __classifier
.getSourceSet());
283 AbstractTask maybe
= (AbstractTask
)tasks
.findByName(checkName
);
285 // If it exists, use that one
287 usedSourceJar
= maybe
;
289 // Otherwise, create it
292 usedSourceJar
= tasks
.create(checkName
,
293 VMCompactLibraryTask
.class, __classifier
.getSourceSet(),
298 // Library that needs to be constructed so execution happens properly
299 VMLibraryTask libTask
= tasks
.create(
300 TaskInitialization
.task("lib", __classifier
),
301 VMLibraryTask
.class, __classifier
, usedSourceJar
);
303 // Is dumping available?
304 if (__classifier
.getVmType().hasDumping())
306 TaskInitialization
.task("dump", __classifier
),
307 VMDumpLibraryTask
.class, __classifier
, libTask
);
309 // Emulator targets, which run the VM with the resultant code
310 if (__classifier
.getVmType().hasEmulator())
312 // Running the target, we want to be smarter and handle the
313 // various entry points but at this point there is no
314 // configuration information loaded yet... so do this later.
315 if (__classifier
.isMainSourceSet())
319 // Testing the target
320 else if (__classifier
.isTestSourceSet())
323 String taskName
= TaskInitialization
.task("test",
326 // Creating the legacy or modern test task? Using the modern
327 // one is recommended if using IntelliJ or otherwise...
328 if (TaskInitialization
.LEGACY_TEST_FRAMEWORK
)
329 vmTest
= tasks
.create(taskName
, VMLegacyTestTask
.class,
330 __classifier
, libTask
);
332 vmTest
= tasks
.create(taskName
, VMModernTestTask
.class,
333 __classifier
, libTask
);
335 // Since there is a release and debug variant, have the base
336 // test refer to both of these
337 String bothName
= TaskInitialization
.task("test",
338 __classifier
.getSourceSet(), __classifier
.getVmType(),
339 __classifier
.getBangletVariant(), null);
341 // If the task is missing, create it
342 Test bothTest
= (Test
)__project
.getTasks()
343 .findByName(bothName
);
344 if (bothTest
== null)
346 // Create a test task, so IDEs like IntelliJ can pick this
347 // up despite there being no actual tests that exist
348 bothTest
= __project
.getTasks().create(bothName
,
351 // Setup description of these
352 bothTest
.setGroup("squirreljme");
354 // Make sure the description makes sense
355 if (__classifier
.getVmType().allowOnlyDebug())
356 bothTest
.setDescription(
357 String
.format("Alias for %s.", taskName
));
359 bothTest
.setDescription(
360 String
.format("Runs both test tasks %s and %s.",
361 taskName
, TaskInitialization
.task(
363 __classifier
.withClutterLevel(
364 __classifier
.getTargetClassifier()
365 .getClutterLevel().opposite()))));
367 // Gradle will think these are JUnit tests and then fail
368 // so exclude everything
369 bothTest
.setScanForTestClasses(false);
371 bothTest
.exclude("**");
374 // Add to the both task as a dependency
375 bothTest
.dependsOn(vmTest
);
377 // Make the standard test task depend on these two VM tasks
378 // so that way if it is run, both are run accordingly
379 if (__classifier
.getVmType().isGoldTest())
381 Test test
= (Test
)__project
.getTasks()
385 test
.dependsOn(vmTest
);
387 // Gradle will think these are JUnit tests and then fail
388 // so exclude everything
389 test
.setScanForTestClasses(false);
398 * Initializes the task which puts the entire Markdown documentation into
399 * Fossil's versioned space.
401 * @param __project The project to initialize for.
402 * @param __javaDoc The JavaDoc Task.
403 * @throws NullPointerException On null arguments.
406 public static void initializeFossilMarkdownTask(Project __project
,
408 throws NullPointerException
410 if (__project
== null || __javaDoc
== null)
411 throw new NullPointerException("NARG");
413 // Find existing task, create if it does not yet exist
414 UpdateFossilJavaDoc task
= (UpdateFossilJavaDoc
)__project
.getTasks()
415 .findByName("updateFossilJavaDoc");
417 task
= (UpdateFossilJavaDoc
)__project
.getTasks()
418 .create("updateFossilJavaDoc", UpdateFossilJavaDoc
.class);
420 // Add dependency to the task for later usage
421 task
.dependsOn(__javaDoc
);
425 * Initializes the full-suite run which selects every API and library
426 * module available, along with allowing an external 3rd library classpath
429 * @param __project The root project.
430 * @throws NullPointerException On null arguments.
433 public static void initializeFullSuiteTask(Project __project
)
434 throws NullPointerException
436 if (__project
== null)
437 throw new NullPointerException("NARG");
439 for (ClutterLevel clutterLevel
: ClutterLevel
.values())
440 for (VMType vmType
: VMType
.values())
441 for (BangletVariant variant
: vmType
.banglets())
442 for (String sourceSet
: TaskInitialization
._SOURCE_SETS
)
443 TaskInitialization
.initializeFullSuiteTask(__project
,
444 new SourceTargetClassifier(sourceSet
, vmType
,
445 variant
, clutterLevel
));
449 * Initializes the full-suite run which selects every API and library
450 * module available, along with allowing an external 3rd library classpath
453 * @param __project The root project.
454 * @param __classifier The classifier used.
455 * @throws NullPointerException On null arguments.
458 public static void initializeFullSuiteTask(Project __project
,
459 SourceTargetClassifier __classifier
)
460 throws NullPointerException
462 if (__project
== null || __classifier
== null)
463 throw new NullPointerException("NARG");
465 // Is this a single source set ROM?
466 VMSpecifier vmType
= __classifier
.getVmType();
467 boolean isSingleSourceSetRom
= vmType
.isSingleSourceSetRom(
468 __classifier
.getBangletVariant());
470 // Do not run if there is no emulator
471 if (!__classifier
.getVmType().hasEmulator())
474 // Standard run everything as one, only allow main and test source
475 // sets to be a candidate for full
476 if (!__classifier
.isMainSourceSet() && !__classifier
.isTestSourceSet())
479 // If this is a debug only target and the requested clutter level is
480 // not debugging, then do not make such a task
481 if (__classifier
.getVmType().allowOnlyDebug() &&
482 !__classifier
.getTargetClassifier().getClutterLevel().isDebug())
486 TaskContainer tasks
= __project
.getTasks();
488 TaskInitialization
.task("full", __classifier
),
489 VMFullSuite
.class, __classifier
);
491 // Add generic runner for whatever we want
492 MakeRunTaskProvider provider
= (__useName
, __useClassifier
,
493 __useMainClass
, __useMidlet
, __useDebugServer
) -> {
494 tasks
.create(__useName
,
495 VMRunWhateverTask
.class, __useClassifier
,
496 __useMainClass
, __useMidlet
,
500 URI
[] gdbServer
= GdbUtils
.debuggerUri();
502 // Setup a bunch of fake MIDlets to possibly run
504 JavaMEMidlet
[] midlets
= new JavaMEMidlet
[n
];
505 for (int i
= 1; i
<= n
; i
++)
506 midlets
[i
- 1] = new JavaMEMidlet("" + i
, null,
509 // Make all the tasks
510 TaskInitialization
.makeRunTasks(provider
,
511 TaskInitialization
.task("runJar", __classifier
),
519 * Late initialization step.
521 * @param __project The project to initialize.
522 * @throws NullPointerException On null arguments.
525 public static void lateInitialize(Project __project
)
526 throws NullPointerException
528 if (__project
== null)
529 throw new NullPointerException("NARG");
531 // Configuration, for modifiers
532 SquirrelJMEPluginConfiguration config
=
533 SquirrelJMEPluginConfiguration
.configuration(__project
);
535 // Do we have main class and midlets?
536 boolean hasMain
= (config
.mainClass
!= null &&
537 !config
.mainClass
.isEmpty());
538 boolean hasMidlets
= (config
.midlets
!= null &&
539 !config
.midlets
.isEmpty());
541 // Tasks for registration and otherwise
542 TaskContainer tasks
= __project
.getTasks();
545 URI
[] gdbServer
= GdbUtils
.debuggerUri();
547 // Handle all source sets
548 if (hasMain
|| hasMidlets
)
549 for (String sourceSet
: TaskInitialization
._SOURCE_SETS
)
551 // Only consider the main source set
552 if (!sourceSet
.equals(SourceSet
.MAIN_SOURCE_SET_NAME
))
555 // Handle each virtual machine
556 for (VMType vmType
: VMType
.values())
558 // We cannot run on something that has no emulator
559 if (!vmType
.hasEmulator())
562 // We then have release/debug
563 for (ClutterLevel clutterLevel
: ClutterLevel
.values())
566 SourceTargetClassifier classifier
=
567 new SourceTargetClassifier(sourceSet
, vmType
,
568 BangletVariant
.NONE
, clutterLevel
);
570 // Dependent library task
571 VMLibraryTask libTask
=
572 (VMLibraryTask
)tasks
.findByName(
573 TaskInitialization
.task("lib",
578 // Index for base IDs
581 // Make all the run tasks
582 TaskInitialization
.makeRunTasks(classifier
, hasMain
,
583 tasks
, libTask
, config
,
584 gdbServer
, hasMidlets
);
589 // We need to evaluate the Doclet project first since we need
590 // the Jar task, which if we use normal evaluation does not exist
592 Project docletProject
=
593 __project
.evaluationDependsOn(":tools:markdown-javadoc");
595 // Setup task for creating JavaDoc
596 Javadoc mdJavaDoc
= tasks
597 .create("markdownJavaDoc", Javadoc
.class);
599 // What does this do?
600 mdJavaDoc
.setGroup("squirreljme");
601 mdJavaDoc
.setDescription("Generates Markdown JavaDoc.");
603 // This has a hard dependency and we do not want to get out of order
604 mdJavaDoc
.mustRunAfter(
605 docletProject
.getTasks().getByName("clean"),
606 docletProject
.getTasks().getByName("jar"));
608 // We are using a specific classpath, in this case it is just
609 // SpringCoat's libraries for runtime
610 SourceTargetClassifier classifier
= new SourceTargetClassifier(
611 SourceSet
.MAIN_SOURCE_SET_NAME
, VMType
.SPRINGCOAT
,
612 BangletVariant
.NONE
, ClutterLevel
.DEBUG
);
613 FileCollection useClassPath
= __project
.files(
614 (Object
[])VMHelpers
.runClassPath(__project
,
617 // We need to know how to make the classes
618 Task classes
= tasks
.getByName(TaskInitialization
.task(
619 "", SourceSet
.MAIN_SOURCE_SET_NAME
, "classes"));
621 // Where do we find the JAR?
622 Provider
<Task
> jarProvider
= __project
.provider(() ->
623 __project
.getRootProject().findProject(
624 ":tools:markdown-javadoc").getTasks()
625 .getByName("shadowJar"));
627 // SpringCoat related tasks
628 Provider
<Iterable
<Task
>> springCoatTasks
= __project
.provider(() ->
629 VMHelpers
.<Task
>resolveProjectTasks(
630 Task
.class, __project
, VMHelpers
.runClassTasks(__project
,
633 // Classes need to compile first, and we need the doclet Jar too
634 // However we do not know it exists yet
635 mdJavaDoc
.dependsOn(classes
);
636 mdJavaDoc
.dependsOn(springCoatTasks
);
637 mdJavaDoc
.dependsOn(jarProvider
);
639 // We also need to depend on other markdownJavaDoc tasks of our
640 // dependencies... this is so we can do cross-project links with
641 // our JavaDoc generation
642 mdJavaDoc
.dependsOn(__project
.provider(() -> {
643 Map
<String
, Javadoc
> result
= new LinkedHashMap
<>();
645 for (Task task
: springCoatTasks
.get()) {
646 // Ignore our own project, otherwise recursive!
647 Project subProject
= task
.getProject();
648 if (subProject
.equals(__project
))
651 // Only refer to projects once
652 String subName
= subProject
.getPath();
653 if (!result
.containsKey(subName
))
655 (Javadoc
)subProject
.getTasks()
656 .getByName("markdownJavaDoc"));
659 return result
.values();
662 // Where are the sources?
663 SourceSet sourceSet
= __project
.getConvention().getPlugin(
664 JavaPluginConvention
.class).getSourceSets().getByName(
665 SourceSet
.MAIN_SOURCE_SET_NAME
);
667 // Configure the JavaDoc task
668 mdJavaDoc
.setDestinationDir(TaskInitialization
.markdownPath(__project
)
670 mdJavaDoc
.source(sourceSet
.getAllJava());
671 mdJavaDoc
.setClasspath(useClassPath
);
672 mdJavaDoc
.setTitle(config
.swmName
);
674 // Determine the paths where all markdown JavaDocs are being stored
675 List
<Path
> projectPaths
= new ArrayList
<>();
676 for (Project subProject
: __project
.getRootProject().getAllprojects())
678 // Only consider SquirrelJME projects
680 SquirrelJMEPluginConfiguration
.configurationOrNull(subProject
))
683 // We just store this here, since we do not know what exists
684 // and does not exist
685 projectPaths
.add(TaskInitialization
.markdownPath(subProject
));
688 // Setup more advanced options
689 mdJavaDoc
.options((MinimalJavadocOptions __options
) ->
691 // We need to set the bootstrap class path otherwise
692 // we will get derivations from whatever JDK the system
693 // is using, and we definitely do not want that.
694 __options
.bootClasspath(useClassPath
.getFiles()
695 .toArray(new File
[0]));
697 // We get this by forcing evaluation
698 Task mdJavaDocletJar
= jarProvider
.get();
701 __options
.showFromProtected();
702 __options
.encoding("utf-8");
703 __options
.locale("en_US");
704 __options
.docletpath(mdJavaDocletJar
.getOutputs()
705 .getFiles().getSingleFile());
707 "cc.squirreljme.doclet.MarkdownDoclet");
709 // Used for completion counting
710 if (__options
instanceof CoreJavadocOptions
)
712 CoreJavadocOptions coreOptions
=
713 (CoreJavadocOptions
)__options
;
715 // Where to find our own sources (for TODOs)
716 coreOptions
.addStringOption(
717 "squirreljmejavasources",
718 sourceSet
.getAllJava().getAsPath());
720 // Directories to all the other markdown JavaDocs
721 coreOptions
.addStringOption(
722 "squirreljmeprojectmjd",
723 VMHelpers
.classpathAsString(projectPaths
));
725 // The name of the project
726 coreOptions
.addStringOption(
727 "squirreljmeproject",
728 __project
.getName());
733 TaskInitialization
.initializeFossilMarkdownTask(
734 __project
.getRootProject(), mdJavaDoc
);
740 * @param __provider The task creation provider.
741 * @param __name The name of the task.
742 * @param __mainClass The main class.
743 * @param __midlet The midlet to create for.
744 * @param __classifier The classifier used.
745 * @param __gdbServer The GBD server.
748 public static void makeRunTasks(MakeRunTaskProvider __provider
,
749 String __name
, String __mainClass
, JavaMEMidlet __midlet
,
750 SourceTargetClassifier __classifier
, URI
[] __gdbServer
)
752 if (__provider
== null || __name
== null || __classifier
== null ||
753 __mainClass
== null || __midlet
== null)
754 throw new NullPointerException("NARG");
756 if (!__mainClass
.isEmpty() && __midlet
!= JavaMEMidlet
.NONE
)
757 throw new IllegalArgumentException(
758 "Main class and MIDlet are exclusive to each other");
760 // Main debug-free task
761 __provider
.makeTask(__name
,
762 __classifier
, __mainClass
, __midlet
,
763 VMRunTask
.NO_DEBUG_SERVER
);
765 // JDWP and Internal JDWP Tasks
766 __provider
.makeTask(__name
+ "Jdwp",
767 __classifier
, __mainClass
, __midlet
,
768 VMRunTask
.JDWP_HOST
);
769 __provider
.makeTask(__name
+ "JdwpInternal",
770 __classifier
, __mainClass
, __midlet
,
774 if (__gdbServer
!= null && __gdbServer
.length
> 0)
775 for (URI server
: __gdbServer
)
776 __provider
.makeTask(__name
+
777 TaskInitialization
.uppercaseFirst(server
.getScheme()),
778 __classifier
, __mainClass
, __midlet
,
783 * Makes tasks for the main class and all the MIDlets.
785 * @param __provider The provider for creating tasks.
786 * @param __name The task base name.
787 * @param __mainClass The main class.
788 * @param __midlets The MIDlets to create for.
789 * @param __classifier The classifier used.
790 * @param __gdbServer The GDB server.
793 public static void makeRunTasks(MakeRunTaskProvider __provider
,
794 String __name
, String __mainClass
, JavaMEMidlet
[] __midlets
,
795 SourceTargetClassifier __classifier
, URI
[] __gdbServer
)
797 // Consider standard Java mains first
799 if (__mainClass
!= null && !__mainClass
.isEmpty())
802 TaskInitialization
.makeRunTasks(__provider
,
803 __name
, __mainClass
, JavaMEMidlet
.NONE
, __classifier
,
811 if (__midlets
!= null && __midlets
.length
> 0)
812 for (JavaMEMidlet midlet
: __midlets
)
814 // Add digit following for different midlets
815 String realName
= (index
> 0 ?
816 __name
+ index
: __name
);
819 TaskInitialization
.makeRunTasks(__provider
,
820 realName
, "", midlet
, __classifier
,
831 * @param __classifier The classifier used.
832 * @param __hasMain Is there a main class specified?
833 * @param __tasks The tasks.
834 * @param __libTask The current library task.
835 * @param __config The configuration used.
836 * @param __gdbServer The GDB server.
837 * @param __hasMidlets Does this have MIDlets?
840 public static void makeRunTasks(SourceTargetClassifier __classifier
,
841 boolean __hasMain
, TaskContainer __tasks
, VMLibraryTask __libTask
,
842 SquirrelJMEPluginConfiguration __config
, URI
[] __gdbServer
,
843 boolean __hasMidlets
)
845 // Base name for task
846 String name
= TaskInitialization
.task("run", __classifier
);
848 MakeRunTaskProvider provider
= (__useName
,
850 __useMainClass
, __useMidlet
, __useDebugServer
) -> {
851 __tasks
.create(__useName
,
852 VMRunTask
.class, __useClassifier
, __libTask
,
853 __useMainClass
, __useMidlet
,
856 TaskInitialization
.makeRunTasks(provider
,
858 (String
)(__hasMain ? __config
.mainClass
: null),
859 (JavaMEMidlet
[])(__hasMidlets ? __config
.midlets
.toArray(
860 new JavaMEMidlet
[0]) : null),
866 * Returns the path to the markdown JavaDoc for a project.
868 * @param __project The project to get for.
869 * @return The path to the project's markdown JavaDoc.
870 * @throws NullPointerException On null arguments.
873 public static Path
markdownPath(Project __project
)
874 throws NullPointerException
876 if (__project
== null)
877 throw new NullPointerException("NARG");
879 return __project
.getBuildDir().toPath().resolve("markdownJavaDoc");
883 * Initializes ROM tasks for the given base project.
885 * @param __project The root project.
886 * @throws NullPointerException On null arguments.
889 public static void romTasks(Project __project
)
890 throws NullPointerException
892 if (__project
== null)
893 throw new NullPointerException("NARG");
895 // Initialize or both main classes and such
896 for (VMType vmType
: VMType
.values())
898 // Sequential clean storage?
899 List
<Task
> sequentialClean
= new ArrayList
<>();
901 // Process for each possible combination
902 for (ClutterLevel clutterLevel
: ClutterLevel
.values())
903 for (String sourceSet
: TaskInitialization
._SOURCE_SETS
)
904 for (BangletVariant variant
: vmType
.banglets())
905 TaskInitialization
.romTasks(__project
,
906 new SourceTargetClassifier(sourceSet
, vmType
,
907 variant
, clutterLevel
), sequentialClean
);
912 * Initializes ROM tasks for the given base project.
914 * @param __project The root project.
915 * @param __classifier The classifier used.
916 * @param __sequentialClean Sequential clean list.
917 * @throws NullPointerException On null arguments.
920 public static void romTasks(Project __project
,
921 SourceTargetClassifier __classifier
, List
<Task
> __sequentialClean
)
922 throws NullPointerException
924 if (__project
== null || __classifier
== null ||
925 __sequentialClean
== null)
926 throw new NullPointerException("NARG");
928 // Everything will be working on these tasks
929 TaskContainer tasks
= __project
.getTasks();
931 // Determine if this is a single source set ROM
932 VMSpecifier vmType
= __classifier
.getVmType();
933 boolean isSingleSourceSetRom
= vmType
.isSingleSourceSetRom(
934 __classifier
.getBangletVariant());
936 // Does the VM utilize ROMs?
937 // Test fixtures are just for testing, so there is no test fixtures
938 // ROM variant... unless we are a single source set ROM variant
939 if (vmType
.hasRom(__classifier
.getBangletVariant()) &&
940 (isSingleSourceSetRom
|| !__classifier
.isTestFixturesSourceSet()))
942 String baseName
= TaskInitialization
.task("rom",
944 VMRomTask rom
= tasks
.create(baseName
, VMRomTask
.class,
947 // Which native ports are supported?
948 for (NativePortSupport nativePort
:
949 __classifier
.getVmType().hasNativePortSupport())
957 taskName
= baseName
+ "NanoCoat";
958 nativeTask
= tasks
.create(
960 NanoCoatBuiltInTask
.class,
965 throw new Error(nativePort
.toString());
968 // Setup cleaning task
969 Task cleanTask
= nativePort
.cleanTask(nativeTask
,
972 // Clean should call these accordingly
973 __project
.afterEvaluate((__p
) ->
974 cleanTask
.getProject().getRootProject().getTasks()
975 .getByName("clean").dependsOn(cleanTask
));
977 // Does clean have to be done sequentially and not in
978 // parallel? This means the clean task is quite complicated
979 // and not easily determined, probably because it looks at
980 // all the ROM files.
981 if (isSingleSourceSetRom
|| nativePort
.isSequentialClean())
983 // Have this task run after the previous clean task that
985 if (!__sequentialClean
.isEmpty())
986 cleanTask
.mustRunAfter(__sequentialClean
.get(
987 __sequentialClean
.size() - 1));
989 // Add self to the sequential clean list
990 __sequentialClean
.add(cleanTask
);
993 // Clean, if it occurs, must happen before
994 nativeTask
.mustRunAfter(cleanTask
);
1000 * Builds a name for a task, without the virtual machine type.
1002 * @param __name The task name.
1003 * @param __sourceSet The source set for the task base.
1004 * @return A string representing the task.
1005 * @throws NullPointerException On null arguments.
1008 public static String
task(String __name
, String __sourceSet
)
1009 throws NullPointerException
1011 return TaskInitialization
.task(__name
, __sourceSet
, "");
1015 * Builds a name for a task, without the virtual machine type.
1017 * @param __name The task name.
1018 * @param __sourceSet The source set for the task base.
1019 * @param __suffix The task suffix.
1020 * @return A string representing the task.
1021 * @throws NullPointerException On null arguments.
1024 public static String
task(String __name
, String __sourceSet
,
1026 throws NullPointerException
1028 if (__name
== null || __sourceSet
== null || __suffix
== null)
1029 throw new NullPointerException("NARG");
1031 // We need to later determine how the suffix works
1034 // If this is the main source set, never include the source set as
1035 // it becomes implied. Additionally, if the name and the source set
1036 // are the same, reduce the confusion so there is no "testTestHosted".
1037 if (__sourceSet
.equals(SourceSet
.MAIN_SOURCE_SET_NAME
) ||
1038 __sourceSet
.equals(__name
) || __sourceSet
.isEmpty())
1041 // Otherwise, include it
1044 // If just the source set, then just keep that lowercase
1045 if (__name
.isEmpty())
1046 baseName
= __sourceSet
;
1049 TaskInitialization
.uppercaseFirst(__sourceSet
);
1052 // If there is no suffix, just return the base
1053 if (__suffix
.isEmpty())
1056 // If there is no base, just return the suffix
1057 if (baseName
.isEmpty())
1060 // Otherwise, perform needed capitalization
1061 // "additionalJarProperties" or "additionalTestJarProperties"
1062 return baseName
+ TaskInitialization
.uppercaseFirst(__suffix
);
1066 * Builds a name for a task.
1068 * @param __name The task name.
1069 * @param __sourceSet The source set for the task base.
1070 * @param __vmType The type of virtual machine used.
1071 * @return A string representing the task.
1072 * @throws NullPointerException On null arguments.
1075 public static String
task(String __name
, String __sourceSet
,
1076 VMSpecifier __vmType
)
1077 throws NullPointerException
1079 return TaskInitialization
.task(__name
, __sourceSet
, __vmType
,
1080 BangletVariant
.NONE
, ClutterLevel
.DEBUG
);
1084 * Initializes the task name.
1086 * @param __name The name of the task.
1087 * @param __classifier The classifier for the target.
1088 * @return The task name.
1089 * @throws NullPointerException On null arguments.
1092 public static String
task(String __name
,
1093 SourceTargetClassifier __classifier
)
1094 throws NullPointerException
1096 if (__name
== null || __classifier
== null)
1097 throw new NullPointerException("NARG");
1099 return TaskInitialization
.task(__name
,
1100 __classifier
.getSourceSet(),
1101 __classifier
.getTargetClassifier().getVmType(),
1102 __classifier
.getTargetClassifier().getBangletVariant(),
1103 __classifier
.getTargetClassifier().getClutterLevel());
1107 * Builds a name for a task.
1109 * @param __name The task name.
1110 * @param __sourceSet The source set for the task base.
1111 * @param __vmType The type of virtual machine used.
1112 * @param __variant The banglet variant.
1113 * @param __clutterLevel Release or debug, may be {@code null}.
1114 * @return A string representing the task.
1115 * @throws NullPointerException On null arguments.
1118 public static String
task(String __name
, String __sourceSet
,
1119 VMSpecifier __vmType
, BangletVariant __variant
,
1120 ClutterLevel __clutterLevel
)
1121 throws NullPointerException
1123 if (__name
== null || __sourceSet
== null || __vmType
== null ||
1125 throw new NullPointerException("NARG");
1127 return TaskInitialization
.task(__name
, __sourceSet
) +
1128 __vmType
.vmName(VMNameFormat
.PROPER_NOUN
) +
1129 TaskInitialization
.uppercaseFirst(__variant
.properNoun
) +
1130 (__clutterLevel
== null ?
"" :
1131 TaskInitialization
.uppercaseFirst(__clutterLevel
.toString()));
1135 * Uppercases the first character of a string.
1137 * @param __input The input string.
1138 * @return The string with the first character uppercased.
1139 * @throws NullPointerException On null arguments.
1142 public static String
uppercaseFirst(String __input
)
1143 throws NullPointerException
1145 if (__input
== null)
1146 throw new NullPointerException("NARG");
1148 if (__input
.isEmpty())
1151 return Character
.toUpperCase(__input
.charAt(0)) +
1152 __input
.substring(1);