From 94fe41418a8af8c07aaead6d09a200e041c79104 Mon Sep 17 00:00:00 2001 From: Dmytro Dashenkov Date: Tue, 7 Apr 2020 15:16:23 +0300 Subject: [PATCH 01/10] Move import resolution code to `tool-base` --- license-report.md | 30 +++++----- .../spine/tools/code}/DirectoryPattern.java | 3 +- .../io/spine/tools/code}/ExternalModule.java | 11 +++- .../io/spine/tools/code}/ImportStatement.java | 12 ++-- .../java/io/spine/tools/code}/JsFile.java | 10 ++-- .../io/spine/tools/code}/package-info.java | 2 +- .../spine/tools/gradle/ProtoDartTaskName.java | 4 +- .../tools/code}/DirectoryPatternTest.java | 2 +- .../spine/tools/code}/ExternalModuleTest.java | 4 +- .../tools/code}/ImportStatementTest.java | 6 +- .../java/io/spine/tools/code}/JsFileTest.java | 4 +- .../io/spine/tools/code}/given/Given.java | 16 ++--- .../spine/tools/code/given/package-info.java | 28 +++++++++ .../io/spine/generate/dart/Extension.java | 59 +++++++++++++++++++ .../spine/generate/dart/ProtoDartPlugin.java | 11 ++++ .../java/io/spine/js/gradle/Extension.java | 20 ++----- .../io/spine/js/gradle/ProtoJsPlugin.java | 3 +- .../resolve => gradle}/ResolveImports.java | 5 +- .../io/spine/js/gradle/ExtensionTest.java | 34 +++++------ .../ResolveImportsTest.java | 12 +++- 20 files changed, 185 insertions(+), 91 deletions(-) rename tools/{proto-js-plugin/src/main/java/io/spine/js/generate/resolve => plugin-base/src/main/java/io/spine/tools/code}/DirectoryPattern.java (98%) rename tools/{proto-js-plugin/src/main/java/io/spine/js/generate/resolve => plugin-base/src/main/java/io/spine/tools/code}/ExternalModule.java (94%) rename tools/{proto-js-plugin/src/main/java/io/spine/js/generate/resolve => plugin-base/src/main/java/io/spine/tools/code}/ImportStatement.java (93%) rename tools/{proto-js-plugin/src/main/java/io/spine/js/generate/resolve => plugin-base/src/main/java/io/spine/tools/code}/JsFile.java (93%) rename tools/{proto-js-plugin/src/main/java/io/spine/js/generate/resolve => plugin-base/src/main/java/io/spine/tools/code}/package-info.java (96%) rename tools/{proto-js-plugin/src/test/java/io/spine/js/generate/resolve => plugin-base/src/test/java/io/spine/tools/code}/DirectoryPatternTest.java (99%) rename tools/{proto-js-plugin/src/test/java/io/spine/js/generate/resolve => plugin-base/src/test/java/io/spine/tools/code}/ExternalModuleTest.java (97%) rename tools/{proto-js-plugin/src/test/java/io/spine/js/generate/resolve => plugin-base/src/test/java/io/spine/tools/code}/ImportStatementTest.java (93%) rename tools/{proto-js-plugin/src/test/java/io/spine/js/generate/resolve => plugin-base/src/test/java/io/spine/tools/code}/JsFileTest.java (96%) rename tools/{proto-js-plugin/src/test/java/io/spine/js/generate/resolve => plugin-base/src/test/java/io/spine/tools/code}/given/Given.java (85%) create mode 100644 tools/plugin-base/src/test/java/io/spine/tools/code/given/package-info.java rename tools/proto-js-plugin/src/main/java/io/spine/js/{generate/resolve => gradle}/ResolveImports.java (98%) rename tools/proto-js-plugin/src/test/java/io/spine/js/{generate/resolve => gradle}/ResolveImportsTest.java (93%) diff --git a/license-report.md b/license-report.md index 1e5d2392a5..1c78e3cc14 100644 --- a/license-report.md +++ b/license-report.md @@ -330,7 +330,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 06 12:01:12 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Apr 07 13:45:02 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -777,7 +777,7 @@ This report was generated on **Mon Apr 06 12:01:12 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 06 12:01:13 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Apr 07 13:45:03 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1170,7 +1170,7 @@ This report was generated on **Mon Apr 06 12:01:13 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 06 12:01:14 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Apr 07 13:45:04 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1537,7 +1537,7 @@ This report was generated on **Mon Apr 06 12:01:14 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 06 12:01:14 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Apr 07 13:45:05 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1920,7 +1920,7 @@ This report was generated on **Mon Apr 06 12:01:14 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 06 12:01:15 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Apr 07 13:45:05 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2305,7 +2305,7 @@ This report was generated on **Mon Apr 06 12:01:15 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 06 12:01:15 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Apr 07 13:45:06 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -2672,7 +2672,7 @@ This report was generated on **Mon Apr 06 12:01:15 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 06 12:01:16 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Apr 07 13:45:06 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3097,7 +3097,7 @@ This report was generated on **Mon Apr 06 12:01:16 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 06 12:01:16 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Apr 07 13:45:07 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3464,7 +3464,7 @@ This report was generated on **Mon Apr 06 12:01:16 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 06 12:01:17 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Apr 07 13:45:07 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -3831,7 +3831,7 @@ This report was generated on **Mon Apr 06 12:01:17 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 06 12:01:17 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Apr 07 13:45:07 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4158,7 +4158,7 @@ This report was generated on **Mon Apr 06 12:01:17 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 06 12:01:18 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Apr 07 13:45:08 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4493,7 +4493,7 @@ This report was generated on **Mon Apr 06 12:01:18 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 06 12:01:18 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Apr 07 13:45:08 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -4878,7 +4878,7 @@ This report was generated on **Mon Apr 06 12:01:18 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 06 12:01:18 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Apr 07 13:45:09 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5213,7 +5213,7 @@ This report was generated on **Mon Apr 06 12:01:18 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 06 12:01:19 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Apr 07 13:45:09 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -5548,4 +5548,4 @@ This report was generated on **Mon Apr 06 12:01:19 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 06 12:01:19 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file +This report was generated on **Tue Apr 07 13:45:09 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file diff --git a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/DirectoryPattern.java b/tools/plugin-base/src/main/java/io/spine/tools/code/DirectoryPattern.java similarity index 98% rename from tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/DirectoryPattern.java rename to tools/plugin-base/src/main/java/io/spine/tools/code/DirectoryPattern.java index cbd124ae28..d3c6455a24 100644 --- a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/DirectoryPattern.java +++ b/tools/plugin-base/src/main/java/io/spine/tools/code/DirectoryPattern.java @@ -18,7 +18,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.js.generate.resolve; +package io.spine.tools.code; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Joiner; @@ -62,7 +62,6 @@ private DirectoryPattern(DirectoryReference directory, boolean includeNested) { * the value of the pattern * @return a new instance */ - @SuppressWarnings("ResultOfMethodCallIgnored" /* The result can be ignored. */) public static DirectoryPattern of(String value) { checkNotEmptyOrBlank(value); boolean includeNested = value.endsWith(INCLUDE_NESTED_PATTERN_ENDING); diff --git a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/ExternalModule.java b/tools/plugin-base/src/main/java/io/spine/tools/code/ExternalModule.java similarity index 94% rename from tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/ExternalModule.java rename to tools/plugin-base/src/main/java/io/spine/tools/code/ExternalModule.java index 40e1e94535..8ce1e99c9b 100644 --- a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/ExternalModule.java +++ b/tools/plugin-base/src/main/java/io/spine/tools/code/ExternalModule.java @@ -18,9 +18,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.js.generate.resolve; +package io.spine.tools.code; import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import io.spine.code.fs.js.DirectoryReference; import io.spine.code.fs.js.FileReference; @@ -65,7 +66,7 @@ public ExternalModule(String name, Collection directories) { * @throws IllegalStateException * if the file is not provided by the module */ - FileReference fileInModule(FileReference fileReference) { + public FileReference fileInModule(FileReference fileReference) { Optional matchingDirectory = matchingDirectory(fileReference); checkState(matchingDirectory.isPresent()); DirectoryReference directory = matchingDirectory.get() @@ -83,7 +84,7 @@ FileReference fileInModule(FileReference fileReference) { * the file to check * @return {@code true} if the module provides the file */ - boolean provides(FileReference fileReference) { + public boolean provides(FileReference fileReference) { boolean result = matchingDirectory(fileReference).isPresent(); return result; } @@ -133,6 +134,10 @@ public static ExternalModule spineUsers() { return new ExternalModule("spine-users", directories); } + public static ImmutableList predefinedModules() { + return ImmutableList.of(spineWeb(), spineUsers()); + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/ImportStatement.java b/tools/plugin-base/src/main/java/io/spine/tools/code/ImportStatement.java similarity index 93% rename from tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/ImportStatement.java rename to tools/plugin-base/src/main/java/io/spine/tools/code/ImportStatement.java index 45026415db..edfd18fcc4 100644 --- a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/ImportStatement.java +++ b/tools/plugin-base/src/main/java/io/spine/tools/code/ImportStatement.java @@ -18,7 +18,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.js.generate.resolve; +package io.spine.tools.code; import io.spine.code.fs.js.FileReference; import io.spine.logging.Logging; @@ -66,7 +66,7 @@ static boolean hasImport(String line) { /** * Obtains the file reference used in this import. */ - FileReference path() { + public FileReference path() { int beginIndex = text.indexOf(IMPORT_BEGIN_SIGN) + IMPORT_BEGIN_SIGN.length(); int endIndex = text.indexOf(IMPORT_END_SIGN, beginIndex); String importPath = text.substring(beginIndex, endIndex); @@ -76,7 +76,7 @@ FileReference path() { /** * Obtains a new instance with the updated path in the import statement. */ - ImportStatement replacePath(CharSequence newPath) { + public ImportStatement replacePath(CharSequence newPath) { String updatedText = text.replace(path().value(), newPath); return new ImportStatement(updatedText, originFile); } @@ -91,7 +91,7 @@ String text() { /** * Tells whether the imported file is present on a file system. */ - boolean importedFileExists() { + public boolean importedFileExists() { Path filePath = importedFilePath(); boolean exists = filePath.toFile() .exists(); @@ -102,7 +102,7 @@ boolean importedFileExists() { /** * Obtains the absolute path to the imported file. */ - Path importedFilePath() { + public Path importedFilePath() { FileReference fileReference = path(); Path filePath = sourceDirectory().resolve(fileReference.value()); return filePath.normalize(); @@ -111,7 +111,7 @@ Path importedFilePath() { /** * Obtains the path of the directory with the file containing this import. */ - Path sourceDirectory() { + public Path sourceDirectory() { return originFile.getParentFile() .toPath(); } diff --git a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/JsFile.java b/tools/plugin-base/src/main/java/io/spine/tools/code/JsFile.java similarity index 93% rename from tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/JsFile.java rename to tools/plugin-base/src/main/java/io/spine/tools/code/JsFile.java index ca1490c877..dfd3f6c8a6 100644 --- a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/JsFile.java +++ b/tools/plugin-base/src/main/java/io/spine/tools/code/JsFile.java @@ -18,7 +18,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.js.generate.resolve; +package io.spine.tools.code; import com.google.common.base.Charsets; @@ -39,13 +39,13 @@ /** * A JavaScript file present on a file system. */ -final class JsFile { +public final class JsFile { private static final String EXTENSION = ".js"; private final Path path; - JsFile(Path path) { + public JsFile(Path path) { checkArgument(path.toString() .endsWith(EXTENSION), "A JavaScript file is expected."); checkArgument(path.toFile() @@ -63,7 +63,7 @@ final class JsFile { * @param processFunction * the function processing an import */ - void processImports(Predicate importFilter, + public void processImports(Predicate importFilter, ProcessImport processFunction) { try (Stream lines = Files.lines(path)) { List updatedLines = lines @@ -101,6 +101,6 @@ private void rewriteFile(Iterable lines) { /** * A function processing an import statement. */ - interface ProcessImport extends UnaryOperator { + public interface ProcessImport extends UnaryOperator { } } diff --git a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/package-info.java b/tools/plugin-base/src/main/java/io/spine/tools/code/package-info.java similarity index 96% rename from tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/package-info.java rename to tools/plugin-base/src/main/java/io/spine/tools/code/package-info.java index 5810177a3d..a640309c8d 100644 --- a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/package-info.java +++ b/tools/plugin-base/src/main/java/io/spine/tools/code/package-info.java @@ -23,7 +23,7 @@ */ @CheckReturnValue @ParametersAreNonnullByDefault -package io.spine.js.generate.resolve; +package io.spine.tools.code; import javax.annotation.CheckReturnValue; import javax.annotation.ParametersAreNonnullByDefault; diff --git a/tools/plugin-base/src/main/java/io/spine/tools/gradle/ProtoDartTaskName.java b/tools/plugin-base/src/main/java/io/spine/tools/gradle/ProtoDartTaskName.java index 4a70a34aa4..d5e79420a1 100644 --- a/tools/plugin-base/src/main/java/io/spine/tools/gradle/ProtoDartTaskName.java +++ b/tools/plugin-base/src/main/java/io/spine/tools/gradle/ProtoDartTaskName.java @@ -58,5 +58,7 @@ public enum ProtoDartTaskName implements TaskName { * *

Works only with the {@code test} scope files. */ - copyTestGeneratedDart + copyTestGeneratedDart, + + resolveImports } diff --git a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/DirectoryPatternTest.java b/tools/plugin-base/src/test/java/io/spine/tools/code/DirectoryPatternTest.java similarity index 99% rename from tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/DirectoryPatternTest.java rename to tools/plugin-base/src/test/java/io/spine/tools/code/DirectoryPatternTest.java index e2ce73c3f5..f812a29b70 100644 --- a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/DirectoryPatternTest.java +++ b/tools/plugin-base/src/test/java/io/spine/tools/code/DirectoryPatternTest.java @@ -18,7 +18,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.js.generate.resolve; +package io.spine.tools.code; import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; diff --git a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/ExternalModuleTest.java b/tools/plugin-base/src/test/java/io/spine/tools/code/ExternalModuleTest.java similarity index 97% rename from tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/ExternalModuleTest.java rename to tools/plugin-base/src/test/java/io/spine/tools/code/ExternalModuleTest.java index ccacea3996..d337e88eea 100644 --- a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/ExternalModuleTest.java +++ b/tools/plugin-base/src/test/java/io/spine/tools/code/ExternalModuleTest.java @@ -18,14 +18,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.js.generate.resolve; +package io.spine.tools.code; import com.google.common.testing.EqualsTester; import io.spine.code.fs.js.FileReference; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import static io.spine.js.generate.resolve.given.Given.newModule; +import static io.spine.tools.code.given.Given.newModule; import static java.util.Collections.emptySet; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; diff --git a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/ImportStatementTest.java b/tools/plugin-base/src/test/java/io/spine/tools/code/ImportStatementTest.java similarity index 93% rename from tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/ImportStatementTest.java rename to tools/plugin-base/src/test/java/io/spine/tools/code/ImportStatementTest.java index 08146d49c7..9d7d97907f 100644 --- a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/ImportStatementTest.java +++ b/tools/plugin-base/src/test/java/io/spine/tools/code/ImportStatementTest.java @@ -18,7 +18,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.js.generate.resolve; +package io.spine.tools.code; import io.spine.code.fs.js.FileReference; import org.junit.jupiter.api.DisplayName; @@ -29,8 +29,8 @@ import java.nio.file.Paths; import static com.google.common.truth.Truth.assertThat; -import static io.spine.js.generate.resolve.given.Given.importWithPath; -import static io.spine.js.generate.resolve.given.Given.relativeImportPath; +import static io.spine.tools.code.given.Given.importWithPath; +import static io.spine.tools.code.given.Given.relativeImportPath; import static org.junit.jupiter.api.Assertions.assertEquals; @DisplayName("ImportStatement should") diff --git a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/JsFileTest.java b/tools/plugin-base/src/test/java/io/spine/tools/code/JsFileTest.java similarity index 96% rename from tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/JsFileTest.java rename to tools/plugin-base/src/test/java/io/spine/tools/code/JsFileTest.java index a2fab1eb48..859e8e1955 100644 --- a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/JsFileTest.java +++ b/tools/plugin-base/src/test/java/io/spine/tools/code/JsFileTest.java @@ -18,7 +18,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.js.generate.resolve; +package io.spine.tools.code; import com.google.common.collect.ImmutableList; import org.junit.jupiter.api.BeforeEach; @@ -35,7 +35,7 @@ import java.util.List; import static com.google.common.truth.Truth.assertThat; -import static io.spine.js.generate.resolve.given.Given.importWithPath; +import static io.spine.tools.code.given.Given.importWithPath; @ExtendWith(TempDirectory.class) @DisplayName("JavaScript file should") diff --git a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/given/Given.java b/tools/plugin-base/src/test/java/io/spine/tools/code/given/Given.java similarity index 85% rename from tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/given/Given.java rename to tools/plugin-base/src/test/java/io/spine/tools/code/given/Given.java index 7da7c8021c..5c6a67b748 100644 --- a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/given/Given.java +++ b/tools/plugin-base/src/test/java/io/spine/tools/code/given/Given.java @@ -18,12 +18,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.js.generate.resolve.given; +package io.spine.tools.code.given; import io.spine.code.fs.js.Directory; -import io.spine.js.generate.resolve.DirectoryPattern; -import io.spine.js.generate.resolve.ExternalModule; -import io.spine.js.generate.resolve.ImportStatement; +import io.spine.tools.code.DirectoryPattern; +import io.spine.tools.code.ExternalModule; +import io.spine.tools.code.ImportStatement; import java.io.File; import java.nio.file.Path; @@ -44,14 +44,6 @@ public static ImportStatement importWithPath(String path, File importOrigin) { return new ImportStatement(importText, importOrigin); } - public static Directory mainProtoRoot() { - return protoRoot("main"); - } - - public static Directory testProtoRoot() { - return protoRoot("test"); - } - public static String relativeImportPath() { return "../path-relative-to-parent.js"; } diff --git a/tools/plugin-base/src/test/java/io/spine/tools/code/given/package-info.java b/tools/plugin-base/src/test/java/io/spine/tools/code/given/package-info.java new file mode 100644 index 0000000000..fdce3cb515 --- /dev/null +++ b/tools/plugin-base/src/test/java/io/spine/tools/code/given/package-info.java @@ -0,0 +1,28 @@ + +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +@CheckReturnValue +@ParametersAreNonnullByDefault +package io.spine.tools.code.given; + +import com.google.errorprone.annotations.CheckReturnValue; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/Extension.java b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/Extension.java index 146695c1ca..7175142e3b 100644 --- a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/Extension.java +++ b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/Extension.java @@ -21,6 +21,8 @@ package io.spine.generate.dart; import io.spine.code.fs.dart.DefaultDartProject; +import io.spine.tools.code.DirectoryPattern; +import io.spine.tools.code.ExternalModule; import io.spine.tools.gradle.GradleExtension; import org.gradle.api.Project; import org.gradle.api.file.DirectoryProperty; @@ -29,6 +31,14 @@ import java.io.File; import java.nio.file.Path; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import static com.google.common.collect.Lists.newArrayList; +import static com.google.common.collect.Maps.newHashMap; +import static io.spine.tools.code.ExternalModule.predefinedModules; +import static java.util.stream.Collectors.toList; /** * DSL extension for configuring Protobuf-to-Dart compilation. @@ -50,6 +60,38 @@ public final class Extension extends GradleExtension { private final DirectoryProperty testDir; private final DirectoryProperty mainGeneratedDir; private final DirectoryProperty testGeneratedDir; + + /** + * Names of JavaScript modules and directories they provide. + * + *

Information about modules is used to resolve imports in generated Protobuf files. + * + *

Additionally to modules specified via the property, + * the {@linkplain ExternalModule#predefinedModules() predefined Spine} modules are used. + * + *

An example of the definition: + *

{@code
+     * modules = [
+     *      // The module provides `company/client` directory (not including subdirectories).
+     *      // So, an import path like {@code ../company/client/file.js}
+     *      // becomes {@code client/company/client/file.js}.
+     *      'client' : ['company/client'],
+     *
+     *      // The module provides `company/server` directory (including subdirectories).
+     *      // So, an import path like {@code ../company/server/nested/file.js}
+     *      // becomes {@code server/company/server/nested/file.js}.
+     *      'server' : ['company/server/*'],
+     *
+     *      // The module provides 'proto/company` directory.
+     *      // So, an import pah like {@code ../company/file.js}
+     *      // becomes {@code common-types/proto/company/file.js}.
+     *      'common-types' : ['proto/company']
+     * ]
+     * }
+ */ + @SuppressWarnings("PublicField" /* Expose fields as a Gradle extension */) + public Map> modules = newHashMap(); + private final Project project; Extension(Project project) { @@ -225,6 +267,17 @@ Path testGeneratedDir() { .toPath(); } + public List modules() { + List modules = newArrayList(); + for (String moduleName : this.modules.keySet()) { + List patterns = patterns(this.modules.get(moduleName)); + ExternalModule module = new ExternalModule(moduleName, patterns); + modules.add(module); + } + modules.addAll(predefinedModules()); + return modules; + } + /** * Finalizes all configurable values. * @@ -245,6 +298,12 @@ private File file(Property property) { return project.file(property.get()); } + private static List patterns(Collection rawPatterns) { + return rawPatterns.stream() + .map(DirectoryPattern::of) + .collect(toList()); + } + @Override protected DefaultDartProject defaultProject(Project project) { return DefaultDartProject.at(project.getProjectDir().toPath()); diff --git a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java index 39e6f6d85f..8b27e5a24a 100644 --- a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java +++ b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java @@ -35,6 +35,7 @@ import static io.spine.tools.gradle.BaseTaskName.assemble; import static io.spine.tools.gradle.ProtoDartTaskName.copyGeneratedDart; import static io.spine.tools.gradle.ProtoDartTaskName.copyTestGeneratedDart; +import static io.spine.tools.gradle.ProtoDartTaskName.resolveImports; import static io.spine.tools.gradle.ProtobufTaskName.generateProto; import static io.spine.tools.gradle.ProtobufTaskName.generateTestProto; import static io.spine.tools.gradle.ProtocPluginName.dart; @@ -62,6 +63,7 @@ public void apply(Project project) { createMainCopyTask(project, extension); createTestCopyTask(project, extension); + createResolveImportTask(project, extension); } private static void createMainCopyTask(Project project, Extension extension) { @@ -94,4 +96,13 @@ private static void createCopyTask(Project project, Extension extension, SourceS .getByName(assemble.name()) .dependsOn(taskName.name()); } + + private void createResolveImportTask(Project project, Extension extension) { + newTask(resolveImports, task -> { + + }) + .insertAfterTask(copyGeneratedDart) + .insertBeforeTask(assemble) + .applyNowTo(project); + } } diff --git a/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/Extension.java b/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/Extension.java index aaccfd2ff8..1a6ef2c6d2 100644 --- a/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/Extension.java +++ b/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/Extension.java @@ -21,12 +21,11 @@ package io.spine.js.gradle; import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; import io.spine.code.fs.DefaultProject; import io.spine.code.fs.js.DefaultJsProject; import io.spine.code.fs.js.Directory; -import io.spine.js.generate.resolve.DirectoryPattern; -import io.spine.js.generate.resolve.ExternalModule; +import io.spine.tools.code.DirectoryPattern; +import io.spine.tools.code.ExternalModule; import io.spine.tools.gradle.GradleExtension; import org.gradle.api.Project; import org.gradle.api.Task; @@ -78,7 +77,7 @@ public class Extension extends GradleExtension { *

Information about modules is used to resolve imports in generated Protobuf files. * *

Additionally to modules specified via the property, - * the {@linkplain #predefinedModules() predefined Spine} modules are used. + * the {@linkplain ExternalModule#predefinedModules() predefined Spine} modules are used. * *

An example of the definition: *

{@code
@@ -144,7 +143,7 @@ public static List modules(Project project) {
             ExternalModule module = new ExternalModule(moduleName, patterns);
             modules.add(module);
         }
-        modules.addAll(predefinedModules());
+        modules.addAll(ExternalModule.predefinedModules());
         return modules;
     }
 
@@ -172,17 +171,6 @@ static Extension extension(Project project) {
                        .getByName(extensionName());
     }
 
-    /**
-     * Obtains the external modules published by Spine.
-     */
-    @VisibleForTesting
-    static List predefinedModules() {
-        return ImmutableList.of(
-                ExternalModule.spineWeb(),
-                ExternalModule.spineUsers()
-        );
-    }
-
     private static List patterns(Collection rawPatterns) {
         return rawPatterns.stream()
                           .map(DirectoryPattern::of)
diff --git a/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ProtoJsPlugin.java b/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ProtoJsPlugin.java
index 87b75ce3ef..e448e83a6b 100644
--- a/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ProtoJsPlugin.java
+++ b/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ProtoJsPlugin.java
@@ -28,8 +28,7 @@
 import io.spine.js.generate.GenerationTask;
 import io.spine.js.generate.index.GenerateIndexFile;
 import io.spine.js.generate.parse.GenerateKnownTypeParsers;
-import io.spine.js.generate.resolve.ExternalModule;
-import io.spine.js.generate.resolve.ResolveImports;
+import io.spine.tools.code.ExternalModule;
 import io.spine.tools.gradle.BaseTaskName;
 import io.spine.tools.gradle.GradleTask;
 import io.spine.tools.gradle.ProtoPlugin;
diff --git a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/ResolveImports.java b/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ResolveImports.java
similarity index 98%
rename from tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/ResolveImports.java
rename to tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ResolveImports.java
index 182e20838e..4d63bb1de2 100644
--- a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/resolve/ResolveImports.java
+++ b/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ResolveImports.java
@@ -18,7 +18,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-package io.spine.js.generate.resolve;
+package io.spine.js.gradle;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Predicate;
@@ -31,6 +31,9 @@
 import io.spine.code.proto.FileSet;
 import io.spine.js.generate.GenerationTask;
 import io.spine.logging.Logging;
+import io.spine.tools.code.ExternalModule;
+import io.spine.tools.code.ImportStatement;
+import io.spine.tools.code.JsFile;
 import org.checkerframework.checker.nullness.qual.Nullable;
 
 import java.nio.file.Path;
diff --git a/tools/proto-js-plugin/src/test/java/io/spine/js/gradle/ExtensionTest.java b/tools/proto-js-plugin/src/test/java/io/spine/js/gradle/ExtensionTest.java
index f4bab09a43..d15c1e9b9d 100644
--- a/tools/proto-js-plugin/src/test/java/io/spine/js/gradle/ExtensionTest.java
+++ b/tools/proto-js-plugin/src/test/java/io/spine/js/gradle/ExtensionTest.java
@@ -22,7 +22,7 @@
 
 import io.spine.code.fs.js.DefaultJsProject;
 import io.spine.code.fs.js.Directory;
-import io.spine.js.generate.resolve.ExternalModule;
+import io.spine.tools.code.ExternalModule;
 import org.gradle.api.Project;
 import org.gradle.api.plugins.PluginManager;
 import org.gradle.testfixtures.ProjectBuilder;
@@ -75,7 +75,8 @@ void defaultMainGenProto() {
         Directory directory = Extension.getMainGenProto(project);
         Directory expected = defaultProject.proto()
                                            .mainJs();
-        assertEquals(expected, directory);
+        assertThat(directory)
+                .isEqualTo(expected);
     }
 
     @Test
@@ -94,7 +95,8 @@ void defaultTestGenProto() {
         Directory directory = Extension.getTestGenProtoDir(project);
         Directory expected = defaultProject.proto()
                                            .testJs();
-        assertEquals(expected, directory);
+        assertThat(directory)
+                .isEqualTo(expected);
     }
 
     @Test
@@ -104,7 +106,8 @@ void customTestGenProto() {
         pluginExtension().testGenProtoDir = customPath;
         Directory directory = Extension.getTestGenProtoDir(project);
         Directory expected = Directory.at(Paths.get(customPath));
-        assertEquals(expected, directory);
+        assertThat(directory)
+                .isEqualTo(expected);
     }
 
     @Test
@@ -117,7 +120,8 @@ void defaultMainDescriptorSet() {
         File expected = mainDescriptors
                 .resolve(GROUP_ID + '_' + project.getName() + '_' + VERSION + ".desc")
                 .toFile();
-        assertEquals(expected, file);
+        assertThat(file)
+                .isEqualTo(expected);
     }
 
     @Test
@@ -127,7 +131,8 @@ void customMainDescriptorSet() {
         pluginExtension().mainDescriptorSetPath = customPath;
         File file = Extension.getMainDescriptorSet(project);
         File expected = new File(customPath);
-        assertEquals(expected, file);
+        assertThat(file)
+                .isEqualTo(expected);
     }
 
     @Test
@@ -140,7 +145,8 @@ void defaultTestDescriptorSet() {
         File expected = testDescriptors
                 .resolve(GROUP_ID + '_' + project.getName() + '_' + VERSION + "_test.desc")
                 .toFile();
-        assertEquals(expected, file);
+        assertThat(file)
+                .isEqualTo(expected);
     }
 
     @Test
@@ -150,14 +156,8 @@ void customTestDescriptorSet() {
         pluginExtension().testDescriptorSetPath = customPath;
         File file = Extension.getTestDescriptorSet(project);
         File expected = new File(customPath);
-        assertEquals(expected, file);
-    }
-
-    @Test
-    @DisplayName("include predefined Spine modules")
-    void includePredefinedModules() {
-        List modules = Extension.modules(project);
-        assertThat(modules).containsAtLeastElementsIn(Extension.predefinedModules());
+        assertThat(file)
+                .isEqualTo(expected);
     }
 
     @Test
@@ -167,8 +167,8 @@ void setModulesToResolve() {
         Map> modulesExt = pluginExtension().modules;
         modulesExt.put(moduleName, emptyList());
         List modules = Extension.modules(project);
-        assertThat(modules).containsAtLeastElementsIn(Extension.predefinedModules());
-        assertThat(modules).contains(new ExternalModule(moduleName, emptyList()));
+        assertThat(modules)
+                .contains(new ExternalModule(moduleName, emptyList()));
     }
 
     private Extension pluginExtension() {
diff --git a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/ResolveImportsTest.java b/tools/proto-js-plugin/src/test/java/io/spine/js/gradle/ResolveImportsTest.java
similarity index 93%
rename from tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/ResolveImportsTest.java
rename to tools/proto-js-plugin/src/test/java/io/spine/js/gradle/ResolveImportsTest.java
index 87f5435e99..923d45c4a6 100644
--- a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/resolve/ResolveImportsTest.java
+++ b/tools/proto-js-plugin/src/test/java/io/spine/js/gradle/ResolveImportsTest.java
@@ -18,12 +18,14 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-package io.spine.js.generate.resolve;
+package io.spine.js.gradle;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.truth.IterableSubject;
 import io.spine.code.fs.js.Directory;
 import io.spine.js.generate.given.GivenProject;
+import io.spine.tools.code.DirectoryPattern;
+import io.spine.tools.code.ExternalModule;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Test;
 
@@ -33,8 +35,8 @@
 import java.util.List;
 
 import static com.google.common.truth.Truth.assertThat;
-import static io.spine.js.generate.resolve.given.Given.newModule;
 import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
 
 @DisplayName("ResolveImports task should")
 class ResolveImportsTest {
@@ -148,4 +150,10 @@ private static IterableSubject afterResolve(Path file, ResolveImports task) thro
     private ResolveImports newTask(ExternalModule module) {
         return new ResolveImports(generatedProtoDir, ImmutableList.of(module));
     }
+
+    private static ExternalModule newModule(String moduleName, String directoryPattern) {
+        DirectoryPattern pattern = DirectoryPattern.of(directoryPattern);
+        List patterns = singletonList(pattern);
+        return new ExternalModule(moduleName, patterns);
+    }
 }

From 30f248d6f74db14fd0747ef25267f93ef70298a5 Mon Sep 17 00:00:00 2001
From: Dmytro Dashenkov 
Date: Wed, 8 Apr 2020 13:24:55 +0300
Subject: [PATCH 02/10] Resolve imports in Dart Protobuf files

---
 license-report.md                             | 30 ++++----
 .../io/spine/tools/code/ExternalModule.java   |  4 +
 .../io/spine/tools/gradle/GradleTask.java     |  2 +-
 .../spine/tools/code/ExternalModuleTest.java  | 10 ++-
 .../io/spine/generate/dart/Extension.java     |  2 -
 .../spine/generate/dart/ProtoDartPlugin.java  | 74 ++++++++++++++++++-
 .../generate/dart/ProtoDartPluginTest.java    | 22 ++++--
 .../js/generate/imports}/ImportStatement.java |  2 +-
 .../io/spine/js/generate/imports}/JsFile.java |  2 +-
 .../imports}/ResolveImports.java              |  4 +-
 .../js/generate/imports}/package-info.java    |  3 +-
 .../java/io/spine/js/gradle/Extension.java    |  3 +-
 .../io/spine/js/gradle/ProtoJsPlugin.java     |  1 +
 .../imports}/ImportStatementTest.java         |  6 +-
 .../js/generate/imports}/JsFileTest.java      |  4 +-
 .../imports}/ResolveImportsTest.java          |  2 +-
 .../js/generate/imports}/given/Given.java     | 24 +-----
 .../generate/imports/given/package-info.java  | 28 +++++++
 18 files changed, 162 insertions(+), 61 deletions(-)
 rename tools/{plugin-base/src/main/java/io/spine/tools/code => proto-js-plugin/src/main/java/io/spine/js/generate/imports}/ImportStatement.java (99%)
 rename tools/{plugin-base/src/main/java/io/spine/tools/code => proto-js-plugin/src/main/java/io/spine/js/generate/imports}/JsFile.java (99%)
 rename tools/proto-js-plugin/src/main/java/io/spine/js/{gradle => generate/imports}/ResolveImports.java (98%)
 rename tools/{plugin-base/src/test/java/io/spine/tools/code/given => proto-js-plugin/src/main/java/io/spine/js/generate/imports}/package-info.java (96%)
 rename tools/{plugin-base/src/test/java/io/spine/tools/code => proto-js-plugin/src/test/java/io/spine/js/generate/imports}/ImportStatementTest.java (93%)
 rename tools/{plugin-base/src/test/java/io/spine/tools/code => proto-js-plugin/src/test/java/io/spine/js/generate/imports}/JsFileTest.java (96%)
 rename tools/proto-js-plugin/src/test/java/io/spine/js/{gradle => generate/imports}/ResolveImportsTest.java (99%)
 rename tools/{plugin-base/src/test/java/io/spine/tools/code => proto-js-plugin/src/test/java/io/spine/js/generate/imports}/given/Given.java (63%)
 create mode 100644 tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/given/package-info.java

diff --git a/license-report.md b/license-report.md
index 1c78e3cc14..6b84c6964b 100644
--- a/license-report.md
+++ b/license-report.md
@@ -330,7 +330,7 @@
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Tue Apr 07 13:45:02 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:22:03 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -777,7 +777,7 @@ This report was generated on **Tue Apr 07 13:45:02 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Tue Apr 07 13:45:03 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:22:04 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -1170,7 +1170,7 @@ This report was generated on **Tue Apr 07 13:45:03 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Tue Apr 07 13:45:04 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:22:05 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -1537,7 +1537,7 @@ This report was generated on **Tue Apr 07 13:45:04 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Tue Apr 07 13:45:05 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:22:05 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -1920,7 +1920,7 @@ This report was generated on **Tue Apr 07 13:45:05 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Tue Apr 07 13:45:05 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:22:06 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -2305,7 +2305,7 @@ This report was generated on **Tue Apr 07 13:45:05 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Tue Apr 07 13:45:06 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:22:06 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -2672,7 +2672,7 @@ This report was generated on **Tue Apr 07 13:45:06 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Tue Apr 07 13:45:06 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:22:07 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -3097,7 +3097,7 @@ This report was generated on **Tue Apr 07 13:45:06 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Tue Apr 07 13:45:07 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:22:07 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -3464,7 +3464,7 @@ This report was generated on **Tue Apr 07 13:45:07 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Tue Apr 07 13:45:07 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:22:08 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -3831,7 +3831,7 @@ This report was generated on **Tue Apr 07 13:45:07 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Tue Apr 07 13:45:07 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:22:08 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -4158,7 +4158,7 @@ This report was generated on **Tue Apr 07 13:45:07 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Tue Apr 07 13:45:08 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:22:09 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -4493,7 +4493,7 @@ This report was generated on **Tue Apr 07 13:45:08 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Tue Apr 07 13:45:08 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:22:09 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -4878,7 +4878,7 @@ This report was generated on **Tue Apr 07 13:45:08 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Tue Apr 07 13:45:09 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:22:09 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -5213,7 +5213,7 @@ This report was generated on **Tue Apr 07 13:45:09 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Tue Apr 07 13:45:09 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:22:10 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -5548,4 +5548,4 @@ This report was generated on **Tue Apr 07 13:45:09 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Tue Apr 07 13:45:09 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
\ No newline at end of file
+This report was generated on **Wed Apr 08 13:22:10 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
\ No newline at end of file
diff --git a/tools/plugin-base/src/main/java/io/spine/tools/code/ExternalModule.java b/tools/plugin-base/src/main/java/io/spine/tools/code/ExternalModule.java
index 8ce1e99c9b..dfc524502e 100644
--- a/tools/plugin-base/src/main/java/io/spine/tools/code/ExternalModule.java
+++ b/tools/plugin-base/src/main/java/io/spine/tools/code/ExternalModule.java
@@ -89,6 +89,10 @@ public boolean provides(FileReference fileReference) {
         return result;
     }
 
+    public String name() {
+        return name;
+    }
+
     private Optional matchingDirectory(FileReference fileReference) {
         DirectoryReference directory = fileReference.directory();
         for (DirectoryPattern pattern : directories) {
diff --git a/tools/plugin-base/src/main/java/io/spine/tools/gradle/GradleTask.java b/tools/plugin-base/src/main/java/io/spine/tools/gradle/GradleTask.java
index 077f525b82..8c9a48da9a 100644
--- a/tools/plugin-base/src/main/java/io/spine/tools/gradle/GradleTask.java
+++ b/tools/plugin-base/src/main/java/io/spine/tools/gradle/GradleTask.java
@@ -296,7 +296,7 @@ private void dependTask(Task task, Project project) {
             }
             if (followingTask != null) {
                 TaskContainer existingTasks = project.getTasks();
-                existingTasks.getByPath(followingTask.name())
+                existingTasks.getByName(followingTask.name())
                              .dependsOn(task);
             }
             if (previousTaskOfAllProjects != null) {
diff --git a/tools/plugin-base/src/test/java/io/spine/tools/code/ExternalModuleTest.java b/tools/plugin-base/src/test/java/io/spine/tools/code/ExternalModuleTest.java
index d337e88eea..ff4d48c028 100644
--- a/tools/plugin-base/src/test/java/io/spine/tools/code/ExternalModuleTest.java
+++ b/tools/plugin-base/src/test/java/io/spine/tools/code/ExternalModuleTest.java
@@ -25,8 +25,10 @@
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Test;
 
-import static io.spine.tools.code.given.Given.newModule;
+import java.util.List;
+
 import static java.util.Collections.emptySet;
+import static java.util.Collections.singletonList;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
@@ -104,4 +106,10 @@ void acceptOnlyProvidedProto() {
                 () -> module.fileInModule(reference)
         );
     }
+
+    private static ExternalModule newModule(String moduleName, String directoryPattern) {
+        DirectoryPattern pattern = DirectoryPattern.of(directoryPattern);
+        List patterns = singletonList(pattern);
+        return new ExternalModule(moduleName, patterns);
+    }
 }
diff --git a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/Extension.java b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/Extension.java
index 7175142e3b..1aa690aa5f 100644
--- a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/Extension.java
+++ b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/Extension.java
@@ -37,7 +37,6 @@
 
 import static com.google.common.collect.Lists.newArrayList;
 import static com.google.common.collect.Maps.newHashMap;
-import static io.spine.tools.code.ExternalModule.predefinedModules;
 import static java.util.stream.Collectors.toList;
 
 /**
@@ -274,7 +273,6 @@ public List modules() {
             ExternalModule module = new ExternalModule(moduleName, patterns);
             modules.add(module);
         }
-        modules.addAll(predefinedModules());
         return modules;
     }
 
diff --git a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java
index 8b27e5a24a..5d1bfe60d4 100644
--- a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java
+++ b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java
@@ -21,16 +21,26 @@
 package io.spine.generate.dart;
 
 import com.google.common.collect.ImmutableMap;
+import io.spine.code.fs.js.FileReference;
+import io.spine.tools.code.ExternalModule;
 import io.spine.tools.gradle.ProtoDartTaskName;
 import io.spine.tools.gradle.SourceScope;
 import io.spine.tools.gradle.SpinePlugin;
 import io.spine.tools.gradle.TaskName;
+import org.gradle.api.GradleException;
 import org.gradle.api.Plugin;
 import org.gradle.api.Project;
 import org.gradle.api.file.DirectoryProperty;
+import org.gradle.api.file.FileTree;
 import org.gradle.api.tasks.Copy;
 
 import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import static io.spine.tools.gradle.BaseTaskName.assemble;
 import static io.spine.tools.gradle.ProtoDartTaskName.copyGeneratedDart;
@@ -41,6 +51,9 @@
 import static io.spine.tools.gradle.ProtocPluginName.dart;
 import static io.spine.tools.gradle.SourceScope.main;
 import static io.spine.tools.gradle.SourceScope.test;
+import static java.lang.String.format;
+import static java.nio.file.Files.readAllLines;
+import static java.nio.file.Files.write;
 import static org.gradle.api.Task.TASK_TYPE;
 
 /**
@@ -99,10 +112,69 @@ private static void createCopyTask(Project project, Extension extension, SourceS
 
     private void createResolveImportTask(Project project, Extension extension) {
         newTask(resolveImports, task -> {
-
+            FileTree generatedDir = extension.getMainGeneratedDir()
+                                             .getAsFileTree();
+            generatedDir.forEach(file -> resolveImports(file, extension));
         })
                 .insertAfterTask(copyGeneratedDart)
                 .insertBeforeTask(assemble)
                 .applyNowTo(project);
     }
+
+    private void resolveImports(File sourceFile, Extension extension) {
+        if (!isPbDartFile(sourceFile)) {
+            return;
+        }
+        List lines;
+        Path asPath = sourceFile.toPath();
+        try {
+            lines = readAllLines(asPath);
+        } catch (IOException e) {
+            throw new GradleException(format("Unable to read file `%s`.", sourceFile), e);
+        }
+        List modules = extension.modules();
+        Pattern importPattern = Pattern.compile("import \"(.+)\" as (.+);");
+        List resultLines = new ArrayList<>(lines.size());
+        for (String line : lines) {
+            Matcher matcher = importPattern.matcher(line);
+            if (matcher.find()) {
+                String path = matcher.group(1);
+                Path absolutePath = asPath.resolve(path)
+                                          .normalize();
+                Path libPath = extension.getLibDir()
+                                        .getAsFile()
+                                        .map(File::toPath)
+                                        .get();
+                Path relativeImport = libPath.relativize(absolutePath);
+                FileReference reference = FileReference.of(relativeImport.toString());
+                for (ExternalModule module : modules) {
+                    if (module.provides(reference)) {
+                        String importStatement = format("import \"package:%s/%s\" as %s;",
+                                                        module.name(),
+                                                        relativeImport,
+                                                        matcher.group(2));
+                        resultLines.add(importStatement);
+                    }
+                }
+            } else {
+                resultLines.add(line);
+            }
+        }
+        try {
+            write(asPath, resultLines);
+        } catch (IOException e) {
+            throw new GradleException(format("Unable to write file `%s`.", sourceFile), e);
+        }
+    }
+
+    private static boolean isPbDartFile(File file) {
+        if (!file.isFile()) {
+            return false;
+        }
+        String name = file.getName();
+        return name.endsWith(".pb.dart")
+                || name.endsWith(".pbenum.dart")
+                || name.endsWith(".pbservice.dart")
+                || name.endsWith(".pbjson.dart");
+    }
 }
diff --git a/tools/proto-dart-plugin/src/test/java/io/spine/generate/dart/ProtoDartPluginTest.java b/tools/proto-dart-plugin/src/test/java/io/spine/generate/dart/ProtoDartPluginTest.java
index cb1828358d..ce2a7c2e9e 100644
--- a/tools/proto-dart-plugin/src/test/java/io/spine/generate/dart/ProtoDartPluginTest.java
+++ b/tools/proto-dart-plugin/src/test/java/io/spine/generate/dart/ProtoDartPluginTest.java
@@ -20,6 +20,7 @@
 
 package io.spine.generate.dart;
 
+import com.google.errorprone.annotations.CanIgnoreReturnValue;
 import io.spine.tools.gradle.TaskName;
 import org.gradle.api.Project;
 import org.gradle.api.Task;
@@ -35,6 +36,7 @@
 import static io.spine.tools.gradle.BaseTaskName.assemble;
 import static io.spine.tools.gradle.ProtoDartTaskName.copyGeneratedDart;
 import static io.spine.tools.gradle.ProtoDartTaskName.copyTestGeneratedDart;
+import static io.spine.tools.gradle.ProtoDartTaskName.resolveImports;
 
 @DisplayName("`ProtoDartPlugin` should")
 class ProtoDartPluginTest {
@@ -57,10 +59,10 @@ void createMainTask() {
         ProtoDartPlugin plugin = new ProtoDartPlugin();
         plugin.apply(project);
 
-        Task task = task(copyGeneratedDart);
+        Task task = findTask(copyGeneratedDart);
         assertThat(task.getDependsOn()).isNotEmpty();
 
-        Task assembleTask = task(assemble);
+        Task assembleTask = findTask(assemble);
         assertThat(assembleTask.getDependsOn()).contains(task.getName());
     }
 
@@ -70,14 +72,24 @@ void createTestTask() {
         ProtoDartPlugin plugin = new ProtoDartPlugin();
         plugin.apply(project);
 
-        Task task = task(copyTestGeneratedDart);
+        Task task = findTask(copyTestGeneratedDart);
         assertThat(task.getDependsOn()).isNotEmpty();
 
-        Task assembleTask = task(assemble);
+        Task assembleTask = findTask(assemble);
         assertThat(assembleTask.getDependsOn()).contains(task.getName());
     }
 
-    private Task task(TaskName name) {
+    @Test
+    @DisplayName("create `resolveImports` task")
+    void createResolveTask() {
+        ProtoDartPlugin plugin = new ProtoDartPlugin();
+        plugin.apply(project);
+
+        findTask(resolveImports);
+    }
+
+    @CanIgnoreReturnValue
+    private Task findTask(TaskName name) {
         Task task = project.getTasks()
                            .findByName(name.name());
         assertThat(task).isNotNull();
diff --git a/tools/plugin-base/src/main/java/io/spine/tools/code/ImportStatement.java b/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/ImportStatement.java
similarity index 99%
rename from tools/plugin-base/src/main/java/io/spine/tools/code/ImportStatement.java
rename to tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/ImportStatement.java
index edfd18fcc4..c4af377f2f 100644
--- a/tools/plugin-base/src/main/java/io/spine/tools/code/ImportStatement.java
+++ b/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/ImportStatement.java
@@ -18,7 +18,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-package io.spine.tools.code;
+package io.spine.js.generate.imports;
 
 import io.spine.code.fs.js.FileReference;
 import io.spine.logging.Logging;
diff --git a/tools/plugin-base/src/main/java/io/spine/tools/code/JsFile.java b/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/JsFile.java
similarity index 99%
rename from tools/plugin-base/src/main/java/io/spine/tools/code/JsFile.java
rename to tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/JsFile.java
index dfd3f6c8a6..20b7fb5f8c 100644
--- a/tools/plugin-base/src/main/java/io/spine/tools/code/JsFile.java
+++ b/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/JsFile.java
@@ -18,7 +18,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-package io.spine.tools.code;
+package io.spine.js.generate.imports;
 
 import com.google.common.base.Charsets;
 
diff --git a/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ResolveImports.java b/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/ResolveImports.java
similarity index 98%
rename from tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ResolveImports.java
rename to tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/ResolveImports.java
index 4d63bb1de2..2c1a718e08 100644
--- a/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ResolveImports.java
+++ b/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/ResolveImports.java
@@ -18,7 +18,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-package io.spine.js.gradle;
+package io.spine.js.generate.imports;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Predicate;
@@ -32,8 +32,6 @@
 import io.spine.js.generate.GenerationTask;
 import io.spine.logging.Logging;
 import io.spine.tools.code.ExternalModule;
-import io.spine.tools.code.ImportStatement;
-import io.spine.tools.code.JsFile;
 import org.checkerframework.checker.nullness.qual.Nullable;
 
 import java.nio.file.Path;
diff --git a/tools/plugin-base/src/test/java/io/spine/tools/code/given/package-info.java b/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/package-info.java
similarity index 96%
rename from tools/plugin-base/src/test/java/io/spine/tools/code/given/package-info.java
rename to tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/package-info.java
index fdce3cb515..bebe6ac936 100644
--- a/tools/plugin-base/src/test/java/io/spine/tools/code/given/package-info.java
+++ b/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/package-info.java
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2020, TeamDev. All rights reserved.
  *
@@ -21,7 +20,7 @@
 
 @CheckReturnValue
 @ParametersAreNonnullByDefault
-package io.spine.tools.code.given;
+package io.spine.js.generate.imports;
 
 import com.google.errorprone.annotations.CheckReturnValue;
 
diff --git a/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/Extension.java b/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/Extension.java
index 1a6ef2c6d2..ff52b94d34 100644
--- a/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/Extension.java
+++ b/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/Extension.java
@@ -42,6 +42,7 @@
 import static com.google.common.collect.Lists.newArrayList;
 import static com.google.common.collect.Maps.newHashMap;
 import static io.spine.js.gradle.ProtoJsPlugin.extensionName;
+import static io.spine.tools.code.ExternalModule.predefinedModules;
 import static java.util.stream.Collectors.toList;
 
 /**
@@ -143,7 +144,7 @@ public static List modules(Project project) {
             ExternalModule module = new ExternalModule(moduleName, patterns);
             modules.add(module);
         }
-        modules.addAll(ExternalModule.predefinedModules());
+        modules.addAll(predefinedModules());
         return modules;
     }
 
diff --git a/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ProtoJsPlugin.java b/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ProtoJsPlugin.java
index e448e83a6b..24eff2fbb5 100644
--- a/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ProtoJsPlugin.java
+++ b/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ProtoJsPlugin.java
@@ -26,6 +26,7 @@
 import io.spine.code.proto.FileSet;
 import io.spine.js.generate.AppendTypeUrlGetter;
 import io.spine.js.generate.GenerationTask;
+import io.spine.js.generate.imports.ResolveImports;
 import io.spine.js.generate.index.GenerateIndexFile;
 import io.spine.js.generate.parse.GenerateKnownTypeParsers;
 import io.spine.tools.code.ExternalModule;
diff --git a/tools/plugin-base/src/test/java/io/spine/tools/code/ImportStatementTest.java b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ImportStatementTest.java
similarity index 93%
rename from tools/plugin-base/src/test/java/io/spine/tools/code/ImportStatementTest.java
rename to tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ImportStatementTest.java
index 9d7d97907f..81c8b88e92 100644
--- a/tools/plugin-base/src/test/java/io/spine/tools/code/ImportStatementTest.java
+++ b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ImportStatementTest.java
@@ -18,7 +18,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-package io.spine.tools.code;
+package io.spine.js.generate.imports;
 
 import io.spine.code.fs.js.FileReference;
 import org.junit.jupiter.api.DisplayName;
@@ -29,8 +29,8 @@
 import java.nio.file.Paths;
 
 import static com.google.common.truth.Truth.assertThat;
-import static io.spine.tools.code.given.Given.importWithPath;
-import static io.spine.tools.code.given.Given.relativeImportPath;
+import static io.spine.js.generate.imports.given.Given.importWithPath;
+import static io.spine.js.generate.imports.given.Given.relativeImportPath;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
 @DisplayName("ImportStatement should")
diff --git a/tools/plugin-base/src/test/java/io/spine/tools/code/JsFileTest.java b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/JsFileTest.java
similarity index 96%
rename from tools/plugin-base/src/test/java/io/spine/tools/code/JsFileTest.java
rename to tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/JsFileTest.java
index 859e8e1955..738cc77346 100644
--- a/tools/plugin-base/src/test/java/io/spine/tools/code/JsFileTest.java
+++ b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/JsFileTest.java
@@ -18,7 +18,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-package io.spine.tools.code;
+package io.spine.js.generate.imports;
 
 import com.google.common.collect.ImmutableList;
 import org.junit.jupiter.api.BeforeEach;
@@ -35,7 +35,7 @@
 import java.util.List;
 
 import static com.google.common.truth.Truth.assertThat;
-import static io.spine.tools.code.given.Given.importWithPath;
+import static io.spine.js.generate.imports.given.Given.importWithPath;
 
 @ExtendWith(TempDirectory.class)
 @DisplayName("JavaScript file should")
diff --git a/tools/proto-js-plugin/src/test/java/io/spine/js/gradle/ResolveImportsTest.java b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ResolveImportsTest.java
similarity index 99%
rename from tools/proto-js-plugin/src/test/java/io/spine/js/gradle/ResolveImportsTest.java
rename to tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ResolveImportsTest.java
index 923d45c4a6..24a87b10fb 100644
--- a/tools/proto-js-plugin/src/test/java/io/spine/js/gradle/ResolveImportsTest.java
+++ b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ResolveImportsTest.java
@@ -18,7 +18,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-package io.spine.js.gradle;
+package io.spine.js.generate.imports;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.truth.IterableSubject;
diff --git a/tools/plugin-base/src/test/java/io/spine/tools/code/given/Given.java b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/given/Given.java
similarity index 63%
rename from tools/plugin-base/src/test/java/io/spine/tools/code/given/Given.java
rename to tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/given/Given.java
index 5c6a67b748..6441e6337e 100644
--- a/tools/plugin-base/src/test/java/io/spine/tools/code/given/Given.java
+++ b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/given/Given.java
@@ -18,20 +18,13 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-package io.spine.tools.code.given;
+package io.spine.js.generate.imports.given;
 
-import io.spine.code.fs.js.Directory;
-import io.spine.tools.code.DirectoryPattern;
-import io.spine.tools.code.ExternalModule;
-import io.spine.tools.code.ImportStatement;
+import io.spine.js.generate.imports.ImportStatement;
 
 import java.io.File;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.List;
 
 import static java.lang.String.format;
-import static java.util.Collections.singletonList;
 
 public class Given {
 
@@ -47,17 +40,4 @@ public static ImportStatement importWithPath(String path, File importOrigin) {
     public static String relativeImportPath() {
         return "../path-relative-to-parent.js";
     }
-
-    private static Directory protoRoot(String sourceSetName) {
-        Path path = Paths.get("src")
-                         .resolve(sourceSetName)
-                         .resolve("proto");
-        return Directory.at(path.toAbsolutePath());
-    }
-
-    public static ExternalModule newModule(String moduleName, String directoryPattern) {
-        DirectoryPattern pattern = DirectoryPattern.of(directoryPattern);
-        List patterns = singletonList(pattern);
-        return new ExternalModule(moduleName, patterns);
-    }
 }
diff --git a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/given/package-info.java b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/given/package-info.java
new file mode 100644
index 0000000000..f28c85e449
--- /dev/null
+++ b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/given/package-info.java
@@ -0,0 +1,28 @@
+
+/*
+ * Copyright 2020, TeamDev. All rights reserved.
+ *
+ * Redistribution and use in source and/or binary forms, with or without
+ * modification, must retain the above copyright notice and the following
+ * disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+@CheckReturnValue
+@ParametersAreNonnullByDefault
+package io.spine.js.generate.imports.given;
+
+import com.google.errorprone.annotations.CheckReturnValue;
+
+import javax.annotation.ParametersAreNonnullByDefault;

From c7a4c23949f4909b52ee171e5259e0cfb176fa53 Mon Sep 17 00:00:00 2001
From: Dmytro Dashenkov 
Date: Wed, 8 Apr 2020 14:50:04 +0300
Subject: [PATCH 03/10] Fix extension

---
 .../src/main/java/io/spine/generate/dart/ProtoDartPlugin.java   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java
index 5d1bfe60d4..75b33e951f 100644
--- a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java
+++ b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java
@@ -174,7 +174,7 @@ private static boolean isPbDartFile(File file) {
         String name = file.getName();
         return name.endsWith(".pb.dart")
                 || name.endsWith(".pbenum.dart")
-                || name.endsWith(".pbservice.dart")
+                || name.endsWith(".pbserver.dart")
                 || name.endsWith(".pbjson.dart");
     }
 }

From 5ca45a2df4bfcfbd6cdfbae44b0ebc36013d93bb Mon Sep 17 00:00:00 2001
From: Dmytro Dashenkov 
Date: Wed, 8 Apr 2020 14:50:22 +0300
Subject: [PATCH 04/10] Bump version to 1.5.5

---
 license-report.md | 60 +++++++++++++++++++++++------------------------
 pom.xml           |  4 ++--
 version.gradle    |  2 +-
 3 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/license-report.md b/license-report.md
index 6b84c6964b..dd632d0fa2 100644
--- a/license-report.md
+++ b/license-report.md
@@ -1,6 +1,6 @@
 
     
-# Dependencies of `io.spine:spine-base:1.5.4`
+# Dependencies of `io.spine:spine-base:1.5.5`
 
 ## Runtime
 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2
@@ -330,12 +330,12 @@
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:22:03 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:32:45 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
     
-# Dependencies of `io.spine.tools:spine-errorprone-checks:1.5.4`
+# Dependencies of `io.spine.tools:spine-errorprone-checks:1.5.5`
 
 ## Runtime
 1. **Group:** com.github.ben-manes.caffeine **Name:** caffeine **Version:** 2.7.0
@@ -777,12 +777,12 @@ This report was generated on **Wed Apr 08 13:22:03 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:22:04 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:32:46 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
     
-# Dependencies of `io.spine.tools:spine-javadoc-filter:1.5.4`
+# Dependencies of `io.spine.tools:spine-javadoc-filter:1.5.5`
 
 ## Runtime
 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
@@ -1170,12 +1170,12 @@ This report was generated on **Wed Apr 08 13:22:04 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:22:05 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:32:47 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
     
-# Dependencies of `io.spine.tools:spine-javadoc-prettifier:1.5.4`
+# Dependencies of `io.spine.tools:spine-javadoc-prettifier:1.5.5`
 
 ## Runtime
 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2
@@ -1537,12 +1537,12 @@ This report was generated on **Wed Apr 08 13:22:05 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:22:05 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:32:47 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
     
-# Dependencies of `io.spine.tools:spine-model-compiler:1.5.4`
+# Dependencies of `io.spine.tools:spine-model-compiler:1.5.5`
 
 ## Runtime
 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2
@@ -1920,12 +1920,12 @@ This report was generated on **Wed Apr 08 13:22:05 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:22:06 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:32:48 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
     
-# Dependencies of `io.spine.tools:spine-mute-logging:1.5.4`
+# Dependencies of `io.spine.tools:spine-mute-logging:1.5.5`
 
 ## Runtime
 1. **Group:** com.google.auto.value **Name:** auto-value-annotations **Version:** 1.6.3
@@ -2305,12 +2305,12 @@ This report was generated on **Wed Apr 08 13:22:06 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:22:06 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:32:48 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
     
-# Dependencies of `io.spine.tools:spine-plugin-base:1.5.4`
+# Dependencies of `io.spine.tools:spine-plugin-base:1.5.5`
 
 ## Runtime
 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2
@@ -2672,12 +2672,12 @@ This report was generated on **Wed Apr 08 13:22:06 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:22:07 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:32:49 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
     
-# Dependencies of `io.spine.tools:spine-plugin-testlib:1.5.4`
+# Dependencies of `io.spine.tools:spine-plugin-testlib:1.5.5`
 
 ## Runtime
 1. **Group:** com.google.auto.value **Name:** auto-value-annotations **Version:** 1.6.3
@@ -3097,12 +3097,12 @@ This report was generated on **Wed Apr 08 13:22:07 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:22:07 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:32:49 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
     
-# Dependencies of `io.spine.tools:spine-proto-dart-plugin:1.5.4`
+# Dependencies of `io.spine.tools:spine-proto-dart-plugin:1.5.5`
 
 ## Runtime
 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2
@@ -3464,12 +3464,12 @@ This report was generated on **Wed Apr 08 13:22:07 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:22:08 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:32:50 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
     
-# Dependencies of `io.spine.tools:spine-proto-js-plugin:1.5.4`
+# Dependencies of `io.spine.tools:spine-proto-js-plugin:1.5.5`
 
 ## Runtime
 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2
@@ -3831,12 +3831,12 @@ This report was generated on **Wed Apr 08 13:22:08 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:22:08 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:32:50 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
     
-# Dependencies of `io.spine.tools:spine-protoc-api:1.5.4`
+# Dependencies of `io.spine.tools:spine-protoc-api:1.5.5`
 
 ## Runtime
 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2
@@ -4158,12 +4158,12 @@ This report was generated on **Wed Apr 08 13:22:08 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:22:09 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:32:51 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
     
-# Dependencies of `io.spine.tools:spine-protoc-plugin:1.5.4`
+# Dependencies of `io.spine.tools:spine-protoc-plugin:1.5.5`
 
 ## Runtime
 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2
@@ -4493,12 +4493,12 @@ This report was generated on **Wed Apr 08 13:22:09 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:22:09 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:32:51 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
     
-# Dependencies of `io.spine:spine-testlib:1.5.4`
+# Dependencies of `io.spine:spine-testlib:1.5.5`
 
 ## Runtime
 1. **Group:** com.google.auto.value **Name:** auto-value-annotations **Version:** 1.6.3
@@ -4878,12 +4878,12 @@ This report was generated on **Wed Apr 08 13:22:09 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:22:09 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:32:52 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
     
-# Dependencies of `io.spine.tools:spine-tool-base:1.5.4`
+# Dependencies of `io.spine.tools:spine-tool-base:1.5.5`
 
 ## Runtime
 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2
@@ -5213,12 +5213,12 @@ This report was generated on **Wed Apr 08 13:22:09 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:22:10 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 13:32:52 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
     
-# Dependencies of `io.spine.tools:spine-validation-generator:1.5.4`
+# Dependencies of `io.spine.tools:spine-validation-generator:1.5.5`
 
 ## Runtime
 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2
@@ -5548,4 +5548,4 @@ This report was generated on **Wed Apr 08 13:22:10 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:22:10 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
\ No newline at end of file
+This report was generated on **Wed Apr 08 13:32:53 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index a53084ee50..506ec3a047 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,7 +12,7 @@ all modules and does not describe the project structure per-subproject.
 
 io.spine
 spine-base
-1.5.4
+1.5.5
 
 2015
 
@@ -154,7 +154,7 @@ all modules and does not describe the project structure per-subproject.
   
     io.spine.tools
     spine-protoc-plugin
-    1.5.4
+    1.5.5
     test
   
   
diff --git a/version.gradle b/version.gradle
index 8d3d59d0b5..7add5bdb18 100644
--- a/version.gradle
+++ b/version.gradle
@@ -25,7 +25,7 @@
  * as we want to manage the versions in a single source.
  */
 
-final def SPINE_VERSION = '1.5.4'
+final def SPINE_VERSION = '1.5.5'
 
 ext {
     spineVersion = SPINE_VERSION

From 95194feef1a00e041bb69afb7ad3f2c136879160 Mon Sep 17 00:00:00 2001
From: Dmytro Dashenkov 
Date: Wed, 8 Apr 2020 16:26:18 +0300
Subject: [PATCH 05/10] Fix pattern and add logging

---
 .../spine/generate/dart/ProtoDartPlugin.java   | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java
index 75b33e951f..9c187d27d1 100644
--- a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java
+++ b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java
@@ -125,6 +125,7 @@ private void resolveImports(File sourceFile, Extension extension) {
         if (!isPbDartFile(sourceFile)) {
             return;
         }
+        _debug().log("Resolving imports in file %s", sourceFile);
         List lines;
         Path asPath = sourceFile.toPath();
         try {
@@ -133,29 +134,40 @@ private void resolveImports(File sourceFile, Extension extension) {
             throw new GradleException(format("Unable to read file `%s`.", sourceFile), e);
         }
         List modules = extension.modules();
-        Pattern importPattern = Pattern.compile("import \"(.+)\" as (.+);");
+        Pattern importPattern = Pattern.compile("import [\"']([^:]+)[\"'] as (.+);");
         List resultLines = new ArrayList<>(lines.size());
         for (String line : lines) {
             Matcher matcher = importPattern.matcher(line);
             if (matcher.find()) {
+                _debug().log("Import found: `%s`", line);
                 String path = matcher.group(1);
-                Path absolutePath = asPath.resolve(path)
+                Path absolutePath = asPath.getParent()
+                                          .resolve(path)
                                           .normalize();
+                _debug().log("Resolved against this file: `%s`", absolutePath);
                 Path libPath = extension.getLibDir()
                                         .getAsFile()
                                         .map(File::toPath)
                                         .get();
                 Path relativeImport = libPath.relativize(absolutePath);
+                _debug().log("Relative: `%s`", relativeImport);
                 FileReference reference = FileReference.of(relativeImport.toString());
+                boolean match = false;
                 for (ExternalModule module : modules) {
                     if (module.provides(reference)) {
-                        String importStatement = format("import \"package:%s/%s\" as %s;",
+                        String importStatement = format("import 'package:%s/%s' as %s;",
                                                         module.name(),
                                                         relativeImport,
                                                         matcher.group(2));
                         resultLines.add(importStatement);
+                        match = true;
+                        _debug().log("Replacing with %s", importStatement);
+                        break;
                     }
                 }
+                if (!match) {
+                    resultLines.add(line);
+                }
             } else {
                 resultLines.add(line);
             }

From 2f9f91a1637750a99706ab70929cd282d1974d0f Mon Sep 17 00:00:00 2001
From: Dmytro Dashenkov 
Date: Wed, 8 Apr 2020 17:32:45 +0300
Subject: [PATCH 06/10] Extract Import logic

---
 license-report.md                             |  30 ++---
 .../io/spine/generate/dart/Extension.java     |   8 +-
 .../spine/generate/dart/ProtoDartPlugin.java  |  84 ++-----------
 .../io/spine/generate/dart/SourceFile.java    | 119 ++++++++++++++++++
 4 files changed, 148 insertions(+), 93 deletions(-)
 create mode 100644 tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/SourceFile.java

diff --git a/license-report.md b/license-report.md
index dd632d0fa2..74193d05bb 100644
--- a/license-report.md
+++ b/license-report.md
@@ -330,7 +330,7 @@
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:32:45 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 17:20:53 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -777,7 +777,7 @@ This report was generated on **Wed Apr 08 13:32:45 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:32:46 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 17:20:54 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -1170,7 +1170,7 @@ This report was generated on **Wed Apr 08 13:32:46 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:32:47 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 17:20:55 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -1537,7 +1537,7 @@ This report was generated on **Wed Apr 08 13:32:47 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:32:47 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 17:20:55 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -1920,7 +1920,7 @@ This report was generated on **Wed Apr 08 13:32:47 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:32:48 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 17:20:56 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -2305,7 +2305,7 @@ This report was generated on **Wed Apr 08 13:32:48 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:32:48 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 17:20:57 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -2672,7 +2672,7 @@ This report was generated on **Wed Apr 08 13:32:48 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:32:49 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 17:20:58 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -3097,7 +3097,7 @@ This report was generated on **Wed Apr 08 13:32:49 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:32:49 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 17:20:58 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -3464,7 +3464,7 @@ This report was generated on **Wed Apr 08 13:32:49 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:32:50 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 17:20:59 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -3831,7 +3831,7 @@ This report was generated on **Wed Apr 08 13:32:50 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:32:50 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 17:21:00 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -4158,7 +4158,7 @@ This report was generated on **Wed Apr 08 13:32:50 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:32:51 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 17:21:00 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -4493,7 +4493,7 @@ This report was generated on **Wed Apr 08 13:32:51 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:32:51 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 17:21:01 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -4878,7 +4878,7 @@ This report was generated on **Wed Apr 08 13:32:51 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:32:52 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 17:21:01 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -5213,7 +5213,7 @@ This report was generated on **Wed Apr 08 13:32:52 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:32:52 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Wed Apr 08 17:21:02 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
 
 
 
@@ -5548,4 +5548,4 @@ This report was generated on **Wed Apr 08 13:32:52 EEST 2020** using [Gradle-Lic
  The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
 
 
-This report was generated on **Wed Apr 08 13:32:53 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
\ No newline at end of file
+This report was generated on **Wed Apr 08 17:21:02 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
\ No newline at end of file
diff --git a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/Extension.java b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/Extension.java
index 1aa690aa5f..2fcb9d0a4c 100644
--- a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/Extension.java
+++ b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/Extension.java
@@ -20,6 +20,7 @@
 
 package io.spine.generate.dart;
 
+import com.google.common.collect.ImmutableList;
 import io.spine.code.fs.dart.DefaultDartProject;
 import io.spine.tools.code.DirectoryPattern;
 import io.spine.tools.code.ExternalModule;
@@ -35,7 +36,6 @@
 import java.util.List;
 import java.util.Map;
 
-import static com.google.common.collect.Lists.newArrayList;
 import static com.google.common.collect.Maps.newHashMap;
 import static java.util.stream.Collectors.toList;
 
@@ -266,14 +266,14 @@ Path testGeneratedDir() {
                                     .toPath();
     }
 
-    public List modules() {
-        List modules = newArrayList();
+    ImmutableList modules() {
+        ImmutableList.Builder modules = ImmutableList.builder();
         for (String moduleName : this.modules.keySet()) {
             List patterns = patterns(this.modules.get(moduleName));
             ExternalModule module = new ExternalModule(moduleName, patterns);
             modules.add(module);
         }
-        return modules;
+        return modules.build();
     }
 
     /**
diff --git a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java
index 9c187d27d1..31441f9884 100644
--- a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java
+++ b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/ProtoDartPlugin.java
@@ -21,13 +21,10 @@
 package io.spine.generate.dart;
 
 import com.google.common.collect.ImmutableMap;
-import io.spine.code.fs.js.FileReference;
-import io.spine.tools.code.ExternalModule;
 import io.spine.tools.gradle.ProtoDartTaskName;
 import io.spine.tools.gradle.SourceScope;
 import io.spine.tools.gradle.SpinePlugin;
 import io.spine.tools.gradle.TaskName;
-import org.gradle.api.GradleException;
 import org.gradle.api.Plugin;
 import org.gradle.api.Project;
 import org.gradle.api.file.DirectoryProperty;
@@ -35,13 +32,9 @@
 import org.gradle.api.tasks.Copy;
 
 import java.io.File;
-import java.io.IOException;
 import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
+import static io.spine.generate.dart.SourceFile.isGeneratedDart;
 import static io.spine.tools.gradle.BaseTaskName.assemble;
 import static io.spine.tools.gradle.ProtoDartTaskName.copyGeneratedDart;
 import static io.spine.tools.gradle.ProtoDartTaskName.copyTestGeneratedDart;
@@ -51,9 +44,6 @@
 import static io.spine.tools.gradle.ProtocPluginName.dart;
 import static io.spine.tools.gradle.SourceScope.main;
 import static io.spine.tools.gradle.SourceScope.test;
-import static java.lang.String.format;
-import static java.nio.file.Files.readAllLines;
-import static java.nio.file.Files.write;
 import static org.gradle.api.Task.TASK_TYPE;
 
 /**
@@ -122,71 +112,17 @@ private void createResolveImportTask(Project project, Extension extension) {
     }
 
     private void resolveImports(File sourceFile, Extension extension) {
-        if (!isPbDartFile(sourceFile)) {
+        Path asPath = sourceFile.toPath();
+        if (!isGeneratedDart(asPath)) {
             return;
         }
         _debug().log("Resolving imports in file %s", sourceFile);
-        List lines;
-        Path asPath = sourceFile.toPath();
-        try {
-            lines = readAllLines(asPath);
-        } catch (IOException e) {
-            throw new GradleException(format("Unable to read file `%s`.", sourceFile), e);
-        }
-        List modules = extension.modules();
-        Pattern importPattern = Pattern.compile("import [\"']([^:]+)[\"'] as (.+);");
-        List resultLines = new ArrayList<>(lines.size());
-        for (String line : lines) {
-            Matcher matcher = importPattern.matcher(line);
-            if (matcher.find()) {
-                _debug().log("Import found: `%s`", line);
-                String path = matcher.group(1);
-                Path absolutePath = asPath.getParent()
-                                          .resolve(path)
-                                          .normalize();
-                _debug().log("Resolved against this file: `%s`", absolutePath);
-                Path libPath = extension.getLibDir()
-                                        .getAsFile()
-                                        .map(File::toPath)
-                                        .get();
-                Path relativeImport = libPath.relativize(absolutePath);
-                _debug().log("Relative: `%s`", relativeImport);
-                FileReference reference = FileReference.of(relativeImport.toString());
-                boolean match = false;
-                for (ExternalModule module : modules) {
-                    if (module.provides(reference)) {
-                        String importStatement = format("import 'package:%s/%s' as %s;",
-                                                        module.name(),
-                                                        relativeImport,
-                                                        matcher.group(2));
-                        resultLines.add(importStatement);
-                        match = true;
-                        _debug().log("Replacing with %s", importStatement);
-                        break;
-                    }
-                }
-                if (!match) {
-                    resultLines.add(line);
-                }
-            } else {
-                resultLines.add(line);
-            }
-        }
-        try {
-            write(asPath, resultLines);
-        } catch (IOException e) {
-            throw new GradleException(format("Unable to write file `%s`.", sourceFile), e);
-        }
-    }
-
-    private static boolean isPbDartFile(File file) {
-        if (!file.isFile()) {
-            return false;
-        }
-        String name = file.getName();
-        return name.endsWith(".pb.dart")
-                || name.endsWith(".pbenum.dart")
-                || name.endsWith(".pbserver.dart")
-                || name.endsWith(".pbjson.dart");
+        SourceFile file = SourceFile.read(sourceFile.toPath());
+        Path libPath = extension.getLibDir()
+                                .getAsFile()
+                                .map(File::toPath)
+                                .get();
+        file.resolveImports(extension.modules(), libPath);
+        file.store();
     }
 }
diff --git a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/SourceFile.java b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/SourceFile.java
new file mode 100644
index 0000000000..3c537102df
--- /dev/null
+++ b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/SourceFile.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2020, TeamDev. All rights reserved.
+ *
+ * Redistribution and use in source and/or binary forms, with or without
+ * modification, must retain the above copyright notice and the following
+ * disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.spine.generate.dart;
+
+import com.google.common.collect.ImmutableList;
+import io.spine.code.AbstractSourceFile;
+import io.spine.code.fs.js.FileReference;
+import io.spine.logging.Logging;
+import io.spine.tools.code.ExternalModule;
+import org.checkerframework.checker.regex.qual.Regex;
+import org.gradle.api.GradleException;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.lang.String.format;
+import static java.nio.file.Files.isRegularFile;
+import static java.nio.file.Files.readAllLines;
+import static java.nio.file.Files.write;
+import static java.util.regex.Pattern.compile;
+import static java.util.stream.Collectors.toList;
+
+final class SourceFile extends AbstractSourceFile implements Logging {
+
+    @Regex(2)
+    private static final Pattern IMPORT_PATTERN = compile("import [\"']([^:]+)[\"'] as (.+);");
+
+    private List lines;
+
+    private SourceFile(Path path, List lines) {
+        super(path);
+        this.lines = lines;
+    }
+
+    static SourceFile read(Path path) {
+        checkNotNull(path);
+        try {
+            List lines = readAllLines(path);
+            return new SourceFile(path, lines);
+        } catch (IOException e) {
+            throw new GradleException(format("Unable to read file `%s`.", path), e);
+        }
+    }
+
+    static boolean isGeneratedDart(Path file) {
+        if (!isRegularFile(file)) {
+            return false;
+        }
+        return file.endsWith(".pb.dart")
+                || file.endsWith(".pbenum.dart")
+                || file.endsWith(".pbserver.dart")
+                || file.endsWith(".pbjson.dart");
+    }
+
+    void resolveImports(ImmutableList modules, Path libPath) {
+        lines = lines.stream()
+                     .map(line -> resolveImportInLine(line, modules, libPath))
+                     .collect(toList());
+    }
+
+    private String resolveImportInLine(String line,
+                                       ImmutableList modules,
+                                       Path libPath) {
+        Matcher matcher = IMPORT_PATTERN.matcher(line);
+        if (matcher.matches()) {
+            _debug().log("Import found: `%s`", line);
+            String path = matcher.group(1);
+            Path absolutePath = path().getParent()
+                                      .resolve(path)
+                                      .normalize();
+            _debug().log("Resolved against this file: `%s`", absolutePath);
+            Path relativeImport = libPath.relativize(absolutePath);
+            _debug().log("Relative: `%s`", relativeImport);
+            FileReference reference = FileReference.of(relativeImport.toString());
+            for (ExternalModule module : modules) {
+                if (module.provides(reference)) {
+                    String importStatement = format("import 'package:%s/%s' as %s;",
+                                                    module.name(),
+                                                    relativeImport,
+                                                    matcher.group(2));
+                    _debug().log("Replacing with %s", importStatement);
+                    return importStatement;
+                }
+            }
+        }
+        return line;
+    }
+
+    void store() {
+        Path path = path();
+        try {
+            write(path, lines);
+        } catch (IOException e) {
+            throw new GradleException(format("Unable to write file `%s`.", path), e);
+        }
+    }
+}

From 4e910f1ef1334a41add9aca4229d612550cbf356 Mon Sep 17 00:00:00 2001
From: Dmytro Dashenkov 
Date: Wed, 8 Apr 2020 18:14:30 +0300
Subject: [PATCH 07/10] Add doc

---
 .../java/io/spine/tools/code/ExternalModule.java     |  6 ++++++
 .../io/spine/tools/gradle/ProtoDartTaskName.java     |  3 +++
 .../main/java/io/spine/generate/dart/SourceFile.java | 12 ++++++++++++
 3 files changed, 21 insertions(+)

diff --git a/tools/plugin-base/src/main/java/io/spine/tools/code/ExternalModule.java b/tools/plugin-base/src/main/java/io/spine/tools/code/ExternalModule.java
index dfc524502e..ea277f152c 100644
--- a/tools/plugin-base/src/main/java/io/spine/tools/code/ExternalModule.java
+++ b/tools/plugin-base/src/main/java/io/spine/tools/code/ExternalModule.java
@@ -89,6 +89,9 @@ public boolean provides(FileReference fileReference) {
         return result;
     }
 
+    /**
+     * Obtains the name of the module.
+     */
     public String name() {
         return name;
     }
@@ -138,6 +141,9 @@ public static ExternalModule spineUsers() {
         return new ExternalModule("spine-users", directories);
     }
 
+    /**
+     * All the modules in {@link #spineWeb()} and {@link #spineUsers()}.
+     */
     public static ImmutableList predefinedModules() {
         return ImmutableList.of(spineWeb(), spineUsers());
     }
diff --git a/tools/plugin-base/src/main/java/io/spine/tools/gradle/ProtoDartTaskName.java b/tools/plugin-base/src/main/java/io/spine/tools/gradle/ProtoDartTaskName.java
index d5e79420a1..c63d29f5d3 100644
--- a/tools/plugin-base/src/main/java/io/spine/tools/gradle/ProtoDartTaskName.java
+++ b/tools/plugin-base/src/main/java/io/spine/tools/gradle/ProtoDartTaskName.java
@@ -60,5 +60,8 @@ public enum ProtoDartTaskName implements TaskName {
      */
     copyTestGeneratedDart,
 
+    /**
+     * Rewrites the Dart source files generated from Protobuf with the resolved absolute imports.
+     */
     resolveImports
 }
diff --git a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/SourceFile.java b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/SourceFile.java
index 3c537102df..c9a485da9d 100644
--- a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/SourceFile.java
+++ b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/SourceFile.java
@@ -42,6 +42,9 @@
 import static java.util.regex.Pattern.compile;
 import static java.util.stream.Collectors.toList;
 
+/**
+ * A Dart source file.
+ */
 final class SourceFile extends AbstractSourceFile implements Logging {
 
     @Regex(2)
@@ -54,6 +57,9 @@ private SourceFile(Path path, List lines) {
         this.lines = lines;
     }
 
+    /**
+     * Reads the file from disc.
+     */
     static SourceFile read(Path path) {
         checkNotNull(path);
         try {
@@ -74,6 +80,9 @@ static boolean isGeneratedDart(Path file) {
                 || file.endsWith(".pbjson.dart");
     }
 
+    /**
+     * Resolves the relative imports in the file into absolute ones with the given modules.
+     */
     void resolveImports(ImmutableList modules, Path libPath) {
         lines = lines.stream()
                      .map(line -> resolveImportInLine(line, modules, libPath))
@@ -108,6 +117,9 @@ private String resolveImportInLine(String line,
         return line;
     }
 
+    /**
+     * Rewrites this file.
+     */
     void store() {
         Path path = path();
         try {

From df743798ce45d354c529f00e01908b8942c36974 Mon Sep 17 00:00:00 2001
From: Dmytro Dashenkov 
Date: Thu, 9 Apr 2020 10:53:14 +0300
Subject: [PATCH 08/10] Fix package naming and doc

---
 .../{ => structure}/DirectoryPattern.java     |  6 ++---
 .../code/{ => structure}/ExternalModule.java  | 10 ++++----
 .../code/{ => structure}/package-info.java    |  2 +-
 .../{ => structure}/DirectoryPatternTest.java |  4 +--
 .../{ => structure}/ExternalModuleTest.java   |  4 +--
 .../io/spine/generate/dart/Extension.java     | 25 ++++++++++---------
 .../io/spine/generate/dart/SourceFile.java    | 17 +++++++------
 .../js/generate/imports/ImportStatement.java  |  2 +-
 .../js/generate/imports/ResolveImports.java   |  4 +--
 .../java/io/spine/js/gradle/Extension.java    |  6 ++---
 .../io/spine/js/gradle/ProtoJsPlugin.java     |  2 +-
 .../generate/imports/ImportStatementTest.java |  2 +-
 .../generate/imports/ResolveImportsTest.java  |  5 ++--
 .../io/spine/js/gradle/ExtensionTest.java     |  2 +-
 .../code/fs/{js => }/DirectoryReference.java  |  2 +-
 .../spine/code/fs/{js => }/FileReference.java |  4 +--
 .../java/io/spine/code/fs/js/FileName.java    |  1 +
 .../code/fs/js/DirectoryReferenceTest.java    |  1 +
 .../spine/code/fs/js/FileReferenceTest.java   |  1 +
 19 files changed, 53 insertions(+), 47 deletions(-)
 rename tools/plugin-base/src/main/java/io/spine/tools/code/{ => structure}/DirectoryPattern.java (98%)
 rename tools/plugin-base/src/main/java/io/spine/tools/code/{ => structure}/ExternalModule.java (95%)
 rename tools/plugin-base/src/main/java/io/spine/tools/code/{ => structure}/package-info.java (96%)
 rename tools/plugin-base/src/test/java/io/spine/tools/code/{ => structure}/DirectoryPatternTest.java (98%)
 rename tools/plugin-base/src/test/java/io/spine/tools/code/{ => structure}/ExternalModuleTest.java (98%)
 rename tools/tool-base/src/main/java/io/spine/code/fs/{js => }/DirectoryReference.java (98%)
 rename tools/tool-base/src/main/java/io/spine/code/fs/{js => }/FileReference.java (97%)

diff --git a/tools/plugin-base/src/main/java/io/spine/tools/code/DirectoryPattern.java b/tools/plugin-base/src/main/java/io/spine/tools/code/structure/DirectoryPattern.java
similarity index 98%
rename from tools/plugin-base/src/main/java/io/spine/tools/code/DirectoryPattern.java
rename to tools/plugin-base/src/main/java/io/spine/tools/code/structure/DirectoryPattern.java
index d3c6455a24..7843c56ce7 100644
--- a/tools/plugin-base/src/main/java/io/spine/tools/code/DirectoryPattern.java
+++ b/tools/plugin-base/src/main/java/io/spine/tools/code/structure/DirectoryPattern.java
@@ -18,12 +18,12 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-package io.spine.tools.code;
+package io.spine.tools.code.structure;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Joiner;
-import io.spine.code.fs.js.DirectoryReference;
-import io.spine.code.fs.js.FileReference;
+import io.spine.code.fs.DirectoryReference;
+import io.spine.code.fs.FileReference;
 
 import java.util.List;
 import java.util.Objects;
diff --git a/tools/plugin-base/src/main/java/io/spine/tools/code/ExternalModule.java b/tools/plugin-base/src/main/java/io/spine/tools/code/structure/ExternalModule.java
similarity index 95%
rename from tools/plugin-base/src/main/java/io/spine/tools/code/ExternalModule.java
rename to tools/plugin-base/src/main/java/io/spine/tools/code/structure/ExternalModule.java
index ea277f152c..2ff2325d03 100644
--- a/tools/plugin-base/src/main/java/io/spine/tools/code/ExternalModule.java
+++ b/tools/plugin-base/src/main/java/io/spine/tools/code/structure/ExternalModule.java
@@ -18,13 +18,13 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-package io.spine.tools.code;
+package io.spine.tools.code.structure;
 
 import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
-import io.spine.code.fs.js.DirectoryReference;
-import io.spine.code.fs.js.FileReference;
+import io.spine.code.fs.DirectoryReference;
+import io.spine.code.fs.FileReference;
 
 import java.util.Collection;
 import java.util.Objects;
@@ -35,9 +35,9 @@
 import static io.spine.util.Preconditions2.checkNotEmptyOrBlank;
 
 /**
- * An external JavaScript module used in a project.
+ * An external library module used in a project.
  *
- * 

External means that it is provided by an artifact repository like NPM. + *

An external module is typically provided by a package manager, such as NPM or Pub. */ public final class ExternalModule { diff --git a/tools/plugin-base/src/main/java/io/spine/tools/code/package-info.java b/tools/plugin-base/src/main/java/io/spine/tools/code/structure/package-info.java similarity index 96% rename from tools/plugin-base/src/main/java/io/spine/tools/code/package-info.java rename to tools/plugin-base/src/main/java/io/spine/tools/code/structure/package-info.java index a640309c8d..1f11357a3f 100644 --- a/tools/plugin-base/src/main/java/io/spine/tools/code/package-info.java +++ b/tools/plugin-base/src/main/java/io/spine/tools/code/structure/package-info.java @@ -23,7 +23,7 @@ */ @CheckReturnValue @ParametersAreNonnullByDefault -package io.spine.tools.code; +package io.spine.tools.code.structure; import javax.annotation.CheckReturnValue; import javax.annotation.ParametersAreNonnullByDefault; diff --git a/tools/plugin-base/src/test/java/io/spine/tools/code/DirectoryPatternTest.java b/tools/plugin-base/src/test/java/io/spine/tools/code/structure/DirectoryPatternTest.java similarity index 98% rename from tools/plugin-base/src/test/java/io/spine/tools/code/DirectoryPatternTest.java rename to tools/plugin-base/src/test/java/io/spine/tools/code/structure/DirectoryPatternTest.java index f812a29b70..32ac8328b0 100644 --- a/tools/plugin-base/src/test/java/io/spine/tools/code/DirectoryPatternTest.java +++ b/tools/plugin-base/src/test/java/io/spine/tools/code/structure/DirectoryPatternTest.java @@ -18,11 +18,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.tools.code; +package io.spine.tools.code.structure; import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; -import io.spine.code.fs.js.DirectoryReference; +import io.spine.code.fs.DirectoryReference; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/tools/plugin-base/src/test/java/io/spine/tools/code/ExternalModuleTest.java b/tools/plugin-base/src/test/java/io/spine/tools/code/structure/ExternalModuleTest.java similarity index 98% rename from tools/plugin-base/src/test/java/io/spine/tools/code/ExternalModuleTest.java rename to tools/plugin-base/src/test/java/io/spine/tools/code/structure/ExternalModuleTest.java index ff4d48c028..8320a32329 100644 --- a/tools/plugin-base/src/test/java/io/spine/tools/code/ExternalModuleTest.java +++ b/tools/plugin-base/src/test/java/io/spine/tools/code/structure/ExternalModuleTest.java @@ -18,10 +18,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.tools.code; +package io.spine.tools.code.structure; import com.google.common.testing.EqualsTester; -import io.spine.code.fs.js.FileReference; +import io.spine.code.fs.FileReference; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/Extension.java b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/Extension.java index 2fcb9d0a4c..74d8cf818f 100644 --- a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/Extension.java +++ b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/Extension.java @@ -22,8 +22,8 @@ import com.google.common.collect.ImmutableList; import io.spine.code.fs.dart.DefaultDartProject; -import io.spine.tools.code.DirectoryPattern; -import io.spine.tools.code.ExternalModule; +import io.spine.tools.code.structure.DirectoryPattern; +import io.spine.tools.code.structure.ExternalModule; import io.spine.tools.gradle.GradleExtension; import org.gradle.api.Project; import org.gradle.api.file.DirectoryProperty; @@ -61,30 +61,31 @@ public final class Extension extends GradleExtension { private final DirectoryProperty testGeneratedDir; /** - * Names of JavaScript modules and directories they provide. + * Names of Dart modules and directories they provide. * *

Information about modules is used to resolve imports in generated Protobuf files. * - *

Additionally to modules specified via the property, - * the {@linkplain ExternalModule#predefinedModules() predefined Spine} modules are used. + *

Import resolution only applies to Dart files generated from Protobuf. Such files must + * have one of extensions: {@code .pb.dart}, {@code .pbenum.dart}, {@code .pbserver.dart}, or + * {@code .pbjson.dart}. All other files are ignored. * *

An example of the definition: *

{@code
      * modules = [
      *      // The module provides `company/client` directory (not including subdirectories).
-     *      // So, an import path like {@code ../company/client/file.js}
-     *      // becomes {@code client/company/client/file.js}.
+     *      // So, an import path like {@code ../company/client/file.pb.dart}
+     *      // becomes {@code package:client/company/client/file.pb.dart}.
      *      'client' : ['company/client'],
      *
      *      // The module provides `company/server` directory (including subdirectories).
-     *      // So, an import path like {@code ../company/server/nested/file.js}
-     *      // becomes {@code server/company/server/nested/file.js}.
+     *      // So, an import path like {@code ../company/server/nested/file.pb.dart}
+     *      // becomes {@code package:server/company/server/nested/file.pb.dart}.
      *      'server' : ['company/server/*'],
      *
      *      // The module provides 'proto/company` directory.
-     *      // So, an import pah like {@code ../company/file.js}
-     *      // becomes {@code common-types/proto/company/file.js}.
-     *      'common-types' : ['proto/company']
+     *      // So, an import pah like {@code ../company/file.pbenum.dart}
+     *      // becomes {@code package:common_types/proto/company/file.pbenum.dart}.
+     *      'common_types' : ['proto/company']
      * ]
      * }
*/ diff --git a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/SourceFile.java b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/SourceFile.java index c9a485da9d..5480fc3281 100644 --- a/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/SourceFile.java +++ b/tools/proto-dart-plugin/src/main/java/io/spine/generate/dart/SourceFile.java @@ -22,14 +22,15 @@ import com.google.common.collect.ImmutableList; import io.spine.code.AbstractSourceFile; -import io.spine.code.fs.js.FileReference; +import io.spine.code.fs.FileReference; import io.spine.logging.Logging; -import io.spine.tools.code.ExternalModule; +import io.spine.tools.code.structure.ExternalModule; import org.checkerframework.checker.regex.qual.Regex; import org.gradle.api.GradleException; import java.io.IOException; import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -40,7 +41,6 @@ import static java.nio.file.Files.readAllLines; import static java.nio.file.Files.write; import static java.util.regex.Pattern.compile; -import static java.util.stream.Collectors.toList; /** * A Dart source file. @@ -58,7 +58,7 @@ private SourceFile(Path path, List lines) { } /** - * Reads the file from disc. + * Reads the file from the local file system. */ static SourceFile read(Path path) { checkNotNull(path); @@ -84,9 +84,12 @@ static boolean isGeneratedDart(Path file) { * Resolves the relative imports in the file into absolute ones with the given modules. */ void resolveImports(ImmutableList modules, Path libPath) { - lines = lines.stream() - .map(line -> resolveImportInLine(line, modules, libPath)) - .collect(toList()); + List processedLines = new ArrayList<>(); + for (String line : lines) { + String processedLine = resolveImportInLine(line, modules, libPath); + processedLines.add(processedLine); + } + lines = processedLines; } private String resolveImportInLine(String line, diff --git a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/ImportStatement.java b/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/ImportStatement.java index c4af377f2f..a1e21d768a 100644 --- a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/ImportStatement.java +++ b/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/ImportStatement.java @@ -20,7 +20,7 @@ package io.spine.js.generate.imports; -import io.spine.code.fs.js.FileReference; +import io.spine.code.fs.FileReference; import io.spine.logging.Logging; import java.io.File; diff --git a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/ResolveImports.java b/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/ResolveImports.java index 2c1a718e08..456a654d9d 100644 --- a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/ResolveImports.java +++ b/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/ResolveImports.java @@ -25,13 +25,13 @@ import com.google.common.collect.ImmutableSet; import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.protobuf.Descriptors.FileDescriptor; +import io.spine.code.fs.FileReference; import io.spine.code.fs.js.Directory; import io.spine.code.fs.js.FileName; -import io.spine.code.fs.js.FileReference; import io.spine.code.proto.FileSet; import io.spine.js.generate.GenerationTask; import io.spine.logging.Logging; -import io.spine.tools.code.ExternalModule; +import io.spine.tools.code.structure.ExternalModule; import org.checkerframework.checker.nullness.qual.Nullable; import java.nio.file.Path; diff --git a/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/Extension.java b/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/Extension.java index ff52b94d34..6faf287a3f 100644 --- a/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/Extension.java +++ b/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/Extension.java @@ -24,8 +24,8 @@ import io.spine.code.fs.DefaultProject; import io.spine.code.fs.js.DefaultJsProject; import io.spine.code.fs.js.Directory; -import io.spine.tools.code.DirectoryPattern; -import io.spine.tools.code.ExternalModule; +import io.spine.tools.code.structure.DirectoryPattern; +import io.spine.tools.code.structure.ExternalModule; import io.spine.tools.gradle.GradleExtension; import org.gradle.api.Project; import org.gradle.api.Task; @@ -42,7 +42,7 @@ import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Maps.newHashMap; import static io.spine.js.gradle.ProtoJsPlugin.extensionName; -import static io.spine.tools.code.ExternalModule.predefinedModules; +import static io.spine.tools.code.structure.ExternalModule.predefinedModules; import static java.util.stream.Collectors.toList; /** diff --git a/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ProtoJsPlugin.java b/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ProtoJsPlugin.java index 24eff2fbb5..e2f769b688 100644 --- a/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ProtoJsPlugin.java +++ b/tools/proto-js-plugin/src/main/java/io/spine/js/gradle/ProtoJsPlugin.java @@ -29,7 +29,7 @@ import io.spine.js.generate.imports.ResolveImports; import io.spine.js.generate.index.GenerateIndexFile; import io.spine.js.generate.parse.GenerateKnownTypeParsers; -import io.spine.tools.code.ExternalModule; +import io.spine.tools.code.structure.ExternalModule; import io.spine.tools.gradle.BaseTaskName; import io.spine.tools.gradle.GradleTask; import io.spine.tools.gradle.ProtoPlugin; diff --git a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ImportStatementTest.java b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ImportStatementTest.java index 81c8b88e92..1c3ec044d9 100644 --- a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ImportStatementTest.java +++ b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ImportStatementTest.java @@ -20,7 +20,7 @@ package io.spine.js.generate.imports; -import io.spine.code.fs.js.FileReference; +import io.spine.code.fs.FileReference; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ResolveImportsTest.java b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ResolveImportsTest.java index 24a87b10fb..a9b7b5cc2d 100644 --- a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ResolveImportsTest.java +++ b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ResolveImportsTest.java @@ -24,8 +24,8 @@ import com.google.common.truth.IterableSubject; import io.spine.code.fs.js.Directory; import io.spine.js.generate.given.GivenProject; -import io.spine.tools.code.DirectoryPattern; -import io.spine.tools.code.ExternalModule; +import io.spine.tools.code.structure.DirectoryPattern; +import io.spine.tools.code.structure.ExternalModule; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -36,7 +36,6 @@ import static com.google.common.truth.Truth.assertThat; import static java.util.Arrays.asList; -import static java.util.Collections.singletonList; @DisplayName("ResolveImports task should") class ResolveImportsTest { diff --git a/tools/proto-js-plugin/src/test/java/io/spine/js/gradle/ExtensionTest.java b/tools/proto-js-plugin/src/test/java/io/spine/js/gradle/ExtensionTest.java index d15c1e9b9d..25a5c01b55 100644 --- a/tools/proto-js-plugin/src/test/java/io/spine/js/gradle/ExtensionTest.java +++ b/tools/proto-js-plugin/src/test/java/io/spine/js/gradle/ExtensionTest.java @@ -22,7 +22,7 @@ import io.spine.code.fs.js.DefaultJsProject; import io.spine.code.fs.js.Directory; -import io.spine.tools.code.ExternalModule; +import io.spine.tools.code.structure.ExternalModule; import org.gradle.api.Project; import org.gradle.api.plugins.PluginManager; import org.gradle.testfixtures.ProjectBuilder; diff --git a/tools/tool-base/src/main/java/io/spine/code/fs/js/DirectoryReference.java b/tools/tool-base/src/main/java/io/spine/code/fs/DirectoryReference.java similarity index 98% rename from tools/tool-base/src/main/java/io/spine/code/fs/js/DirectoryReference.java rename to tools/tool-base/src/main/java/io/spine/code/fs/DirectoryReference.java index 9c37638dae..bc0b795169 100644 --- a/tools/tool-base/src/main/java/io/spine/code/fs/js/DirectoryReference.java +++ b/tools/tool-base/src/main/java/io/spine/code/fs/DirectoryReference.java @@ -18,7 +18,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.code.fs.js; +package io.spine.code.fs; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableList; diff --git a/tools/tool-base/src/main/java/io/spine/code/fs/js/FileReference.java b/tools/tool-base/src/main/java/io/spine/code/fs/FileReference.java similarity index 97% rename from tools/tool-base/src/main/java/io/spine/code/fs/js/FileReference.java rename to tools/tool-base/src/main/java/io/spine/code/fs/FileReference.java index fc36a37d5f..017059f8c1 100644 --- a/tools/tool-base/src/main/java/io/spine/code/fs/js/FileReference.java +++ b/tools/tool-base/src/main/java/io/spine/code/fs/FileReference.java @@ -18,7 +18,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.code.fs.js; +package io.spine.code.fs; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableList; @@ -29,7 +29,7 @@ import static io.spine.util.Preconditions2.checkNotEmptyOrBlank; /** - * A path to a file used in a JavaScript import statement. + * A path to a file used in an import statement. */ public final class FileReference extends StringTypeValue { diff --git a/tools/tool-base/src/main/java/io/spine/code/fs/js/FileName.java b/tools/tool-base/src/main/java/io/spine/code/fs/js/FileName.java index 0268883f85..012bafc69f 100644 --- a/tools/tool-base/src/main/java/io/spine/code/fs/js/FileName.java +++ b/tools/tool-base/src/main/java/io/spine/code/fs/js/FileName.java @@ -26,6 +26,7 @@ import com.google.common.collect.ImmutableList; import com.google.protobuf.Descriptors.FileDescriptor; import io.spine.code.AbstractFileName; +import io.spine.code.fs.FileReference; import java.util.List; diff --git a/tools/tool-base/src/test/java/io/spine/code/fs/js/DirectoryReferenceTest.java b/tools/tool-base/src/test/java/io/spine/code/fs/js/DirectoryReferenceTest.java index a30e846e37..f51e562f74 100644 --- a/tools/tool-base/src/test/java/io/spine/code/fs/js/DirectoryReferenceTest.java +++ b/tools/tool-base/src/test/java/io/spine/code/fs/js/DirectoryReferenceTest.java @@ -20,6 +20,7 @@ package io.spine.code.fs.js; +import io.spine.code.fs.DirectoryReference; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/tools/tool-base/src/test/java/io/spine/code/fs/js/FileReferenceTest.java b/tools/tool-base/src/test/java/io/spine/code/fs/js/FileReferenceTest.java index 2b67d7ca6b..18ff66c56f 100644 --- a/tools/tool-base/src/test/java/io/spine/code/fs/js/FileReferenceTest.java +++ b/tools/tool-base/src/test/java/io/spine/code/fs/js/FileReferenceTest.java @@ -21,6 +21,7 @@ package io.spine.code.fs.js; import com.google.common.testing.NullPointerTester; +import io.spine.code.fs.FileReference; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; From 5b330260016f058806e1904da5e07421d5fdbb08 Mon Sep 17 00:00:00 2001 From: Dmytro Dashenkov Date: Thu, 9 Apr 2020 10:53:45 +0300 Subject: [PATCH 09/10] Remove redundant util method --- .../spine/js/generate/imports/ResolveImportsTest.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ResolveImportsTest.java b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ResolveImportsTest.java index a9b7b5cc2d..92d2696a54 100644 --- a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ResolveImportsTest.java +++ b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/ResolveImportsTest.java @@ -41,7 +41,9 @@ class ResolveImportsTest { private final Directory generatedProtoDir = GivenProject.mainProtoSources(); - private final ExternalModule module = newModule("test-module", "root-dir"); + private final ExternalModule module = new ExternalModule( + "test-module", ImmutableList.of(DirectoryPattern.of("root-dir")) + ); private final Path tempDirectory = generatedProtoDir.path(); private final Path testFile = tempDirectory.resolve("js/with-imports.js"); @@ -149,10 +151,4 @@ private static IterableSubject afterResolve(Path file, ResolveImports task) thro private ResolveImports newTask(ExternalModule module) { return new ResolveImports(generatedProtoDir, ImmutableList.of(module)); } - - private static ExternalModule newModule(String moduleName, String directoryPattern) { - DirectoryPattern pattern = DirectoryPattern.of(directoryPattern); - List patterns = singletonList(pattern); - return new ExternalModule(moduleName, patterns); - } } From 823e02bb224c4e94f7ce052ab506bc3bf2d1de63 Mon Sep 17 00:00:00 2001 From: Dmytro Dashenkov Date: Thu, 9 Apr 2020 11:02:08 +0300 Subject: [PATCH 10/10] Document packages --- .../java/io/spine/tools/code/structure/package-info.java | 2 +- .../main/java/io/spine/js/generate/imports/package-info.java | 4 ++++ .../io/spine/js/generate/imports/given/package-info.java | 5 ++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/plugin-base/src/main/java/io/spine/tools/code/structure/package-info.java b/tools/plugin-base/src/main/java/io/spine/tools/code/structure/package-info.java index 1f11357a3f..e54cbf6162 100644 --- a/tools/plugin-base/src/main/java/io/spine/tools/code/structure/package-info.java +++ b/tools/plugin-base/src/main/java/io/spine/tools/code/structure/package-info.java @@ -19,7 +19,7 @@ */ /** - * The classes which resolve imports in generated code. + * Classes which work with source code directory structure. */ @CheckReturnValue @ParametersAreNonnullByDefault diff --git a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/package-info.java b/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/package-info.java index bebe6ac936..839661a05f 100644 --- a/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/package-info.java +++ b/tools/proto-js-plugin/src/main/java/io/spine/js/generate/imports/package-info.java @@ -18,6 +18,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/** + * Classes for resolving JS imports. + */ + @CheckReturnValue @ParametersAreNonnullByDefault package io.spine.js.generate.imports; diff --git a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/given/package-info.java b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/given/package-info.java index f28c85e449..c412a6f783 100644 --- a/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/given/package-info.java +++ b/tools/proto-js-plugin/src/test/java/io/spine/js/generate/imports/given/package-info.java @@ -1,4 +1,3 @@ - /* * Copyright 2020, TeamDev. All rights reserved. * @@ -19,6 +18,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/** + * Contains test environment for components resolving script language imports. + */ + @CheckReturnValue @ParametersAreNonnullByDefault package io.spine.js.generate.imports.given;