diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/containers/impl/OutputContainerGroupImpl.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/containers/impl/OutputContainerGroupImpl.java index 0e50f400a..222baf3a9 100644 --- a/java-compiler-testing/src/main/java/io/github/ascopes/jct/containers/impl/OutputContainerGroupImpl.java +++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/containers/impl/OutputContainerGroupImpl.java @@ -22,7 +22,6 @@ import io.github.ascopes.jct.containers.PackageContainerGroup; import io.github.ascopes.jct.filemanagers.ModuleLocation; import io.github.ascopes.jct.filemanagers.PathFileObject; -import io.github.ascopes.jct.utils.ModuleHandle; import io.github.ascopes.jct.utils.StringUtils; import io.github.ascopes.jct.workspaces.PathRoot; import io.github.ascopes.jct.workspaces.impl.WrappingDirectoryImpl; @@ -124,13 +123,14 @@ public PackageContainerGroup getModule(String module) { @Override @Nullable public PathFileObject getFileForInput(String packageName, String relativeName) { - var moduleHandle = ModuleHandle.tryExtract(packageName); + var moduleName = extractModuleName(packageName); - if (moduleHandle != null) { - var module = getModule(moduleHandle.getModuleName()); + if (moduleName != null) { + var module = getModule(moduleName); if (module != null) { - var file = module.getFileForInput(moduleHandle.getRest(), relativeName); + var realPackageName = extractPackageName(packageName); + var file = module.getFileForInput(realPackageName, relativeName); if (file != null) { return file; @@ -144,11 +144,12 @@ public PathFileObject getFileForInput(String packageName, String relativeName) { @Override @Nullable public PathFileObject getFileForOutput(String packageName, String relativeName) { - var moduleHandle = ModuleHandle.tryExtract(packageName); + var moduleName = extractModuleName(packageName); - if (moduleHandle != null) { - var module = getOrCreateModule(moduleHandle.getModuleName()); - var file = module.getFileForOutput(moduleHandle.getRest(), relativeName); + if (moduleName != null) { + var module = getOrCreateModule(moduleName); + var realPackageName = extractPackageName(packageName); + var file = module.getFileForOutput(realPackageName, relativeName); if (file != null) { return file; @@ -161,13 +162,14 @@ public PathFileObject getFileForOutput(String packageName, String relativeName) @Override @Nullable public PathFileObject getJavaFileForInput(String className, Kind kind) { - var moduleHandle = ModuleHandle.tryExtract(className); + var moduleName = extractModuleName(className); - if (moduleHandle != null) { - var module = getModule(moduleHandle.getModuleName()); + if (moduleName != null) { + var module = getModule(moduleName); if (module != null) { - var file = module.getJavaFileForInput(moduleHandle.getRest(), kind); + var realClassName = extractPackageName(className); + var file = module.getJavaFileForInput(realClassName, kind); if (file != null) { return file; @@ -181,11 +183,12 @@ public PathFileObject getJavaFileForInput(String className, Kind kind) { @Override @Nullable public PathFileObject getJavaFileForOutput(String className, Kind kind) { - var moduleHandle = ModuleHandle.tryExtract(className); + var moduleName = extractModuleName(className); - if (moduleHandle != null) { - var module = getOrCreateModule(moduleHandle.getModuleName()); - var file = module.getJavaFileForOutput(moduleHandle.getRest(), kind); + if (moduleName != null) { + var module = getOrCreateModule(moduleName); + var realClassName = extractPackageName(className); + var file = module.getJavaFileForOutput(realClassName, kind); if (file != null) { return file; @@ -239,6 +242,21 @@ private OutputPackageContainerGroupImpl newPackageGroup(ModuleLocation moduleLoc return group; } + @Nullable + private static String extractModuleName(String binaryName) { + // extractModuleName("foo.bar.Baz") -> null + // extractModuleName("some.module/foo.bar.Baz") -> "some.module" + var separatorIndex = binaryName.indexOf('/'); + return separatorIndex == -1 ? null : binaryName.substring(0, separatorIndex); + } + + private static String extractPackageName(String binaryName) { + // extractPackageName("foo.bar.Baz") -> "foo.bar.Baz" + // extractPackageName("some.module/foo.bar.Baz") -> "foo.bar.Baz" + var separatorIndex = binaryName.indexOf('/'); + return separatorIndex == -1 ? binaryName : binaryName.substring(separatorIndex + 1); + } + /** * Unlike {@link PackageContainerGroupImpl}, this implementation does not reject output-oriented * locations in the constructor. diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/utils/ModuleHandle.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/utils/ModuleHandle.java deleted file mode 100644 index 30a06a171..000000000 --- a/java-compiler-testing/src/main/java/io/github/ascopes/jct/utils/ModuleHandle.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2022 - 2023, the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.github.ascopes.jct.utils; - -import static java.util.Objects.requireNonNull; - -import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; -import org.apiguardian.api.API; -import org.apiguardian.api.API.Status; - -/** - * Helper class that extracts a module name from a string as a prefix and holds the result. - * - * @author Ashley Scopes - * @since 0.0.1 - */ -@API(since = "0.0.1", status = Status.INTERNAL) -@ThreadSafe -public final class ModuleHandle { - - private final String original; - private final String moduleName; - private final String rest; - - private ModuleHandle(String original, String moduleName, String rest) { - this.original = requireNonNull(original, "original"); - this.moduleName = requireNonNull(moduleName, "moduleName"); - this.rest = requireNonNull(rest, "rest"); - } - - /** - * Get the original input string. - * - * @return the original input string. - */ - public String getOriginal() { - return original; - } - - /** - * Get the extracted module name. - * - * @return the module name. - */ - public String getModuleName() { - return moduleName; - } - - /** - * Get the rest of the string minus the module name. - * - * @return the rest of the string. - */ - public String getRest() { - return rest; - } - - /** - * Try and extract a module name from the given string. - * - * @param original the string to operate on. - * @return the extracted prefix, or nullif no module was found. - * @throws IllegalArgumentException if the input string starts with a forward slash. - */ - @Nullable - public static ModuleHandle tryExtract(String original) { - if (original.startsWith("/")) { - throw new IllegalArgumentException( - "Absolute paths are not supported (got '" + original + "')"); - } - - // If we have a valid module name at the start, we should check in that location first. - var firstSlash = original.indexOf('/'); - - if (firstSlash == -1) { - return null; - } - - var moduleName = original.substring(0, firstSlash); - var restOfPath = original.substring(firstSlash + 1); - return new ModuleHandle(original, moduleName, restOfPath); - } -} diff --git a/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/utils/ModuleHandleTest.java b/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/utils/ModuleHandleTest.java deleted file mode 100644 index dd45b1528..000000000 --- a/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/utils/ModuleHandleTest.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2022 - 2023, the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.github.ascopes.jct.tests.unit.utils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import io.github.ascopes.jct.utils.ModuleHandle; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; -import org.junit.jupiter.params.provider.ValueSource; - -/** - * {@link ModuleHandle} tests. - * - * @author Ashley Scopes - */ -@DisplayName("ModuleHandle tests") -class ModuleHandleTest { - - @DisplayName("tryExtract throws an IllegalArgumentException for names leading with a '/'") - @ValueSource(strings = { - "/", - "/foo", - "/HelloWorld", - "/java.base/java.lang.Integer" - }) - @ParameterizedTest(name = "tryExtract throws an IllegalArgumentException for \"{0}\"") - void tryExtractThrowsIllegalArgumentExceptionForLeadingSlash(String original) { - // Then - assertThatThrownBy(() -> ModuleHandle.tryExtract(original)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Absolute paths are not supported (got '%s')", original); - } - - @DisplayName("tryExtract returns empty if no module prefix is found") - @ValueSource(strings = { - "", - "foo", - "HelloWorld", - "org.example.HelloWorld" - }) - @ParameterizedTest(name = "tryExtract returns null for \"{0}\"") - void tryExtractReturnsNullIfNoModuleHandleIsFound(String original) { - // When - var prefix = ModuleHandle.tryExtract(original); - - // Then - assertThat(prefix).isNull(); - } - - @DisplayName("tryExtract stores the original input in the result") - @Test - void tryExtractStoresTheOriginalInputInTheResult() { - // Given - var original = "net.bytebuddy/net.bytebuddy.ByteBuddy"; - - // When - var prefix = ModuleHandle.tryExtract(original); - - // Then - assertThat(prefix) - .isNotNull() - .extracting(ModuleHandle::getOriginal) - .describedAs("ModuleHandle#getOriginal") - .asString() - .isEqualTo(original); - } - - @DisplayName("tryExtract gets the expected module name for valid modules") - @CsvSource({ - "java.base/, java.base", - "java.base/java.lang.Integer, java.base", - "java.instrument/sun.instrument.TransformerManager, java.instrument", - "net.bytebuddy/net.bytebuddy.ByteBuddy, net.bytebuddy", - "java.base/module-info, java.base", - "foo/org.example.something.Some$Nested$Clazz, foo", - }) - @ParameterizedTest(name = "tryExtract(\"{0}\") extracts the moduleName as \"{1}\"") - void tryExtractExtractsTheModuleName(String original, String expected) { - // Then - assertThat(ModuleHandle.tryExtract(original)) - .isNotNull() - .extracting(ModuleHandle::getModuleName) - .describedAs("ModuleHandle#getModuleName") - .asString() - .isEqualTo(expected); - } - - @DisplayName("tryExtract gets the expected rest of the name for valid modules") - @CsvSource({ - "java.base/, ''", - "java.base/java.lang.Integer, java.lang.Integer", - "java.instrument/sun.instrument.TransformerManager, sun.instrument.TransformerManager", - "net.bytebuddy/net.bytebuddy.ByteBuddy, net.bytebuddy.ByteBuddy", - "java.base/module-info, module-info", - "foo/org.example.something.Some$Nested$Clazz, org.example.something.Some$Nested$Clazz", - }) - @ParameterizedTest(name = "tryExtract(\"{0}\") extracts the rest as \"{1}\"") - void tryExtractExtractsTheRest(String original, String expected) { - // Then - assertThat(ModuleHandle.tryExtract(original)) - .isNotNull() - .extracting(ModuleHandle::getRest) - .describedAs("ModuleHandle#getRest") - .asString() - .isEqualTo(expected); - } -}