From 82b321d57ce6f72ee93c89f17cfc1fc411247576 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 6 Feb 2024 16:21:10 +0100 Subject: [PATCH] IJPL-594 update fastutil 8.5.11 -> 8.5.13 (part 2) GitOrigin-RevId: 4f55be9e64dc4a484750762590056d478b746c97 --- .idea/libraries/fastutil_min.xml | 10 +-- .../java/dependencyView/Mappings.java | 11 ++- .../ObjectObjectTransientMultiMaplet.java | 20 +++--- platform/build-scripts/codeOptimizer/Makefile | 31 --------- ...ij.platform.buildScripts.codeOptimizer.iml | 6 +- .../codeOptimizer/src/fastutil.conf | 9 +++ .../codeOptimizer/src/optimizeLib.kt | 61 +++++++++++++++-- .../com/intellij/lang/impl/MarkerPool.java | 56 +++++++-------- .../intellij/lang/impl/PsiBuilderImpl.java | 38 +++++------ .../application/impl/BulkArrayQueue.java | 20 +++--- .../openapi/application/impl/FlushQueue.java | 7 +- .../newvfs/persistent/PersistentFSImpl.java | 11 +-- .../intellij/openapi/util/io/FileUtilRt.java | 35 ++++++---- .../util/containers/CollectionFactory.java | 12 ++-- .../containers/FastUtilHashingStrategies.java | 14 +++- .../containers/FileCollectionFactory.java | 27 +++----- .../intellij/openapi/util/io/FileUtil.java | 68 +++++++++++++++---- .../GradleServerEnvironmentSetupImpl.kt | 29 ++++---- 18 files changed, 268 insertions(+), 197 deletions(-) delete mode 100644 platform/build-scripts/codeOptimizer/Makefile diff --git a/.idea/libraries/fastutil_min.xml b/.idea/libraries/fastutil_min.xml index 582b096d1f03..65fc8c6832aa 100644 --- a/.idea/libraries/fastutil_min.xml +++ b/.idea/libraries/fastutil_min.xml @@ -1,9 +1,9 @@ - + - - 19d613c22adbaf9cef204d2f4d6f17afe1389087f80728c04aa982c62b5a2cf3 + + d6b7fe103081df530137df0e3df5a9d2ebaef1577f93fcded06186e0f74996b9 @@ -11,11 +11,11 @@ - + - + \ No newline at end of file diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java index a74a5c106c3a..b7188242760b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java @@ -1,4 +1,4 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.jps.builders.java.dependencyView; import com.intellij.openapi.diagnostic.Logger; @@ -7,10 +7,7 @@ import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.SmartList; -import com.intellij.util.containers.CollectionFactory; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.FileCollectionFactory; -import com.intellij.util.containers.SmartHashSet; +import com.intellij.util.containers.*; import com.intellij.util.io.EnumeratorIntegerDescriptor; import it.unimi.dsi.fastutil.ints.IntConsumer; import it.unimi.dsi.fastutil.ints.IntIterator; @@ -144,7 +141,7 @@ public class Mappings { myClassToClassDependency = new IntIntTransientMultiMaplet(); myShortClassNameIndex = null; myRelativeSourceFilePathToClasses = new ObjectObjectTransientMultiMaplet<>( - FileCollectionFactory.FILE_PATH_HASH_STRATEGY, () -> new HashSet<>(5, DEFAULT_SET_LOAD_FACTOR) + FastUtilHashingStrategies.FILE_PATH_HASH_STRATEGY, () -> new HashSet<>(5, DEFAULT_SET_LOAD_FACTOR) ); myClassToRelativeSourceFilePath = new IntObjectTransientMultiMaplet<>(fileCollectionFactory); } @@ -171,7 +168,7 @@ public class Mappings { ) { @Override protected @NotNull String debugString(String path) { - // on case-insensitive file systems save paths in normalized (lowercase) format in order to make tests run deterministically + // on case-insensitive file systems save paths in normalized (lowercase) format to make tests run deterministically return SystemInfo.isFileSystemCaseSensitive ? path : path.toLowerCase(Locale.US); } }; diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ObjectObjectTransientMultiMaplet.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ObjectObjectTransientMultiMaplet.java index 1560033748bb..37ae8592552c 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ObjectObjectTransientMultiMaplet.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ObjectObjectTransientMultiMaplet.java @@ -1,9 +1,9 @@ -// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.jps.builders.java.dependencyView; import com.intellij.util.PairProcessor; -import com.intellij.util.containers.CollectionFactory; -import com.intellij.util.containers.HashingStrategy; +import it.unimi.dsi.fastutil.Hash; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -14,11 +14,11 @@ import java.util.function.Supplier; * @author Eugene Zhuravlev */ public final class ObjectObjectTransientMultiMaplet extends ObjectObjectMultiMaplet{ - private final Map> myMap; + private final Object2ObjectOpenCustomHashMap> myMap; private final Supplier> myCollectionFactory; - public ObjectObjectTransientMultiMaplet(HashingStrategy hashingStrategy, Supplier> collectionFactory) { - myMap = CollectionFactory.createCustomHashingStrategyMap(hashingStrategy); + public ObjectObjectTransientMultiMaplet(Hash.Strategy hashingStrategy, Supplier> collectionFactory) { + myMap = new Object2ObjectOpenCustomHashMap<>(hashingStrategy); myCollectionFactory = collectionFactory; } @@ -89,12 +89,8 @@ public final class ObjectObjectTransientMultiMaplet ext @Override public void removeAll(K key, Collection values) { final Collection collection = myMap.get(key); - if (collection != null) { - if (collection.removeAll(values)) { - if (collection.isEmpty()) { - myMap.remove(key); - } - } + if (collection != null && collection.removeAll(values) && collection.isEmpty()) { + myMap.remove(key); } } diff --git a/platform/build-scripts/codeOptimizer/Makefile b/platform/build-scripts/codeOptimizer/Makefile deleted file mode 100644 index 18a87bc8df4e..000000000000 --- a/platform/build-scripts/codeOptimizer/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -VERSION := 8.5.13 - -install: - mvn install:install-file -DgroupId=org.jetbrains.intellij.deps.fastutil \ - -DartifactId=intellij-deps-fastutil \ - -Dversion=$(VERSION) \ - -Dpackaging=jar \ - -Dfile=out/fastutil.jar - mvn install:install-file -DgroupId=org.jetbrains.intellij.deps.fastutil \ - -DartifactId=intellij-deps-fastutil \ - -Dversion=$(VERSION) \ - -Dpackaging=java-source \ - -DgeneratePom=false \ - -Dfile=out/fastutil-sources.jar - -deploy: install - mvn deploy:deploy-file -DgroupId=org.jetbrains.intellij.deps.fastutil \ - -DartifactId=intellij-deps-fastutil \ - -Dversion=$(VERSION) \ - -Dpackaging=jar \ - -Dfile=out/fastutil.jar \ - -DrepositoryId=space-intellij-dependencies \ - -Durl=https://packages.jetbrains.team/maven/p/ij/intellij-dependencies - mvn deploy:deploy-file -DgroupId=org.jetbrains.intellij.deps.fastutil \ - -DartifactId=intellij-deps-fastutil \ - -Dversion=$(VERSION) \ - -DgeneratePom=false \ - -Dpackaging=java-source \ - -Dfile=out/fastutil-sources.jar \ - -DrepositoryId=space-intellij-dependencies \ - -Durl=https://packages.jetbrains.team/maven/p/ij/intellij-dependencies \ No newline at end of file diff --git a/platform/build-scripts/codeOptimizer/intellij.platform.buildScripts.codeOptimizer.iml b/platform/build-scripts/codeOptimizer/intellij.platform.buildScripts.codeOptimizer.iml index 602f94e3cff7..fff101dad2ea 100644 --- a/platform/build-scripts/codeOptimizer/intellij.platform.buildScripts.codeOptimizer.iml +++ b/platform/build-scripts/codeOptimizer/intellij.platform.buildScripts.codeOptimizer.iml @@ -3,12 +3,12 @@ - + - - + + diff --git a/platform/build-scripts/codeOptimizer/src/fastutil.conf b/platform/build-scripts/codeOptimizer/src/fastutil.conf index cad2fb72972d..d2c02a7ebfd6 100644 --- a/platform/build-scripts/codeOptimizer/src/fastutil.conf +++ b/platform/build-scripts/codeOptimizer/src/fastutil.conf @@ -169,4 +169,13 @@ -keepclassmembers,allowoptimization enum * { public static **[] values(); public static ** valueOf(java.lang.String); +} + +-keepclassmembers class * implements java.io.Serializable { + static final long serialVersionUID; + private static final java.io.ObjectStreamField[] serialPersistentFields; + private void writeObject(java.io.ObjectOutputStream); + private void readObject(java.io.ObjectInputStream); + java.lang.Object writeReplace(); + java.lang.Object readResolve(); } \ No newline at end of file diff --git a/platform/build-scripts/codeOptimizer/src/optimizeLib.kt b/platform/build-scripts/codeOptimizer/src/optimizeLib.kt index b4b01ff77ed5..88e7cf9e6b16 100644 --- a/platform/build-scripts/codeOptimizer/src/optimizeLib.kt +++ b/platform/build-scripts/codeOptimizer/src/optimizeLib.kt @@ -14,11 +14,58 @@ import kotlin.time.measureTime internal data class OptimizeLibraryContext(@JvmField val tempDir: Path, @JvmField val javaHome: Path) -// The Maven Java API can appear somewhat complex and broad, making certain tasks cumbersome. -// Hence, we depend on the prerequisite that the original library is already resolved and stored in the local Maven repository. +private data class LibDescriptor(@JvmField val id: String, @JvmField val version: String, @JvmField val jbVersion: Int) + +private val fastUtil = LibDescriptor(id = "fastutil", version = "8.5.13", jbVersion = 3) + +@Suppress("unused") +internal object FastutilInstall { + @JvmStatic + fun main(args: Array) { + publishToMaven(fastUtil, deploy = false) + } +} + +@Suppress("SpellCheckingInspection", "RedundantSuppression", "SameParameterValue") +private fun publishToMaven( + @Suppress("SameParameterValue") lib: LibDescriptor, + deploy: Boolean, +) { + for (extraArgs in listOf( + listOf("-Dpackaging=jar", "-Dfile=out/${lib.id}.jar"), + listOf("-Dpackaging=java-source", "-Dfile=out/${lib.id}-sources.jar", "-DgeneratePom=false"), + listOf("-Dpackaging=txt", "-Dclassifier=proguard-map", "-Dfile=out/${lib.id}-proguard-map.txt", "-DgeneratePom=false"), + )) { + val list = mutableListOf( + "mvn", + if (deploy) "deploy:deploy-file" else "install:install-file", + "-DgroupId=org.jetbrains.intellij.deps.fastutil", + "-DartifactId=intellij-deps-fastutil", + "-Dversion=${lib.version}-jb${lib.jbVersion}", + ) + list.addAll(extraArgs) + + if (deploy) { + list.addAll(listOf( + "-DrepositoryId=space-intellij-dependencies", + "-Durl=https://packages.jetbrains.team/maven/p/ij/intellij-dependencies", + )) + } + + executeMaven(list) + } +} + +@Suppress("SpellCheckingInspection", "RedundantSuppression") internal object LibraryCodeOptimizer { @JvmStatic fun main(args: Array) { + val version = fastUtil.version + // The Maven Java API can appear somewhat complex and broad, making certain tasks cumbersome. + // Use CLI. + executeMaven(listOf("mvn", "org.apache.maven.plugins:maven-dependency-plugin:get", "-Dartifact=it.unimi.dsi:fastutil:$version")) + executeMaven(listOf("mvn", "org.apache.maven.plugins:maven-dependency-plugin:get", "-Dartifact=it.unimi.dsi:fastutil:$version:java-source:sources")) + val m2 = Path.of(System.getProperty("user.home")).resolve(".m2/repository") val outDir = Path.of("out").toAbsolutePath() val output = outDir.resolve("fastutil.jar") @@ -27,9 +74,8 @@ internal object LibraryCodeOptimizer { } //val input = m2.resolve("com/github/weisj/jsvg/1.3.0-jb.3/jsvg-1.3.0-jb.3.jar") - val version = "8.5.13-jb.1" val input = m2.resolve("it/unimi/dsi/fastutil/$version/fastutil-$version.jar") - val mapping = outDir.resolve("fastutil-map.txt") + val mapping = outDir.resolve("fastutil-proguard-map.txt") val duration = measureTime { optimizeLibrary(name = "fastutil", input = input, @@ -49,6 +95,13 @@ internal object LibraryCodeOptimizer { } } +private fun executeMaven(command: List) { + ProcessBuilder(command) + .inheritIO() + .start() + .waitFor() +} + //private fun cleanZip(file: Path): Path { // val tempFile = Files.createTempFile(file.parent, file.fileName.toString(), ".jar") // ZipFileWriter(channel = FileChannel.open(tempFile, EnumSet.of(StandardOpenOption.WRITE))).use { zipFileWriter -> diff --git a/platform/core-impl/src/com/intellij/lang/impl/MarkerPool.java b/platform/core-impl/src/com/intellij/lang/impl/MarkerPool.java index 4d46e999a48f..0d62bf199755 100644 --- a/platform/core-impl/src/com/intellij/lang/impl/MarkerPool.java +++ b/platform/core-impl/src/com/intellij/lang/impl/MarkerPool.java @@ -1,57 +1,49 @@ -/* - * Copyright 2000-2017 JetBrains s.r.o. - * - * 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. - */ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.lang.impl; import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; -@SuppressWarnings("SSBasedInspection") -final class MarkerPool extends ObjectArrayList { - private final PsiBuilderImpl myBuilder; - private final IntArrayList myFreeStartMarkers = new IntArrayList(); - private final IntArrayList myFreeErrorItems = new IntArrayList(); +import java.util.ArrayList; + +@SuppressWarnings({"SSBasedInspection", "RedundantSuppression"}) +final class MarkerPool { + private final PsiBuilderImpl builder; + private final IntArrayList freeStartMarkers = new IntArrayList(); + private final IntArrayList freeErrorItems = new IntArrayList(); + + final ArrayList list = new ArrayList<>(); MarkerPool(PsiBuilderImpl builder) { - myBuilder = builder; - add(null); //no marker has id 0 + this.builder = builder; + list.add(null); //no marker has id 0 } PsiBuilderImpl.StartMarker allocateStartMarker() { - if (myFreeStartMarkers.size() > 0) { - return (PsiBuilderImpl.StartMarker)get(myFreeStartMarkers.popInt()); + if (!freeStartMarkers.isEmpty()) { + return (PsiBuilderImpl.StartMarker)list.get(freeStartMarkers.popInt()); } - PsiBuilderImpl.StartMarker marker = new PsiBuilderImpl.StartMarker(size(), myBuilder); - add(marker); + PsiBuilderImpl.StartMarker marker = new PsiBuilderImpl.StartMarker(list.size(), builder); + list.add(marker); return marker; } PsiBuilderImpl.ErrorItem allocateErrorItem() { - if (myFreeErrorItems.size() > 0) { - return (PsiBuilderImpl.ErrorItem)get(myFreeErrorItems.popInt()); + if (!freeErrorItems.isEmpty()) { + return (PsiBuilderImpl.ErrorItem)list.get(freeErrorItems.popInt()); } - PsiBuilderImpl.ErrorItem item = new PsiBuilderImpl.ErrorItem(size(), myBuilder); - add(item); + PsiBuilderImpl.ErrorItem item = new PsiBuilderImpl.ErrorItem(list.size(), builder); + list.add(item); return item; } void freeMarker(PsiBuilderImpl.ProductionMarker marker) { marker.clean(); - (marker instanceof PsiBuilderImpl.StartMarker ? myFreeStartMarkers : myFreeErrorItems).push(marker.markerId); + (marker instanceof PsiBuilderImpl.StartMarker ? freeStartMarkers : freeErrorItems).push(marker.markerId); } + PsiBuilderImpl.ProductionMarker get(int index) { + return list.get(index); + } } diff --git a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java index 406c7d6c67cd..12a766a84b00 100644 --- a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java +++ b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java @@ -1,4 +1,4 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.lang.impl; import com.intellij.lang.*; @@ -36,16 +36,12 @@ import com.intellij.util.text.CharArrayUtil; import com.intellij.util.text.CharSequenceSubSequence; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.AbstractList; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; +import java.util.*; import java.util.function.Function; import static com.intellij.lang.WhitespacesBinders.DEFAULT_RIGHT_BINDER; @@ -94,9 +90,9 @@ public class PsiBuilderImpl extends UnprotectedUserDataHolder implements PsiBuil private IElementType myCachedTokenType; private final Int2ObjectMap myChameleonCache = new Int2ObjectOpenHashMap<>(); - private final MarkerPool myPool = new MarkerPool(this); + private final MarkerPool pool = new MarkerPool(this); private final MarkerOptionalData myOptionalData = new MarkerOptionalData(); - private final MarkerProduction myProduction = new MarkerProduction(myPool, myOptionalData); + private final MarkerProduction myProduction = new MarkerProduction(pool, myOptionalData); public static void registerWhitespaceToken(@NotNull IElementType type) { ourAnyLanguageWhitespaceTokens = TokenSet.orSet(ourAnyLanguageWhitespaceTokens, TokenSet.create(type)); @@ -387,7 +383,7 @@ public class PsiBuilderImpl extends UnprotectedUserDataHolder implements PsiBuil @Override public void doneBefore(@NotNull IElementType type, @NotNull Marker before, @NotNull @Nls String errorMessage) { StartMarker marker = (StartMarker)before; - ErrorItem errorItem = myBuilder.myPool.allocateErrorItem(); + ErrorItem errorItem = myBuilder.pool.allocateErrorItem(); errorItem.setMessage(errorMessage); errorItem.myLexemeIndex = marker.myLexemeIndex; myBuilder.myProduction.addBefore(errorItem, marker); @@ -835,7 +831,7 @@ public class PsiBuilderImpl extends UnprotectedUserDataHolder implements PsiBuil } private @NotNull StartMarker createMarker(int lexemeIndex) { - StartMarker marker = myPool.allocateStartMarker(); + StartMarker marker = pool.allocateStartMarker(); marker.myLexemeIndex = lexemeIndex; if (myDebugMode) { myOptionalData.notifyAllocated(marker.markerId); @@ -912,7 +908,7 @@ public class PsiBuilderImpl extends UnprotectedUserDataHolder implements PsiBuil if (lastMarker instanceof ErrorItem && lastMarker.myLexemeIndex == myCurrentLexeme) { return; } - ErrorItem marker = myPool.allocateErrorItem(); + ErrorItem marker = pool.allocateErrorItem(); marker.setMessage(messageText); marker.myLexemeIndex = myCurrentLexeme; myProduction.addMarker(marker); @@ -1036,25 +1032,24 @@ public class PsiBuilderImpl extends UnprotectedUserDataHolder implements PsiBuil rootMarker.myParent = rootMarker.myFirstChild = rootMarker.myLastChild = rootMarker.myNext = null; StartMarker curNode = rootMarker; - ObjectArrayList nodes = new ObjectArrayList<>(); - nodes.push(rootMarker); + ArrayDeque nodes = new ArrayDeque<>(); + nodes.addLast(rootMarker); int lastErrorIndex = -1; int maxDepth = 0; int curDepth = 0; boolean hasCollapsedChameleons = false; int[] productions = myProduction.elements(); - Object[] markers = myPool.elements(); for (int i = 1, size = myProduction.size(); i < size; i++) { int id = productions[i]; - ProductionMarker item = id > 0 ? (ProductionMarker)markers[id] : null; + ProductionMarker item = id > 0 ? pool.get(id) : null; if (item instanceof StartMarker) { StartMarker marker = (StartMarker)item; marker.myParent = curNode; marker.myFirstChild = marker.myLastChild = marker.myNext = null; curNode.addChild(marker); - nodes.push(curNode); + nodes.addLast(curNode); curNode = marker; curDepth++; if (curDepth > maxDepth) maxDepth = curDepth; @@ -1070,8 +1065,8 @@ public class PsiBuilderImpl extends UnprotectedUserDataHolder implements PsiBuil if (isCollapsedChameleon(curNode)) { hasCollapsedChameleons = true; } - assertMarkersBalanced(id < 0 && markers[-id] == curNode, item); - curNode = nodes.pop(); + assertMarkersBalanced(id < 0 && pool.get(-id) == curNode, item); + curNode = nodes.removeLast(); curDepth--; } } @@ -1124,15 +1119,14 @@ public class PsiBuilderImpl extends UnprotectedUserDataHolder implements PsiBuil int lastIndex = 0; int[] productions = myProduction.elements(); - Object[] markers = myPool.elements(); for (int i = 1, size = myProduction.size() - 1; i < size; i++) { int id = productions[i]; - ProductionMarker starting = id > 0 ? (ProductionMarker)markers[id] : null; + ProductionMarker starting = id > 0 ? pool.get(id) : null; if (starting instanceof StartMarker) { assertMarkersBalanced(((StartMarker)starting).isDone(), starting); } boolean done = starting == null; - ProductionMarker item = starting != null ? starting : (ProductionMarker)markers[-id]; + ProductionMarker item = starting != null ? starting : pool.get(-id); WhitespacesAndCommentsBinder binder; if (item instanceof ErrorItem) { @@ -1151,7 +1145,7 @@ public class PsiBuilderImpl extends UnprotectedUserDataHolder implements PsiBuil } else { int prevId = productions[i - 1]; - prevProductionLexIndex = ((ProductionMarker)markers[Math.abs(prevId)]).getLexemeIndex(prevId < 0); + prevProductionLexIndex = pool.get(Math.abs(prevId)).getLexemeIndex(prevId < 0); } int wsStartIndex = Math.max(lexemeIndex, lastIndex); while (wsStartIndex > prevProductionLexIndex && whitespaceOrComment(myLexTypes[wsStartIndex - 1])) wsStartIndex--; diff --git a/platform/core-impl/src/com/intellij/openapi/application/impl/BulkArrayQueue.java b/platform/core-impl/src/com/intellij/openapi/application/impl/BulkArrayQueue.java index 8344e26744f3..77b106166591 100644 --- a/platform/core-impl/src/com/intellij/openapi/application/impl/BulkArrayQueue.java +++ b/platform/core-impl/src/com/intellij/openapi/application/impl/BulkArrayQueue.java @@ -1,16 +1,16 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi.application.impl; -import it.unimi.dsi.fastutil.objects.ObjectList; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.jetbrains.annotations.NotNull; import java.util.function.Predicate; // array-backed queue with additional support for fast bulk inserts -class BulkArrayQueue { +final class BulkArrayQueue { // maintain wrap-around queue using these pointers into myQueue private int tail; // index at which the next element would be stored via enqueue() - private int head; // index to stored element to be returned by pollFirst(); if tail==head the queue is empty + private int head; // index to a stored element to be returned by pollFirst(); if tail==head the queue is empty private Object[] myQueue = new Object[1024]; void enqueue(@NotNull T info) { @@ -69,7 +69,7 @@ class BulkArrayQueue { } // insert all from "elements" before "head" - void bulkEnqueueFirst(@NotNull ObjectList elements) { + void bulkEnqueueFirst(@NotNull ObjectArrayList elements) { int insertSize = elements.size(); int oldCapacity = myQueue.length; int emptySpace = oldCapacity - size() - 1; @@ -88,20 +88,20 @@ class BulkArrayQueue { } void removeAll(@NotNull Predicate shouldRemove) { + int o; if (head <= tail) { // shift alive items in [head..tail) left to head - int o = head; + o = head; for (int i=head; i=head; i--) { T info = getAndNullize(i); if (!shouldRemove.test(info)) { @@ -117,8 +117,8 @@ class BulkArrayQueue { myQueue[o++] = info; } } - tail = o; } + tail = o; } boolean isEmpty() { diff --git a/platform/core-impl/src/com/intellij/openapi/application/impl/FlushQueue.java b/platform/core-impl/src/com/intellij/openapi/application/impl/FlushQueue.java index 897c6cf7422a..0d040f2b3943 100644 --- a/platform/core-impl/src/com/intellij/openapi/application/impl/FlushQueue.java +++ b/platform/core-impl/src/com/intellij/openapi/application/impl/FlushQueue.java @@ -1,4 +1,4 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi.application.impl; import com.intellij.codeWithMe.ClientId; @@ -15,7 +15,6 @@ import com.intellij.openapi.util.Condition; import com.intellij.util.ExceptionUtil; import com.intellij.util.concurrency.ThreadingAssertions; import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import it.unimi.dsi.fastutil.objects.ObjectList; import org.jetbrains.annotations.*; import javax.swing.*; @@ -26,7 +25,7 @@ final class FlushQueue { private static final Logger LOG = Logger.getInstance(FlushQueue.class); private static final ThrottledLogger THROTTLED_LOG = new ThrottledLogger(LOG, MINUTES.toMillis(1)); - private ObjectList mySkippedItems = new ObjectArrayList<>(100); //guarded by getQueueLock() + private ObjectArrayList mySkippedItems = new ObjectArrayList<>(100); //guarded by getQueueLock() private final BulkArrayQueue myQueue = new BulkArrayQueue<>(); //guarded by getQueueLock() private void flushNow() { @@ -110,7 +109,7 @@ final class FlushQueue { // (in .reincludeSkippedItems()) and also reset queueSize/queuedTimeNs fields. // This way we got queue loading info 'cleared' (kind of) from bypassing influence, // i.e. re-appended tasks will look as-if they were just added -- which is not strictly true, - // but it will disturb waiting times much less then current approach there skipped/not skipped + // but it will disturb waiting times much less than the current approach there skipped/not skipped // tasks waiting times stats are merged together. mySkippedItems.add(info.wasSkipped()); } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java index 8f92add5110c..a3d54799811e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java @@ -49,8 +49,10 @@ import com.intellij.util.*; import com.intellij.util.containers.*; import com.intellij.util.io.ReplicatorInputStream; import com.intellij.util.io.storage.HeavyProcessLatch; -import it.unimi.dsi.fastutil.ints.*; +import it.unimi.dsi.fastutil.Hash; import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.*; +import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenCustomHashSet; import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; import org.jetbrains.annotations.*; @@ -1156,9 +1158,8 @@ public final class PersistentFSImpl extends PersistentFS implements Disposable { } else { if (createEvents instanceof VFileCreateEvent prevEvent) { - Set children = parent.isCaseSensitive() - ? new LinkedHashSet<>() - : CollectionFactory.createLinkedCustomHashingStrategySet(CASE_INSENSITIVE_STRATEGY); + Set children; + children = parent.isCaseSensitive() ? new LinkedHashSet<>() : new ObjectLinkedOpenCustomHashSet<>(CASE_INSENSITIVE_STRATEGY); children.add(prevEvent); toCreate.put(parent, children); createEvents = children; @@ -2467,7 +2468,7 @@ public final class PersistentFSImpl extends PersistentFS implements Disposable { (areChildrenCaseSensitive ? Flags.CHILDREN_CASE_SENSITIVE : 0); } - private static final HashingStrategy CASE_INSENSITIVE_STRATEGY = new HashingStrategy<>() { + private static final Hash.Strategy CASE_INSENSITIVE_STRATEGY = new Hash.Strategy<>() { @Override public int hashCode(@Nullable VFileCreateEvent object) { return object == null ? 0 : Strings.stringHashCodeInsensitive(object.getChildName()); diff --git a/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java index de2034cbe297..2c888bbd3b21 100644 --- a/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java +++ b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java @@ -1,4 +1,4 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi.util.io; import com.intellij.openapi.diagnostic.LoggerRt; @@ -23,7 +23,7 @@ import static java.lang.System.getProperty; * A stripped-down version of {@link com.intellij.openapi.util.io.FileUtil}. * Intended to use by external (out-of-IDE-process) runners and helpers, so it should not contain any library dependencies. */ -public class FileUtilRt { +public final class FileUtilRt { private static final int KILOBYTE = 1024; private static final int DEFAULT_INTELLISENSE_LIMIT = 2500 * KILOBYTE; @@ -98,7 +98,7 @@ public class FileUtilRt { } @Contract("null, _, _, _ -> null; !null,_,_,_->!null") - protected static String toCanonicalPath(@Nullable String path, + static String toCanonicalPath(@Nullable String path, char separatorChar, boolean removeLastSlash, @Nullable SymlinkResolver resolver) { @@ -522,16 +522,18 @@ public class FileUtilRt { if (attempts > maxFileNumber / 2 || attempts > MAX_ATTEMPTS) { String[] children = dir.list(); int size = children == null ? 0 : children.length; - maxFileNumber = Math.max(10, size * 10); // if too many files are in tmp dir, we need a bigger random range than meager 10 + maxFileNumber = Math.max(10, size * 10); // if too many files are in tmp dir, we need a bigger random range than a meager 10 if (attempts > MAX_ATTEMPTS) { throw exception != null ? exception: new IOException("Unable to create a temporary file " + f + "\nDirectory '" + dir + "' list ("+size+" children): " + Arrays.toString(children)); } } - i++; // for some reason the file1 can't be created (previous file1 was deleted but got locked by anti-virus?). Try file2. + // For some reason, the file1 can't be created (previous file1 was deleted but got locked by antivirus?). Try file2. + i++; if (i > 2) { - i = 2 + RANDOM.nextInt(maxFileNumber); // generate random suffix if too many failures + // generate random suffix if too many failures + i = 2 + RANDOM.nextInt(maxFileNumber); } } } @@ -722,12 +724,12 @@ public class FileUtilRt { } /** - * Get parent for the file. The method correctly - * processes "." and ".." in file names. The name - * remains relative if was relative before. + * Get parent for the file. + * The method correctly processes `.` and `..` in file names. + * The name remains relative if it was relative before. * * @param file a file to analyze - * @return files's parent, or {@code null} if the file has no parent. + * @return file's parent, or {@code null} if the file has no parent. */ @Nullable public static File getParentFile(@NotNull File file) { @@ -893,7 +895,7 @@ public class FileUtilRt { private static DirectoryNotEmptyException directoryNotEmptyExceptionWithMoreDiagnostic(@NotNull Path path) throws IOException { DirectoryStream.Filter alwaysTrue = new DirectoryStream.Filter() { @Override - public boolean accept(Path entry) throws IOException { + public boolean accept(Path entry) { return true; } }; @@ -938,8 +940,12 @@ public class FileUtilRt { } public static boolean ensureCanCreateFile(@NotNull File file) { - if (file.exists()) return file.canWrite(); - if (!createIfNotExists(file)) return false; + if (file.exists()) { + return file.canWrite(); + } + if (!createIfNotExists(file)) { + return false; + } return delete(file); } @@ -1080,8 +1086,9 @@ public class FileUtilRt { file2 == null ? null : file2.getPath()); } + @SuppressWarnings("RedundantSuppression") public static boolean pathsEqual(@Nullable String path1, @Nullable String path2) { - //noinspection StringEquality + //noinspection StringEquality,SSBasedInspection if (path1 == path2) { return true; } diff --git a/platform/util/base/src/com/intellij/util/containers/CollectionFactory.java b/platform/util/base/src/com/intellij/util/containers/CollectionFactory.java index cf8ef6e1f71a..484922ef59bc 100644 --- a/platform/util/base/src/com/intellij/util/containers/CollectionFactory.java +++ b/platform/util/base/src/com/intellij/util/containers/CollectionFactory.java @@ -1,4 +1,4 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.util.containers; import com.intellij.openapi.util.SystemInfoRt; @@ -266,8 +266,8 @@ public final class CollectionFactory { /** * Return a {@link Map} implementation with slightly faster access for very big maps (>100K keys) and a bit smaller memory footprint - * than {@link HashMap}. Null keys and values are permitted. Use sparingly only when performance considerations are utterly important; - * in all other cases please prefer {@link HashMap}. + * than {@link java.util.HashMap}. Null keys and values are permitted. Use sparingly only when performance considerations are utterly important; + * in all other cases please prefer {@link java.util.HashMap}. */ @Contract(value = "-> new", pure = true) public static @NotNull Map createSmallMemoryFootprintMap() { @@ -381,8 +381,7 @@ public final class CollectionFactory { return new Object2ObjectOpenCustomHashMap<>(adaptStrategy(strategy)); } - @NotNull - private static Hash.Strategy adaptStrategy(@NotNull HashingStrategy strategy) { + private static @NotNull Hash.Strategy adaptStrategy(@NotNull HashingStrategy strategy) { return new FastUtilHashingStrategies.SerializableHashStrategy() { @Override public int hashCode(@Nullable K o) { @@ -399,12 +398,15 @@ public final class CollectionFactory { public static @NotNull Map createCustomHashingStrategyMap(int expected, @NotNull HashingStrategy strategy) { return new Object2ObjectOpenCustomHashMap<>(expected, adaptStrategy(strategy)); } + public static @NotNull Set createCustomHashingStrategySet(@NotNull HashingStrategy strategy) { return new ObjectOpenCustomHashSet<>(adaptStrategy(strategy)); } + public static @NotNull Map createLinkedCustomHashingStrategyMap(@NotNull HashingStrategy strategy) { return new Object2ObjectLinkedOpenCustomHashMap<>(adaptStrategy(strategy)); } + public static @NotNull Set createLinkedCustomHashingStrategySet(@NotNull HashingStrategy strategy) { return new ObjectLinkedOpenCustomHashSet<>(adaptStrategy(strategy)); } diff --git a/platform/util/base/src/com/intellij/util/containers/FastUtilHashingStrategies.java b/platform/util/base/src/com/intellij/util/containers/FastUtilHashingStrategies.java index 480b0177e541..d2f786f1fe67 100644 --- a/platform/util/base/src/com/intellij/util/containers/FastUtilHashingStrategies.java +++ b/platform/util/base/src/com/intellij/util/containers/FastUtilHashingStrategies.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.util.containers; import com.intellij.openapi.util.io.FileUtilRt; @@ -24,6 +24,18 @@ public final class FastUtilHashingStrategies { private FastUtilHashingStrategies() { } + public static final Hash.Strategy FILE_PATH_HASH_STRATEGY = new Hash.Strategy() { + @Override + public int hashCode(@Nullable String o) { + return FileUtilRt.pathHashCode(o); + } + + @Override + public boolean equals(@Nullable String p1, @Nullable String p2) { + return FileUtilRt.pathsEqual(p1, p2); + } + }; + public static final Hash.Strategy FILE_HASH_STRATEGY = new SerializableHashStrategy() { @Override public int hashCode(@Nullable File o) { diff --git a/platform/util/base/src/com/intellij/util/containers/FileCollectionFactory.java b/platform/util/base/src/com/intellij/util/containers/FileCollectionFactory.java index 230ce8bfa01b..7c542bdf9ec4 100644 --- a/platform/util/base/src/com/intellij/util/containers/FileCollectionFactory.java +++ b/platform/util/base/src/com/intellij/util/containers/FileCollectionFactory.java @@ -1,9 +1,10 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.util.containers; import com.intellij.openapi.util.io.FileUtilRt; import it.unimi.dsi.fastutil.Hash; import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenCustomHashMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenCustomHashSet; import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; import org.jetbrains.annotations.NotNull; @@ -20,8 +21,9 @@ import java.util.Set; * Creates map or set with canonicalized path hash strategy. */ public final class FileCollectionFactory { - private interface SerializableHashingStrategy extends HashingStrategy, Serializable {} - private static final HashingStrategy FILE_HASH_STRATEGY = new SerializableHashingStrategy() { + private interface SerializableHashingStrategy extends Hash.Strategy, Serializable {} + + private static final SerializableHashingStrategy FILE_HASH_STRATEGY = new SerializableHashingStrategy() { @Override public int hashCode(@Nullable File o) { return FileUtilRt.pathHashCode(o == null ? null : o.getPath()); @@ -32,17 +34,6 @@ public final class FileCollectionFactory { return FileUtilRt.pathsEqual(a == null ? null : a.getPath(), b == null ? null : b.getPath()); } }; - public static final HashingStrategy FILE_PATH_HASH_STRATEGY = new HashingStrategy() { - @Override - public int hashCode(@Nullable String o) { - return FileUtilRt.pathHashCode(o); - } - - @Override - public boolean equals(@Nullable String p1, @Nullable String p2) { - return FileUtilRt.pathsEqual(p1, p2); - } - }; /** * Create linked map with canonicalized key hash strategy. @@ -69,11 +60,11 @@ public final class FileCollectionFactory { } public static @NotNull Map createCanonicalFileMap() { - return CollectionFactory.createCustomHashingStrategyMap(FILE_HASH_STRATEGY); + return new Object2ObjectOpenCustomHashMap<>(FILE_HASH_STRATEGY); } public static @NotNull Map createCanonicalFileMap(int expected) { - return CollectionFactory.createCustomHashingStrategyMap(expected, FILE_HASH_STRATEGY); + return new Object2ObjectOpenCustomHashMap<>(expected, FILE_HASH_STRATEGY); } public static @NotNull Map createCanonicalFileMap(@NotNull Map map) { @@ -83,7 +74,7 @@ public final class FileCollectionFactory { } public static @NotNull Set createCanonicalFileSet() { - return CollectionFactory.createCustomHashingStrategySet(FILE_HASH_STRATEGY); + return new ObjectOpenCustomHashSet<>(FILE_HASH_STRATEGY); } public static @NotNull Set createCanonicalFileSet(@NotNull Collection files) { @@ -101,7 +92,7 @@ public final class FileCollectionFactory { } public static @NotNull Set createCanonicalFilePathSet() { - return CollectionFactory.createCustomHashingStrategySet(FILE_PATH_HASH_STRATEGY); + return new ObjectOpenCustomHashSet<>(FastUtilHashingStrategies.FILE_PATH_HASH_STRATEGY); } public static @NotNull Set createCanonicalFileLinkedSet() { diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java index 5bdeaad88cdf..134d5e5601a8 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java @@ -35,9 +35,8 @@ import static java.nio.file.attribute.PosixFilePermission.*; /** * Utilities for working with {@link File}. */ -@SuppressWarnings("MethodOverridesStaticMethodOfSuperclass") @ApiStatus.NonExtendable -public class FileUtil extends FileUtilRt { +public class FileUtil { public static final String ASYNC_DELETE_EXTENSION = ".__del__"; public static final int REGEX_PATTERN_FLAGS = SystemInfoRt.isFileSystemCaseSensitive ? 0 : Pattern.CASE_INSENSITIVE; @@ -191,7 +190,7 @@ public class FileUtil extends FileUtilRt { throw new IOException("File length reported negative, probably doesn't exist"); } - if (isTooLarge(len)) { + if (FileUtilRt.isTooLarge(len)) { throw new FileTooBigException("Attempt to load '" + file + "' in memory buffer, file length is " + len + " bytes."); } @@ -357,6 +356,10 @@ public class FileUtil extends FileUtilRt { return FileUtilRt.delete(file); } + public static void deleteRecursively(@NotNull Path file) throws IOException { + FileUtilRt.deleteRecursively(file, null); + } + /** * Delete the path -- recursively, if it is a directory. * Really insist: i.e. retry delete a few times with a timeout -- see {@link FileUtilRt#doDelete(Path)} @@ -366,7 +369,7 @@ public class FileUtil extends FileUtilRt { * @see FileUtilRt#doDelete(Path) */ public static void delete(@NotNull Path path) throws IOException { - deleteRecursively(path, null); + FileUtilRt.deleteRecursively(path, null); } public static boolean createParentDirs(@NotNull File file) { @@ -385,6 +388,10 @@ public class FileUtil extends FileUtilRt { return FileUtilRt.ensureCanCreateFile(file); } + public static boolean createIfNotExists(@NotNull File file) { + return FileUtilRt.createIfNotExists(file); + } + public static void copy(@NotNull File fromFile, @NotNull File toFile) throws IOException { performCopy(fromFile, toFile, true); } @@ -586,6 +593,10 @@ public class FileUtil extends FileUtilRt { return FileUtilRt.toSystemDependentName(filePath); } + public static @NotNull String toSystemDependentName(@NotNull String path, char separatorChar) { + return FileUtilRt.toSystemDependentName(path, separatorChar); + } + /** * Converts {@code filePath} to file system independent form which uses forward slashes ('/'). Such paths can be stored in internal structures * and configuration files. They must be converted to {@link #toSystemDependentName file system dependenct form} to show in UI. @@ -603,7 +614,11 @@ public class FileUtil extends FileUtilRt { */ @Contract("null -> null; !null->!null") public static String toCanonicalPath(@Nullable String path) { - return toCanonicalPath(path, File.separatorChar, true); + return FileUtilRt.toCanonicalPath(path, File.separatorChar, true); + } + + public static String toCanonicalPath(@Nullable String path, char separatorChar, boolean removeLastSlash) { + return FileUtilRt.toCanonicalPath(path, separatorChar, removeLastSlash); } /** @@ -628,15 +643,15 @@ public class FileUtil extends FileUtilRt { @Contract("null, _ -> null; !null,_->!null") public static String toCanonicalPath(@Nullable String path, char separatorChar) { - return toCanonicalPath(path, separatorChar, true); + return FileUtilRt.toCanonicalPath(path, separatorChar, true); } @Contract("null -> null; !null->!null") public static String toCanonicalUriPath(@Nullable String path) { - return toCanonicalPath(path, '/', false); + return FileUtilRt.toCanonicalPath(path, '/', false); } - private static final SymlinkResolver SYMLINK_RESOLVER = new SymlinkResolver() { + private static final FileUtilRt.SymlinkResolver SYMLINK_RESOLVER = new FileUtilRt.SymlinkResolver() { @Override public @NotNull String resolveSymlinksAndCanonicalize(@NotNull String path, char separatorChar, boolean removeLastSlash) { try { @@ -659,8 +674,8 @@ public class FileUtil extends FileUtilRt { char separatorChar, boolean removeLastSlash, boolean resolveSymlinks) { - SymlinkResolver symlinkResolver = resolveSymlinks ? SYMLINK_RESOLVER : null; - return toCanonicalPath(path, separatorChar, removeLastSlash, symlinkResolver); + FileUtilRt.SymlinkResolver symlinkResolver = resolveSymlinks ? SYMLINK_RESOLVER : null; + return FileUtilRt.toCanonicalPath(path, separatorChar, removeLastSlash, symlinkResolver); } /** @@ -799,6 +814,14 @@ public class FileUtil extends FileUtilRt { return Strings.toLowerCase(FileUtilRt.getExtension(fileName)); } + public static @NotNull CharSequence getExtension(@NotNull CharSequence fileName) { + return FileUtilRt.getExtension(fileName); + } + + public static CharSequence getExtension(@NotNull CharSequence fileName, @Nullable String defaultValue) { + return FileUtilRt.getExtension(fileName, defaultValue); + } + public static @NotNull @NlsSafe String resolveShortWindowsName(@NotNull String path) throws IOException { try { return SystemInfoRt.isWindows && containsWindowsShortName(path) ? Paths.get(path).toRealPath(LinkOption.NOFOLLOW_LINKS).toString() : path; @@ -1354,6 +1377,10 @@ public class FileUtil extends FileUtilRt { return FileUtilRt.generateRandomTemporaryPath(); } + public static @NotNull File generateRandomTemporaryPath(@NotNull String prefix, @NotNull String suffix) throws IOException { + return FileUtilRt.generateRandomTemporaryPath(prefix, suffix); + } + public static void setExecutable(@NotNull File file) throws IOException { NioFiles.setExecutable(file.toPath()); } @@ -1395,7 +1422,11 @@ public class FileUtil extends FileUtilRt { return FileUtilRt.loadFileText(file); } - public static char @NotNull [] loadFileText(@NotNull File file, @Nullable String encoding) throws IOException { + public static char @NotNull [] loadFileText(@NotNull File file, @NotNull Charset encoding) throws IOException { + return FileUtilRt.loadFileText(file, encoding); + } + + public static char[] loadFileText(@NotNull File file, @Nullable String encoding) throws IOException { return FileUtilRt.loadFileText(file, encoding); } @@ -1432,7 +1463,11 @@ public class FileUtil extends FileUtilRt { } public static @NotNull List splitPath(@NotNull String path) { - return splitPath(path, File.separatorChar); + return FileUtilRt.splitPath(path, File.separatorChar); + } + + public static @NotNull List splitPath(@NotNull String path, char separatorChar) { + return FileUtilRt.splitPath(path, separatorChar); } public static boolean visitFiles(@NotNull File root, @NotNull Processor processor) { @@ -1482,4 +1517,13 @@ public class FileUtil extends FileUtilRt { public static @NotNull URI fileToUri(@NotNull File file) { return FileUtilRt.fileToUri(file); } + + public static boolean extensionEquals(@NotNull @NonNls String filePath, @NotNull @NonNls String extension) { + return FileUtilRt.extensionEquals(filePath, extension); + } + + @SuppressWarnings("unused") + public static boolean isJarOrZip(@NotNull File file) { + return FileUtilRt.isJarOrZip(file, true); + } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/target/GradleServerEnvironmentSetupImpl.kt b/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/target/GradleServerEnvironmentSetupImpl.kt index f757b9f95adf..ab5095bbcaad 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/target/GradleServerEnvironmentSetupImpl.kt +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/target/GradleServerEnvironmentSetupImpl.kt @@ -18,7 +18,8 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil import com.intellij.openapi.project.Project import com.intellij.openapi.projectRoots.ProjectJdkTable import com.intellij.openapi.util.UserDataHolderBase -import com.intellij.openapi.util.io.FileUtil.* +import com.intellij.openapi.util.io.FileUtil +import com.intellij.openapi.util.io.FileUtilRt import com.intellij.platform.externalSystem.rt.ExternalSystemRtClass import com.intellij.util.PathMapper import com.intellij.util.PathMappingSettings @@ -122,29 +123,33 @@ internal class GradleServerEnvironmentSetupImpl(private val project: Project, val pathsToUpload: MutableSet = HashSet() val workingDir = consumerOperationParameters.projectDir - val gradleProjectDirectory = toSystemDependentName(workingDir.path) + val gradleProjectDirectory = FileUtilRt.toSystemDependentName(workingDir.path) pathsToUpload.add(gradleProjectDirectory) val projectSettings = GradleSettings.getInstance(project).getLinkedProjectSettings( ExternalSystemApiUtil.toCanonicalPath(workingDir.path)) projectSettings?.modules ?.filter { Files.exists(Path.of(it)) } - ?.mapTo(pathsToUpload) { toSystemDependentName(it) } + ?.mapTo(pathsToUpload) { FileUtilRt.toSystemDependentName(it) } val commonAncestor = findCommonAncestor(pathsToUpload) - val uploadPath = Paths.get(toSystemDependentName(commonAncestor!!)) + val uploadPath = Paths.get(FileUtilRt.toSystemDependentName(commonAncestor!!)) val uploadRoot = TargetEnvironment.UploadRoot(uploadPath, TargetEnvironment.TargetPath.Temporary()) request.uploadVolumes += uploadRoot val targetFileSeparator = request.targetPlatform.platform.fileSeparator var targetWorkingDirectory: TargetValue? = null for (path in pathsToUpload) { - val relativePath = getRelativePath(commonAncestor, path, File.separatorChar) + val relativePath = FileUtilRt.getRelativePath(commonAncestor, path, File.separatorChar) val targetValue = targetEnvironmentProvider.upload(uploadRoot, path, relativePath!!) - if (targetWorkingDirectory == null && isAncestor(path, gradleProjectDirectory, false)) { - val workingDirRelativePath = getRelativePath(path, gradleProjectDirectory, File.separatorChar)!! - val targetWorkingDirRelativePath = if (workingDirRelativePath == ".") "" - else toSystemDependentName(workingDirRelativePath, targetFileSeparator) + if (targetWorkingDirectory == null && FileUtil.isAncestor(path, gradleProjectDirectory, false)) { + val workingDirRelativePath = FileUtilRt.getRelativePath(path, gradleProjectDirectory, File.separatorChar)!! + val targetWorkingDirRelativePath = if (workingDirRelativePath == ".") { + "" + } + else { + FileUtilRt.toSystemDependentName(workingDirRelativePath, targetFileSeparator) + } targetWorkingDirectory = TargetValue.map(targetValue) { "$it$targetFileSeparator$targetWorkingDirRelativePath" } } } @@ -155,7 +160,7 @@ internal class GradleServerEnvironmentSetupImpl(private val project: Project, private fun findCommonAncestor(paths: Set): String? { var commonRoot: File? = null for (path in paths) { - commonRoot = if (commonRoot == null) File(path) else findAncestor(commonRoot, File(path)) + commonRoot = if (commonRoot == null) File(path) else FileUtil.findAncestor(commonRoot, File(path)) requireNotNull(commonRoot) { "no common root found" } } assert(commonRoot != null) @@ -207,7 +212,7 @@ internal class GradleServerEnvironmentSetupImpl(private val project: Project, if (request is LocalTargetEnvironmentRequest) { javaParameters.vmParametersList.addProperty(Main.LOCAL_BUILD_PROPERTY, "true") val javaHomePath = consumerOperationParameters.javaHome.path - ProjectJdkTable.getInstance().allJdks.find { pathsEqual(it.homePath, javaHomePath) }?.let { javaParameters.jdk = it } + ProjectJdkTable.getInstance().allJdks.find { FileUtilRt.pathsEqual(it.homePath, javaHomePath) }?.let { javaParameters.jdk = it } } else { if (environmentConfiguration.runtimes.findByType(JavaLanguageRuntimeConfiguration::class.java) == null) { @@ -382,7 +387,7 @@ internal class GradleServerEnvironmentSetupImpl(private val project: Project, fun requestUploadIntoTarget(path: String, request: TargetEnvironmentRequest, environmentConfiguration: TargetEnvironmentConfiguration): TargetValue { - val uploadPath = Paths.get(toSystemDependentName(path)) + val uploadPath = Paths.get(FileUtilRt.toSystemDependentName(path)) val localRootPath = uploadPath.parent val languageRuntime = environmentConfiguration.runtimes.findByType(JavaLanguageRuntimeConfiguration::class.java)