From 584f4563b9e44764ec5e743b5380f0a77b6d1c8d Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 31 Jul 2025 11:20:23 +0200 Subject: [PATCH] [platform] making `Path`-based `PathManager` getters a bit faster; obsoleting `String`-based counterparts GitOrigin-RevId: 3e0ec7453e864f22a2891d74054ddc01a7b40278 --- .../server/WslBuildCommandLineBuilder.java | 16 +- .../eel/provider/utils/eelPathUtils.kt | 2 +- .../library/GlobalLibraryTableBridgeImpl.kt | 4 +- .../impl/legacyBridge/sdk/SdkBridgeImpl.kt | 7 +- platform/util/api-dump-unreviewed.txt | 24 -- platform/util/api-dump.txt | 30 +++ .../openapi/application/PathManager.java | 228 +++++++++++------- .../impl/jps/serialization/jpsTestUtils.kt | 10 +- 8 files changed, 187 insertions(+), 134 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/server/WslBuildCommandLineBuilder.java b/java/compiler/impl/src/com/intellij/compiler/server/WslBuildCommandLineBuilder.java index dbd70ceb501f..1391afc7a95a 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/WslBuildCommandLineBuilder.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/WslBuildCommandLineBuilder.java @@ -59,7 +59,7 @@ final class WslBuildCommandLineBuilder implements BuildCommandLineBuilder { myHostWorkingDirectory = buildDirectory.toString(); myWorkingDirectory = myDistribution.getWslPath(myHostWorkingDirectory); myClasspathDirectory = myWorkingDirectory + "/jps-" + ApplicationInfo.getInstance().getBuild().asString(); - myHostClasspathDirectory = Paths.get(myDistribution.getWindowsPath(myClasspathDirectory)); + myHostClasspathDirectory = Path.of(myDistribution.getWindowsPath(myClasspathDirectory)); if (ApplicationInfo.getInstance().getBuild().isSnapshot() && !CURRENT_SNAPSHOT_COPIED) { //noinspection AssignmentToStaticFieldFromInstanceMethod CURRENT_SNAPSHOT_COPIED = true; @@ -95,7 +95,7 @@ final class WslBuildCommandLineBuilder implements BuildCommandLineBuilder { if (!builder.isEmpty()) { builder.append(":"); } - Path path = Paths.get(pathName); + Path path = Path.of(pathName); if (myClasspathDirectory != null && myHostClasspathDirectory != null) { Path targetPath = copyProjectAgnosticPathToTargetIfRequired(path); if (!myReportedProgress && !targetPath.equals(path) && myProgressIndicator != null) { @@ -144,7 +144,7 @@ final class WslBuildCommandLineBuilder implements BuildCommandLineBuilder { @Override public @NotNull Path getHostWorkingDirectory() { - return Paths.get(myHostWorkingDirectory); + return Path.of(myHostWorkingDirectory); } @Override @@ -182,12 +182,12 @@ final class WslBuildCommandLineBuilder implements BuildCommandLineBuilder { } public static @Nullable Path getWslBuildSystemDirectory(WSLDistribution distribution) { - String pathsSelector = PathManager.getPathsSelector(); - String wslUserHome = distribution.getUserHome(); + var pathsSelector = PathManager.getPathsSelector(); + var wslUserHome = distribution.getUserHome(); if (wslUserHome == null) return null; - String windowsUserHomePath = distribution.getWindowsPath(wslUserHome); + var windowsUserHomePath = distribution.getWindowsPath(wslUserHome); if (pathsSelector == null) pathsSelector = "." + ApplicationNamesInfo.getInstance().getScriptName(); - String workingDirectory = PathManager.getDefaultSystemPathFor(OS.Linux, windowsUserHomePath, pathsSelector)+ "/" + BuildManager.SYSTEM_ROOT; - return Paths.get(workingDirectory); + var workingDirectory = PathManager.getDefaultSystemPathFor(OS.Linux, windowsUserHomePath, pathsSelector) + '/' + BuildManager.SYSTEM_ROOT; + return Path.of(workingDirectory); } } diff --git a/platform/eel-provider/src/com/intellij/platform/eel/provider/utils/eelPathUtils.kt b/platform/eel-provider/src/com/intellij/platform/eel/provider/utils/eelPathUtils.kt index 0bb33dfc8a6a..1e3627ac00f7 100644 --- a/platform/eel-provider/src/com/intellij/platform/eel/provider/utils/eelPathUtils.kt +++ b/platform/eel-provider/src/com/intellij/platform/eel/provider/utils/eelPathUtils.kt @@ -121,7 +121,7 @@ object EelPathUtils { fun getSystemFolder(eel: EelApi): Path { val selector = PathManager.getPathsSelector() ?: "IJ-Platform" val userHomeFolder = eel.userInfo.home.asNioPath().toString() - return PathManager.getDefaultSystemPathFor(eel.platform.toOs(), userHomeFolder, selector, eel.exec.fetchLoginShellEnvVariablesBlocking()) + return Path.of(PathManager.getDefaultSystemPathFor(eel.platform.toOs(), userHomeFolder, selector, eel.exec.fetchLoginShellEnvVariablesBlocking())) } @JvmStatic diff --git a/platform/projectModel-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/library/GlobalLibraryTableBridgeImpl.kt b/platform/projectModel-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/library/GlobalLibraryTableBridgeImpl.kt index eca61b8e330b..97de8def59b2 100644 --- a/platform/projectModel-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/library/GlobalLibraryTableBridgeImpl.kt +++ b/platform/projectModel-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/library/GlobalLibraryTableBridgeImpl.kt @@ -80,8 +80,8 @@ class GlobalLibraryTableBridgeImpl(val eelMachine: EelMachine) : GlobalLibraryTa private fun createEntitySourceForGlobalLibrary(): EntitySource { val virtualFileUrlManager = GlobalWorkspaceModel.getInstance(eelMachine).getVirtualFileUrlManager() - val globalLibrariesFile = virtualFileUrlManager.getOrCreateFromUrl(PathManager.getOptionsFile(JpsGlobalEntitiesSerializers.GLOBAL_LIBRARIES_FILE_NAME).absolutePath) - return JpsGlobalFileEntitySource(globalLibrariesFile) + val globalLibrariesFile = PathManager.getOptionsDir().resolve(JpsGlobalEntitiesSerializers.GLOBAL_LIBRARIES_FILE_NAME + PathManager.DEFAULT_EXT) + return JpsGlobalFileEntitySource(virtualFileUrlManager.getOrCreateFromUrl(globalLibrariesFile.toAbsolutePath().toString())) } companion object { diff --git a/platform/projectModel-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/sdk/SdkBridgeImpl.kt b/platform/projectModel-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/sdk/SdkBridgeImpl.kt index b2fd338b225a..602dca882ecf 100644 --- a/platform/projectModel-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/sdk/SdkBridgeImpl.kt +++ b/platform/projectModel-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/sdk/SdkBridgeImpl.kt @@ -225,9 +225,8 @@ class SdkBridgeImpl(private var sdkEntityBuilder: SdkEntity.Builder) : UserDataH fun createEntitySourceForSdk(): EntitySource { val virtualFileUrlManager = getVirtualFileUrlManager() - val globalLibrariesFile = virtualFileUrlManager.getOrCreateFromUrl( - PathManager.getOptionsFile(JpsGlobalEntitiesSerializers.SDK_FILE_NAME).absolutePath) - return JpsGlobalFileEntitySource(globalLibrariesFile) + val sdkFile = PathManager.getOptionsDir().resolve(JpsGlobalEntitiesSerializers.SDK_FILE_NAME + PathManager.DEFAULT_EXT) + return JpsGlobalFileEntitySource(virtualFileUrlManager.getOrCreateFromUrl(sdkFile.toAbsolutePath().toString())) } } } @@ -278,4 +277,4 @@ fun SdkEntity.Builder.applyChangesFrom(fromSdk: SdkEntity) { private fun getVirtualFileUrlManager(): VirtualFileUrlManager { // here we can use LocalEelMachine, as we simply need to get the virtual file url manager return GlobalWorkspaceModel.getInstance(LocalEelMachine).getVirtualFileUrlManager() -} \ No newline at end of file +} diff --git a/platform/util/api-dump-unreviewed.txt b/platform/util/api-dump-unreviewed.txt index f115437b6a69..a6bf5a9549d4 100644 --- a/platform/util/api-dump-unreviewed.txt +++ b/platform/util/api-dump-unreviewed.txt @@ -237,40 +237,16 @@ f:com.intellij.openapi.application.PathManager - sf:PROPERTY_SCRATCH_PATH:java.lang.String - sf:PROPERTY_SYSTEM_PATH:java.lang.String - sf:SYSTEM_PATHS_CUSTOMIZER:java.lang.String -- ():V -- s:findBinFile(java.lang.String):java.nio.file.Path -- s:findBinFileWithException(java.lang.String):java.nio.file.Path - s:getAbsolutePath(java.lang.String):java.lang.String -- s:getBinPath():java.lang.String - s:getBundledRuntimePath():java.lang.String -- s:getCommonDataPath():java.nio.file.Path -- s:getConfigDir():java.nio.file.Path -- s:getConfigPath():java.lang.String - s:getCustomOptionsDirectory():java.lang.String - s:getDefaultConfigPathFor(java.lang.String):java.lang.String - s:getDefaultSystemPathFor(java.lang.String):java.lang.String -- s:getHomePath():java.lang.String -- s:getHomePath(Z):java.lang.String - s:getJarForClass(java.lang.Class):java.nio.file.Path - s:getJarPathForClass(java.lang.Class):java.lang.String -- s:getLibPath():java.lang.String -- s:getLogDir():java.nio.file.Path -- s:getLogPath():java.lang.String -- s:getOptionsFile(java.lang.String):java.io.File -- s:getOptionsPath():java.lang.String -- s:getPluginTempPath():java.lang.String -- s:getPluginsDir():java.nio.file.Path -- s:getPluginsPath():java.lang.String - s:getPreInstalledPluginsPath():java.lang.String - s:getResourceRoot(java.lang.Class,java.lang.String):java.lang.String - s:getResourceRoot(java.lang.ClassLoader,java.lang.String):java.lang.String -- s:getScratchPath():java.lang.String -- s:getSystemDir():java.nio.file.Path -- s:getSystemPath():java.lang.String -- s:getTempPath():java.lang.String -- s:isUnderHomeDirectory(java.lang.String):Z -- s:isUnderHomeDirectory(java.nio.file.Path):Z -- s:setExplicitConfigPath(java.lang.String):V f:com.intellij.openapi.diagnostic.Attachment - sf:EMPTY_ARRAY:com.intellij.openapi.diagnostic.Attachment[] - (java.lang.String,java.io.File,java.lang.String):V diff --git a/platform/util/api-dump.txt b/platform/util/api-dump.txt index 2962dd2c0b94..fa98cfcc9d10 100644 --- a/platform/util/api-dump.txt +++ b/platform/util/api-dump.txt @@ -21,6 +21,36 @@ com.intellij.openapi.Disposable$Parent - a:beforeTreeDispose():V a:com.intellij.openapi.application.AccessToken - s:compound(java.util.List):com.intellij.openapi.application.AccessToken +f:com.intellij.openapi.application.PathManager +- s:findBinFile(java.lang.String):java.nio.file.Path +- s:findBinFileWithException(java.lang.String):java.nio.file.Path +- s:getBinDir():java.nio.file.Path +- s:getBinPath():java.lang.String +- s:getCommonDataPath():java.nio.file.Path +- s:getConfigDir():java.nio.file.Path +- s:getConfigPath():java.lang.String +- s:getHomeDir():java.nio.file.Path +- s:getHomeDir(Z):java.nio.file.Path +- s:getHomePath():java.lang.String +- s:getHomePath(Z):java.lang.String +- s:getLibDir():java.nio.file.Path +- s:getLibPath():java.lang.String +- s:getLogDir():java.nio.file.Path +- s:getLogPath():java.lang.String +- s:getOptionsDir():java.nio.file.Path +- s:getOptionsFile(java.lang.String):java.io.File +- s:getOptionsPath():java.lang.String +- s:getPluginTempPath():java.lang.String +- s:getPluginsDir():java.nio.file.Path +- s:getPluginsPath():java.lang.String +- s:getScratchDir():java.nio.file.Path +- s:getScratchPath():java.lang.String +- s:getSystemDir():java.nio.file.Path +- s:getSystemPath():java.lang.String +- s:getTempDir():java.nio.file.Path +- s:getTempPath():java.lang.String +- s:isUnderHomeDirectory(java.lang.String):Z +- s:isUnderHomeDirectory(java.nio.file.Path):Z com.intellij.openapi.diagnostic.ExceptionWithAttachments - a:getAttachments():com.intellij.openapi.diagnostic.Attachment[] com.intellij.openapi.diagnostic.Logger$Factory diff --git a/platform/util/src/com/intellij/openapi/application/PathManager.java b/platform/util/src/com/intellij/openapi/application/PathManager.java index 61a836195d5d..cb63bbb1b3e8 100644 --- a/platform/util/src/com/intellij/openapi/application/PathManager.java +++ b/platform/util/src/com/intellij/openapi/application/PathManager.java @@ -56,21 +56,23 @@ public final class PathManager { private static final Pattern PROPERTY_REF = Pattern.compile("\\$\\{(.+?)}"); } - private static volatile String ourHomePath; + private static volatile Path ourHomePath; private static volatile List ourBinDirectories; private static Path ourCommonDataPath; private static String ourPathSelector = System.getProperty(PROPERTY_PATHS_SELECTOR); - private static String ourConfigPath; - private static String ourSystemPath; - private static String ourScratchPath; - private static String ourPluginPath; - private static String ourLogPath; + private static Path ourConfigPath; + private static Path ourSystemPath; + private static Path ourScratchPath; + private static Path ourPluginPath; + private static Path ourLogPath; private static Path ourStartupScriptDir; private static Path ourOriginalConfigDir; private static Path ourOriginalSystemDir; private static Path ourOriginalLogDir; private static Map ourArchivedCompiledClassesMapping; + private PathManager() { } + /** * Returns paths to the directory where the IDE is installed, i.e., the directory containing 'lib', 'plugins' and other subdirectories. * On macOS, it's {@code .app/Contents} directory. @@ -80,17 +82,30 @@ public final class PathManager { * The method is supposed to be called from the main IDE process. For other processes started from the IDE process (e.g., build process) * use {@link #getHomePath(boolean)} with {@code false} argument. */ + public static @NotNull Path getHomeDir() { + return getHomeDir(true); + } + + /** Prefer {@link #getHomeDir()}. */ + @ApiStatus.Obsolete public static @NotNull String getHomePath() { - return getHomePath(true); + return getHomeDir().toString(); + } + + /** Prefer {@link #getHomeDir(boolean)}. */ + @ApiStatus.Obsolete + public static String getHomePath(boolean insideIde) { + Path homeDir = getHomeDir(insideIde); + return homeDir != null ? homeDir.toString() : null; } /** - * A variant of {@link #getHomePath()} which also works inside additional processes started from the main IDE process. + * A variant of {@link #getHomeDir()} which also works inside additional processes started from the main IDE process. * @param insideIde {@code true} if the calling code works inside IDE; {@code false} otherwise (e.g., in a build process or a script) */ @Contract("true -> !null") - public static String getHomePath(boolean insideIde) { - String result = ourHomePath; + public static Path getHomeDir(boolean insideIde) { + Path result = ourHomePath; if (result != null) return result; //noinspection SynchronizeOnThis @@ -98,18 +113,18 @@ public final class PathManager { result = ourHomePath; if (result != null) return result; - String explicit = getExplicitPath(PROPERTY_HOME_PATH); + Path explicit = getExplicitPath(PROPERTY_HOME_PATH); if (explicit == null) explicit = getExplicitPath(PROPERTY_HOME); if (explicit != null) { result = explicit; - if (!Files.isDirectory(Paths.get(result))) { + if (!Files.isDirectory(result)) { ourHomePath = result; throw new RuntimeException("Invalid home path '" + result + "'"); } } else if (insideIde) { //noinspection TestOnlyProblems - result = getHomePathFor(PathManager.class); + result = getHomeDirFor(PathManager.class); if (result == null) { String advice = SystemInfoRt.isMac ? "reinstall the software." : "make sure product-info.json is present in the installation directory."; throw new RuntimeException("Could not find installation home path. Please " + advice); @@ -118,7 +133,7 @@ public final class PathManager { if (result != null && SystemInfoRt.isWindows) { try { - result = Paths.get(result).toRealPath(LinkOption.NOFOLLOW_LINKS).toString(); + result = result.toRealPath(LinkOption.NOFOLLOW_LINKS); } catch (IOException ignored) { } } @@ -129,7 +144,7 @@ public final class PathManager { ourBinDirectories = Collections.emptyList(); } else { - Path root = Paths.get(result); + Path root = result; if (Boolean.getBoolean("idea.use.dev.build.server")) { while (root.getParent() != null) { if (Files.exists(root.resolve(ULTIMATE_MARKER)) || Files.exists(root.resolve(COMMUNITY_MARKER))) { @@ -251,8 +266,14 @@ public final class PathManager { /** * Bin path may be not what you want when developing an IDE. Consider using {@link #findBinFile(String)} if applicable. */ + public static @NotNull Path getBinDir() { + return getHomeDir().resolve(BIN_DIRECTORY); + } + + /** Prefer {@link #getBinDir()}. */ + @ApiStatus.Obsolete public static @NotNull String getBinPath() { - return getHomePath() + '/' + BIN_DIRECTORY; + return getBinDir().toString(); } /** @@ -295,8 +316,14 @@ public final class PathManager { /** * Returns the path to the directory where IDE's JAR files are stored. */ + public static @NotNull Path getLibDir() { + return getHomeDir().resolve(LIB_DIRECTORY); + } + + /** Prefer {@link #getLibDir()}. */ + @ApiStatus.Obsolete public static @NotNull String getLibPath() { - return getHomePath() + '/' + LIB_DIRECTORY; + return getLibDir().toString(); } /** @@ -355,37 +382,43 @@ public final class PathManager { * Usually, you don't need to access this directory directly, use {@link com.intellij.openapi.components.PersistentStateComponent} instead. */ public static @NotNull Path getConfigDir() { - return Paths.get(getConfigPath()); - } - - /** - * Returns the path to the directory where settings are stored. Consider using {@link #getConfigDir()} instead. - */ - public static @NotNull String getConfigPath() { - String path = ourConfigPath; + Path path = ourConfigPath; if (path == null) { - String explicit = getExplicitPath(PROPERTY_CONFIG_PATH); + Path explicit = getExplicitPath(PROPERTY_CONFIG_PATH); ourConfigPath = path = explicit != null ? explicit : - ourPathSelector != null ? getDefaultConfigPathFor(ourPathSelector) : - getHomePath() + '/' + CONFIG_DIRECTORY; + ourPathSelector != null ? Paths.get(getDefaultConfigPathFor(ourPathSelector)) : + getHomeDir().resolve(CONFIG_DIRECTORY); } return path; } + /** Prefer {@link #getConfigDir()}. */ + @ApiStatus.Obsolete + public static @NotNull String getConfigPath() { + return getConfigDir().toString(); + } + @TestOnly - public static void setExplicitConfigPath(@Nullable String path) { + @ApiStatus.Internal + public static void setExplicitConfigPath(@NotNull Path path) { ourConfigPath = path; } + /** Prefer {@link #getScratchDir()}. */ + @ApiStatus.Obsolete + public static @NotNull String getScratchPath() { + return getScratchDir().toString(); + } + /** * Returns the path to the directory where scratch files are stored. */ - public static @NotNull String getScratchPath() { - String path = ourScratchPath; + public static @NotNull Path getScratchDir() { + Path path = ourScratchPath; if (path == null) { - String explicit = getExplicitPath(PROPERTY_SCRATCH_PATH); - ourScratchPath = path = explicit == null ? getConfigPath() : explicit; + Path explicit = getExplicitPath(PROPERTY_SCRATCH_PATH); + ourScratchPath = path = explicit == null ? getConfigDir() : explicit; } return path; } @@ -397,40 +430,48 @@ public final class PathManager { return platformPath(selector, "Application Support", "", "APPDATA", "", "XDG_CONFIG_HOME", ".config", ""); } + /** Use {@link #getOptionsDir()} instead */ + @ApiStatus.Obsolete + public static @NotNull String getOptionsPath() { + return getOptionsDir().toString(); + } + /** * Returns the path to the directory where regular settings are stored. * Usually, you don't need to access this directory directly, use {@link com.intellij.openapi.components.PersistentStateComponent} instead. */ - public static @NotNull String getOptionsPath() { - return getConfigPath() + '/' + OPTIONS_DIRECTORY; + public static @NotNull Path getOptionsDir() { + return getConfigDir().resolve(OPTIONS_DIRECTORY); } /** - * Returns the path to a file with name {@code fileName} where regular settings are stored. - * Usually, you don't need to access this directory directly, use {@link com.intellij.openapi.components.PersistentStateComponent} instead. + * @deprecated prefer {@link com.intellij.openapi.components.PersistentStateComponent}, + * or use {@code PathManager.getOptionsDir().resolve(fileName + PathManager.DEFAULT_EXT)} instead. */ - public static @NotNull File getOptionsFile(@NotNull String fileName) { - return Paths.get(getOptionsPath(), fileName + DEFAULT_EXT).toFile(); + @Deprecated + @ApiStatus.ScheduledForRemoval + @SuppressWarnings({"IO_FILE_USAGE", "UnnecessaryFullyQualifiedName"}) + public static @NotNull java.io.File getOptionsFile(@NotNull String fileName) { + return getOptionsDir().resolve(fileName + DEFAULT_EXT).toFile(); + } + + /** Prefer {@link #getPluginsDir()}. */ + @ApiStatus.Obsolete + public static @NotNull String getPluginsPath() { + return getPluginsDir().toString(); } /** * Returns the path to the directory where custom plugins are stored. */ public static @NotNull Path getPluginsDir() { - return Paths.get(getPluginsPath()); - } - - /** - * Returns the path to the directory where custom plugins are stored. Consider using {@link #getPluginsDir()} instead. - */ - public static @NotNull String getPluginsPath() { - String path = ourPluginPath; + Path path = ourPluginPath; if (path == null) { - String explicit = getExplicitPath(PROPERTY_PLUGINS_PATH); + Path explicit = getExplicitPath(PROPERTY_PLUGINS_PATH); ourPluginPath = path = explicit != null ? explicit : - ourPathSelector != null && System.getProperty(PROPERTY_CONFIG_PATH) == null ? getDefaultPluginPathFor(ourPathSelector) : - getConfigPath() + '/' + PLUGINS_DIRECTORY; + ourPathSelector != null && System.getProperty(PROPERTY_CONFIG_PATH) == null ? Paths.get(getDefaultPluginPathFor(ourPathSelector)) : + getConfigDir().resolve(PLUGINS_DIRECTORY); } return path; } @@ -458,46 +499,51 @@ public final class PathManager { * {@link com.intellij.openapi.project.ProjectUtil#getProjectDataPath} instead. */ public static @NotNull Path getSystemDir() { - return Paths.get(getSystemPath()); - } - - /** - * Returns the path to the directory where caches are stored. - */ - public static @NotNull String getSystemPath() { - String path = ourSystemPath; + Path path = ourSystemPath; if (path == null) { - String explicit = getExplicitPath(PROPERTY_SYSTEM_PATH); + Path explicit = getExplicitPath(PROPERTY_SYSTEM_PATH); ourSystemPath = path = explicit != null ? explicit : - ourPathSelector != null ? getDefaultSystemPathFor(ourPathSelector) : - getHomePath() + '/' + SYSTEM_DIRECTORY; + ourPathSelector != null ? Paths.get(getDefaultSystemPathFor(ourPathSelector)) : + getHomeDir().resolve(SYSTEM_DIRECTORY); } return path; } + /** Prefer {@link #getSystemDir()}. */ + @ApiStatus.Obsolete + public static @NotNull String getSystemPath() { + return getSystemDir().toString(); + } + /** * Returns the path to the directory where caches are stored by default for IDE with the given path selector. */ public static @NotNull String getDefaultSystemPathFor(@NotNull String selector) { - return getDefaultSystemPathFor(OS.CURRENT, System.getProperty("user.home"), selector, System.getenv()).toString(); + return getDefaultSystemPathFor(OS.CURRENT, System.getProperty("user.home"), selector, System.getenv()); } @ApiStatus.Internal - public static @NotNull Path getDefaultSystemPathFor(@NotNull OS os, @NotNull String userHome, @NotNull String selector) { + public static @NotNull String getDefaultSystemPathFor(@NotNull OS os, @NotNull String userHome, @NotNull String selector) { return getDefaultSystemPathFor(os, userHome, selector, System.getenv()); } @ApiStatus.Internal - public static @NotNull Path getDefaultSystemPathFor(@NotNull OS os, @NotNull String userHome, @NotNull String selector, @NotNull Map env) { - return Paths.get(platformPath(os, env, userHome, selector, "Caches", "", "LOCALAPPDATA", "", "XDG_CACHE_HOME", ".cache", "")); + public static @NotNull String getDefaultSystemPathFor(@NotNull OS os, @NotNull String userHome, @NotNull String selector, @NotNull Map env) { + return platformPath(os, env, userHome, selector, "Caches", "", "LOCALAPPDATA", "", "XDG_CACHE_HOME", ".cache", ""); } /** * Returns the path to the directory to store temporary files. */ + public static @NotNull Path getTempDir() { + return getSystemDir().resolve("tmp"); + } + + /** Prefer {@link #getTempDir()}. */ + @ApiStatus.Obsolete public static @NotNull String getTempPath() { - return getSystemPath() + "/tmp"; + return getTempDir().toString(); } /** @@ -505,9 +551,8 @@ public final class PathManager { */ @ApiStatus.Internal public static @NotNull Path getIndexRoot() { - String indexRootPath = getExplicitPath("index_root_path"); - if (indexRootPath == null) indexRootPath = getSystemPath() + "/index"; - return Paths.get(indexRootPath); + Path explicit = getExplicitPath("index_root_path"); + return explicit != null ? explicit : getSystemDir().resolve("index"); } /** @@ -515,24 +560,23 @@ public final class PathManager { * Usually you don't need to access it directly, use {@link Logger} instead. */ public static @NotNull Path getLogDir() { - return Paths.get(getLogPath()); - } - - /** - * Returns the path to the directory where log files are stored. Consider using {@link #getLogDir()} instead. - */ - public static @NotNull String getLogPath() { - String path = ourLogPath; + Path path = ourLogPath; if (path == null) { - String explicit = getExplicitPath(PROPERTY_LOG_PATH); + Path explicit = getExplicitPath(PROPERTY_LOG_PATH); ourLogPath = path = explicit != null ? explicit : - ourPathSelector != null && System.getProperty(PROPERTY_SYSTEM_PATH) == null ? getDefaultLogPathFor(ourPathSelector) : - getSystemPath() + '/' + LOG_DIRECTORY; + ourPathSelector != null && System.getProperty(PROPERTY_SYSTEM_PATH) == null ? Paths.get(getDefaultLogPathFor(ourPathSelector)) : + getSystemDir().resolve(LOG_DIRECTORY); } return path; } + /** Prefer {@link #getLogDir()}. */ + @ApiStatus.Obsolete + public static @NotNull String getLogPath() { + return getLogDir().toString(); + } + /** * Returns the path to the directory where log files are stored by default for IDE with the given path selector. */ @@ -547,18 +591,17 @@ public final class PathManager { */ @ApiStatus.Internal public static @NotNull Path getStartupScriptDir() { - if (ourStartupScriptDir != null) return ourStartupScriptDir; - return getSystemDir().resolve(PLUGINS_DIRECTORY); + return ourStartupScriptDir != null ? ourStartupScriptDir : getSystemDir().resolve(PLUGINS_DIRECTORY); } /** - * This method isn't supposed to be used in new code. If you need to locate a directory where the startup script and related files are - * located, use {@link #getStartupScriptDir()} instead. If you need to save some custom caches related to plugins, create your own - * directory under {@link #getSystemDir()}. + * @deprecated for a directory where the startup script and related files are located, use {@link #getStartupScriptDir()} instead. + * If you need to save some custom caches related to plugins, create your own directory under {@link #getSystemDir()}. */ - @ApiStatus.Obsolete + @Deprecated + @ApiStatus.ScheduledForRemoval public static @NotNull String getPluginTempPath() { - return getSystemPath() + '/' + PLUGINS_DIRECTORY; + return getSystemDir().resolve(PLUGINS_DIRECTORY).toString(); } // misc stuff @@ -878,13 +921,13 @@ public final class PathManager { return Paths.get(path).toAbsolutePath().normalize().toString(); } - private static @Nullable String getExplicitPath(String property) { + private static @Nullable Path getExplicitPath(String property) { String path = System.getProperty(property); if (path == null) return null; try { boolean quoted = path.length() > 1 && '"' == path.charAt(0) && '"' == path.charAt(path.length() - 1); - return getAbsolutePath(quoted ? path.substring(1, path.length() - 1) : path); + return toAbsoluteNormalizedPath(quoted ? path.substring(1, path.length() - 1) : path); } catch (InvalidPathException e) { Logger.getInstance(PathManager.class).error("Invalid value for property '" + property + "'", e); @@ -892,6 +935,13 @@ public final class PathManager { } } + private static Path toAbsoluteNormalizedPath(@NotNull String path) { + if (path.startsWith("~/") || path.startsWith("~\\")) { + path = System.getProperty("user.home") + path.substring(1); + } + return Paths.get(path).toAbsolutePath().normalize(); + } + private static String platformPath( String selector, String macDir, String macSub, diff --git a/platform/workspace/jps/tests/testSrc/com/intellij/workspaceModel/ide/impl/jps/serialization/jpsTestUtils.kt b/platform/workspace/jps/tests/testSrc/com/intellij/workspaceModel/ide/impl/jps/serialization/jpsTestUtils.kt index e255451a183d..5afac7f39ca0 100644 --- a/platform/workspace/jps/tests/testSrc/com/intellij/workspaceModel/ide/impl/jps/serialization/jpsTestUtils.kt +++ b/platform/workspace/jps/tests/testSrc/com/intellij/workspaceModel/ide/impl/jps/serialization/jpsTestUtils.kt @@ -21,7 +21,6 @@ import com.intellij.openapi.util.io.systemIndependentPath import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.vfs.VfsUtilCore -import com.intellij.platform.eel.provider.LocalEelDescriptor import com.intellij.platform.eel.provider.LocalEelMachine import com.intellij.platform.workspace.jps.* import com.intellij.platform.workspace.jps.entities.LibraryEntity @@ -52,7 +51,6 @@ import java.nio.file.Files import java.nio.file.Paths import java.util.function.Supplier import kotlin.coroutines.EmptyCoroutineContext -import kotlin.io.path.Path internal val sampleDirBasedProjectFile = File(PathManagerEx.getCommunityHomePath(), "jps/model-serialization/testData/sampleProject") internal val sampleFileBasedProjectFile = File(PathManagerEx.getCommunityHomePath(), @@ -437,9 +435,9 @@ internal fun copyAndLoadGlobalEntities(originalFile: String? = null, parentDisposable: Disposable, action: (JpsGlobalFileEntitySource, JpsGlobalFileEntitySource) -> Unit) { val stateStore = ApplicationManager.getApplication().stateStore - val oldConfigPath = PathManager.getConfigPath() + val oldConfigDir = PathManager.getConfigDir() try { - PathManager.setExplicitConfigPath(testDir.absolutePath) + PathManager.setExplicitConfigPath(testDir.toPath()) stateStore.setPath(testDir.toPath()) stateStore.clearCaches() @@ -487,8 +485,8 @@ internal fun copyAndLoadGlobalEntities(originalFile: String? = null, } } finally { - PathManager.setExplicitConfigPath(oldConfigPath) - stateStore.setPath(Path(oldConfigPath)) + PathManager.setExplicitConfigPath(oldConfigDir) + stateStore.setPath(oldConfigDir) stateStore.clearCaches() } }