IJPL-594 update fastutil 8.5.11 -> 8.5.13 (part 2)

GitOrigin-RevId: 4f55be9e64dc4a484750762590056d478b746c97
This commit is contained in:
Vladimir Krivosheev
2024-02-06 16:21:10 +01:00
committed by intellij-monorepo-bot
parent c6b0575496
commit 82b321d57c
18 changed files with 268 additions and 197 deletions

View File

@@ -1,9 +1,9 @@
<component name="libraryTable"> <component name="libraryTable">
<library name="fastutil-min" type="repository"> <library name="fastutil-min" type="repository">
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.fastutil:intellij-deps-fastutil:8.5.13"> <properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.fastutil:intellij-deps-fastutil:8.5.13-jb3">
<verification> <verification>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/fastutil/intellij-deps-fastutil/8.5.13/intellij-deps-fastutil-8.5.13.jar"> <artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/fastutil/intellij-deps-fastutil/8.5.13-jb3/intellij-deps-fastutil-8.5.13-jb3.jar">
<sha256sum>19d613c22adbaf9cef204d2f4d6f17afe1389087f80728c04aa982c62b5a2cf3</sha256sum> <sha256sum>d6b7fe103081df530137df0e3df5a9d2ebaef1577f93fcded06186e0f74996b9</sha256sum>
</artifact> </artifact>
</verification> </verification>
</properties> </properties>
@@ -11,11 +11,11 @@
<root url="file://$PROJECT_DIR$/lib/annotations/fastutil" /> <root url="file://$PROJECT_DIR$/lib/annotations/fastutil" />
</ANNOTATIONS> </ANNOTATIONS>
<CLASSES> <CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/fastutil/intellij-deps-fastutil/8.5.13/intellij-deps-fastutil-8.5.13.jar!/" /> <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/fastutil/intellij-deps-fastutil/8.5.13-jb3/intellij-deps-fastutil-8.5.13-jb3.jar!/" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES> <SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/fastutil/intellij-deps-fastutil/8.5.13/intellij-deps-fastutil-8.5.13-sources.jar!/" /> <root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/fastutil/intellij-deps-fastutil/8.5.13-jb3/intellij-deps-fastutil-8.5.13-jb3-sources.jar!/" />
</SOURCES> </SOURCES>
</library> </library>
</component> </component>

View File

@@ -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; package org.jetbrains.jps.builders.java.dependencyView;
import com.intellij.openapi.diagnostic.Logger; 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.SystemInfo;
import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.SmartList; import com.intellij.util.SmartList;
import com.intellij.util.containers.CollectionFactory; import com.intellij.util.containers.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.FileCollectionFactory;
import com.intellij.util.containers.SmartHashSet;
import com.intellij.util.io.EnumeratorIntegerDescriptor; import com.intellij.util.io.EnumeratorIntegerDescriptor;
import it.unimi.dsi.fastutil.ints.IntConsumer; import it.unimi.dsi.fastutil.ints.IntConsumer;
import it.unimi.dsi.fastutil.ints.IntIterator; import it.unimi.dsi.fastutil.ints.IntIterator;
@@ -144,7 +141,7 @@ public class Mappings {
myClassToClassDependency = new IntIntTransientMultiMaplet(); myClassToClassDependency = new IntIntTransientMultiMaplet();
myShortClassNameIndex = null; myShortClassNameIndex = null;
myRelativeSourceFilePathToClasses = new ObjectObjectTransientMultiMaplet<>( 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); myClassToRelativeSourceFilePath = new IntObjectTransientMultiMaplet<>(fileCollectionFactory);
} }
@@ -171,7 +168,7 @@ public class Mappings {
) { ) {
@Override @Override
protected @NotNull String debugString(String path) { 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); return SystemInfo.isFileSystemCaseSensitive ? path : path.toLowerCase(Locale.US);
} }
}; };

View File

@@ -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; package org.jetbrains.jps.builders.java.dependencyView;
import com.intellij.util.PairProcessor; import com.intellij.util.PairProcessor;
import com.intellij.util.containers.CollectionFactory; import it.unimi.dsi.fastutil.Hash;
import com.intellij.util.containers.HashingStrategy; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Collection; import java.util.Collection;
@@ -14,11 +14,11 @@ import java.util.function.Supplier;
* @author Eugene Zhuravlev * @author Eugene Zhuravlev
*/ */
public final class ObjectObjectTransientMultiMaplet<K, V extends Streamable> extends ObjectObjectMultiMaplet<K, V>{ public final class ObjectObjectTransientMultiMaplet<K, V extends Streamable> extends ObjectObjectMultiMaplet<K, V>{
private final Map<K, Collection<V>> myMap; private final Object2ObjectOpenCustomHashMap<K, Collection<V>> myMap;
private final Supplier<? extends Collection<V>> myCollectionFactory; private final Supplier<? extends Collection<V>> myCollectionFactory;
public ObjectObjectTransientMultiMaplet(HashingStrategy<K> hashingStrategy, Supplier<? extends Collection<V>> collectionFactory) { public ObjectObjectTransientMultiMaplet(Hash.Strategy<K> hashingStrategy, Supplier<? extends Collection<V>> collectionFactory) {
myMap = CollectionFactory.createCustomHashingStrategyMap(hashingStrategy); myMap = new Object2ObjectOpenCustomHashMap<>(hashingStrategy);
myCollectionFactory = collectionFactory; myCollectionFactory = collectionFactory;
} }
@@ -89,12 +89,8 @@ public final class ObjectObjectTransientMultiMaplet<K, V extends Streamable> ext
@Override @Override
public void removeAll(K key, Collection<V> values) { public void removeAll(K key, Collection<V> values) {
final Collection<V> collection = myMap.get(key); final Collection<V> collection = myMap.get(key);
if (collection != null) { if (collection != null && collection.removeAll(values) && collection.isEmpty()) {
if (collection.removeAll(values)) { myMap.remove(key);
if (collection.isEmpty()) {
myMap.remove(key);
}
}
} }
} }

View File

@@ -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

View File

@@ -3,12 +3,12 @@
<component name="NewModuleRootManager" inherit-compiler-output="true"> <component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="true" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="kotlin-stdlib" level="project" /> <orderEntry type="library" scope="TEST" name="kotlin-stdlib" level="project" />
<orderEntry type="module-library"> <orderEntry type="module-library" scope="TEST">
<library name="proguard" type="repository"> <library name="proguard" type="repository">
<properties maven-id="com.guardsquare:proguard-base:7.4.2"> <properties maven-id="com.guardsquare:proguard-base:7.4.2">
<verification> <verification>

View File

@@ -169,4 +169,13 @@
-keepclassmembers,allowoptimization enum * { -keepclassmembers,allowoptimization enum * {
public static **[] values(); public static **[] values();
public static ** valueOf(java.lang.String); 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();
} }

View File

@@ -14,11 +14,58 @@ import kotlin.time.measureTime
internal data class OptimizeLibraryContext(@JvmField val tempDir: Path, @JvmField val javaHome: Path) 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. private data class LibDescriptor(@JvmField val id: String, @JvmField val version: String, @JvmField val jbVersion: Int)
// Hence, we depend on the prerequisite that the original library is already resolved and stored in the local Maven repository.
private val fastUtil = LibDescriptor(id = "fastutil", version = "8.5.13", jbVersion = 3)
@Suppress("unused")
internal object FastutilInstall {
@JvmStatic
fun main(args: Array<String>) {
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 { internal object LibraryCodeOptimizer {
@JvmStatic @JvmStatic
fun main(args: Array<String>) { fun main(args: Array<String>) {
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 m2 = Path.of(System.getProperty("user.home")).resolve(".m2/repository")
val outDir = Path.of("out").toAbsolutePath() val outDir = Path.of("out").toAbsolutePath()
val output = outDir.resolve("fastutil.jar") 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 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 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 { val duration = measureTime {
optimizeLibrary(name = "fastutil", optimizeLibrary(name = "fastutil",
input = input, input = input,
@@ -49,6 +95,13 @@ internal object LibraryCodeOptimizer {
} }
} }
private fun executeMaven(command: List<String>) {
ProcessBuilder(command)
.inheritIO()
.start()
.waitFor()
}
//private fun cleanZip(file: Path): Path { //private fun cleanZip(file: Path): Path {
// val tempFile = Files.createTempFile(file.parent, file.fileName.toString(), ".jar") // val tempFile = Files.createTempFile(file.parent, file.fileName.toString(), ".jar")
// ZipFileWriter(channel = FileChannel.open(tempFile, EnumSet.of(StandardOpenOption.WRITE))).use { zipFileWriter -> // ZipFileWriter(channel = FileChannel.open(tempFile, EnumSet.of(StandardOpenOption.WRITE))).use { zipFileWriter ->

View File

@@ -1,57 +1,49 @@
/* // Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
* 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.
*/
package com.intellij.lang.impl; package com.intellij.lang.impl;
import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
@SuppressWarnings("SSBasedInspection") import java.util.ArrayList;
final class MarkerPool extends ObjectArrayList<PsiBuilderImpl.ProductionMarker> {
private final PsiBuilderImpl myBuilder; @SuppressWarnings({"SSBasedInspection", "RedundantSuppression"})
private final IntArrayList myFreeStartMarkers = new IntArrayList(); final class MarkerPool {
private final IntArrayList myFreeErrorItems = new IntArrayList(); private final PsiBuilderImpl builder;
private final IntArrayList freeStartMarkers = new IntArrayList();
private final IntArrayList freeErrorItems = new IntArrayList();
final ArrayList<PsiBuilderImpl.ProductionMarker> list = new ArrayList<>();
MarkerPool(PsiBuilderImpl builder) { MarkerPool(PsiBuilderImpl builder) {
myBuilder = builder; this.builder = builder;
add(null); //no marker has id 0 list.add(null); //no marker has id 0
} }
PsiBuilderImpl.StartMarker allocateStartMarker() { PsiBuilderImpl.StartMarker allocateStartMarker() {
if (myFreeStartMarkers.size() > 0) { if (!freeStartMarkers.isEmpty()) {
return (PsiBuilderImpl.StartMarker)get(myFreeStartMarkers.popInt()); return (PsiBuilderImpl.StartMarker)list.get(freeStartMarkers.popInt());
} }
PsiBuilderImpl.StartMarker marker = new PsiBuilderImpl.StartMarker(size(), myBuilder); PsiBuilderImpl.StartMarker marker = new PsiBuilderImpl.StartMarker(list.size(), builder);
add(marker); list.add(marker);
return marker; return marker;
} }
PsiBuilderImpl.ErrorItem allocateErrorItem() { PsiBuilderImpl.ErrorItem allocateErrorItem() {
if (myFreeErrorItems.size() > 0) { if (!freeErrorItems.isEmpty()) {
return (PsiBuilderImpl.ErrorItem)get(myFreeErrorItems.popInt()); return (PsiBuilderImpl.ErrorItem)list.get(freeErrorItems.popInt());
} }
PsiBuilderImpl.ErrorItem item = new PsiBuilderImpl.ErrorItem(size(), myBuilder); PsiBuilderImpl.ErrorItem item = new PsiBuilderImpl.ErrorItem(list.size(), builder);
add(item); list.add(item);
return item; return item;
} }
void freeMarker(PsiBuilderImpl.ProductionMarker marker) { void freeMarker(PsiBuilderImpl.ProductionMarker marker) {
marker.clean(); 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);
}
} }

View File

@@ -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; package com.intellij.lang.impl;
import com.intellij.lang.*; import com.intellij.lang.*;
@@ -36,16 +36,12 @@ import com.intellij.util.text.CharArrayUtil;
import com.intellij.util.text.CharSequenceSubSequence; import com.intellij.util.text.CharSequenceSubSequence;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.AbstractList; import java.util.*;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Function; import java.util.function.Function;
import static com.intellij.lang.WhitespacesBinders.DEFAULT_RIGHT_BINDER; import static com.intellij.lang.WhitespacesBinders.DEFAULT_RIGHT_BINDER;
@@ -94,9 +90,9 @@ public class PsiBuilderImpl extends UnprotectedUserDataHolder implements PsiBuil
private IElementType myCachedTokenType; private IElementType myCachedTokenType;
private final Int2ObjectMap<LazyParseableToken> myChameleonCache = new Int2ObjectOpenHashMap<>(); private final Int2ObjectMap<LazyParseableToken> 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 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) { public static void registerWhitespaceToken(@NotNull IElementType type) {
ourAnyLanguageWhitespaceTokens = TokenSet.orSet(ourAnyLanguageWhitespaceTokens, TokenSet.create(type)); ourAnyLanguageWhitespaceTokens = TokenSet.orSet(ourAnyLanguageWhitespaceTokens, TokenSet.create(type));
@@ -387,7 +383,7 @@ public class PsiBuilderImpl extends UnprotectedUserDataHolder implements PsiBuil
@Override @Override
public void doneBefore(@NotNull IElementType type, @NotNull Marker before, @NotNull @Nls String errorMessage) { public void doneBefore(@NotNull IElementType type, @NotNull Marker before, @NotNull @Nls String errorMessage) {
StartMarker marker = (StartMarker)before; StartMarker marker = (StartMarker)before;
ErrorItem errorItem = myBuilder.myPool.allocateErrorItem(); ErrorItem errorItem = myBuilder.pool.allocateErrorItem();
errorItem.setMessage(errorMessage); errorItem.setMessage(errorMessage);
errorItem.myLexemeIndex = marker.myLexemeIndex; errorItem.myLexemeIndex = marker.myLexemeIndex;
myBuilder.myProduction.addBefore(errorItem, marker); myBuilder.myProduction.addBefore(errorItem, marker);
@@ -835,7 +831,7 @@ public class PsiBuilderImpl extends UnprotectedUserDataHolder implements PsiBuil
} }
private @NotNull StartMarker createMarker(int lexemeIndex) { private @NotNull StartMarker createMarker(int lexemeIndex) {
StartMarker marker = myPool.allocateStartMarker(); StartMarker marker = pool.allocateStartMarker();
marker.myLexemeIndex = lexemeIndex; marker.myLexemeIndex = lexemeIndex;
if (myDebugMode) { if (myDebugMode) {
myOptionalData.notifyAllocated(marker.markerId); myOptionalData.notifyAllocated(marker.markerId);
@@ -912,7 +908,7 @@ public class PsiBuilderImpl extends UnprotectedUserDataHolder implements PsiBuil
if (lastMarker instanceof ErrorItem && lastMarker.myLexemeIndex == myCurrentLexeme) { if (lastMarker instanceof ErrorItem && lastMarker.myLexemeIndex == myCurrentLexeme) {
return; return;
} }
ErrorItem marker = myPool.allocateErrorItem(); ErrorItem marker = pool.allocateErrorItem();
marker.setMessage(messageText); marker.setMessage(messageText);
marker.myLexemeIndex = myCurrentLexeme; marker.myLexemeIndex = myCurrentLexeme;
myProduction.addMarker(marker); myProduction.addMarker(marker);
@@ -1036,25 +1032,24 @@ public class PsiBuilderImpl extends UnprotectedUserDataHolder implements PsiBuil
rootMarker.myParent = rootMarker.myFirstChild = rootMarker.myLastChild = rootMarker.myNext = null; rootMarker.myParent = rootMarker.myFirstChild = rootMarker.myLastChild = rootMarker.myNext = null;
StartMarker curNode = rootMarker; StartMarker curNode = rootMarker;
ObjectArrayList<StartMarker> nodes = new ObjectArrayList<>(); ArrayDeque<StartMarker> nodes = new ArrayDeque<>();
nodes.push(rootMarker); nodes.addLast(rootMarker);
int lastErrorIndex = -1; int lastErrorIndex = -1;
int maxDepth = 0; int maxDepth = 0;
int curDepth = 0; int curDepth = 0;
boolean hasCollapsedChameleons = false; boolean hasCollapsedChameleons = false;
int[] productions = myProduction.elements(); int[] productions = myProduction.elements();
Object[] markers = myPool.elements();
for (int i = 1, size = myProduction.size(); i < size; i++) { for (int i = 1, size = myProduction.size(); i < size; i++) {
int id = productions[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) { if (item instanceof StartMarker) {
StartMarker marker = (StartMarker)item; StartMarker marker = (StartMarker)item;
marker.myParent = curNode; marker.myParent = curNode;
marker.myFirstChild = marker.myLastChild = marker.myNext = null; marker.myFirstChild = marker.myLastChild = marker.myNext = null;
curNode.addChild(marker); curNode.addChild(marker);
nodes.push(curNode); nodes.addLast(curNode);
curNode = marker; curNode = marker;
curDepth++; curDepth++;
if (curDepth > maxDepth) maxDepth = curDepth; if (curDepth > maxDepth) maxDepth = curDepth;
@@ -1070,8 +1065,8 @@ public class PsiBuilderImpl extends UnprotectedUserDataHolder implements PsiBuil
if (isCollapsedChameleon(curNode)) { if (isCollapsedChameleon(curNode)) {
hasCollapsedChameleons = true; hasCollapsedChameleons = true;
} }
assertMarkersBalanced(id < 0 && markers[-id] == curNode, item); assertMarkersBalanced(id < 0 && pool.get(-id) == curNode, item);
curNode = nodes.pop(); curNode = nodes.removeLast();
curDepth--; curDepth--;
} }
} }
@@ -1124,15 +1119,14 @@ public class PsiBuilderImpl extends UnprotectedUserDataHolder implements PsiBuil
int lastIndex = 0; int lastIndex = 0;
int[] productions = myProduction.elements(); int[] productions = myProduction.elements();
Object[] markers = myPool.elements();
for (int i = 1, size = myProduction.size() - 1; i < size; i++) { for (int i = 1, size = myProduction.size() - 1; i < size; i++) {
int id = productions[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) { if (starting instanceof StartMarker) {
assertMarkersBalanced(((StartMarker)starting).isDone(), starting); assertMarkersBalanced(((StartMarker)starting).isDone(), starting);
} }
boolean done = starting == null; boolean done = starting == null;
ProductionMarker item = starting != null ? starting : (ProductionMarker)markers[-id]; ProductionMarker item = starting != null ? starting : pool.get(-id);
WhitespacesAndCommentsBinder binder; WhitespacesAndCommentsBinder binder;
if (item instanceof ErrorItem) { if (item instanceof ErrorItem) {
@@ -1151,7 +1145,7 @@ public class PsiBuilderImpl extends UnprotectedUserDataHolder implements PsiBuil
} }
else { else {
int prevId = productions[i - 1]; 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); int wsStartIndex = Math.max(lexemeIndex, lastIndex);
while (wsStartIndex > prevProductionLexIndex && whitespaceOrComment(myLexTypes[wsStartIndex - 1])) wsStartIndex--; while (wsStartIndex > prevProductionLexIndex && whitespaceOrComment(myLexTypes[wsStartIndex - 1])) wsStartIndex--;

View File

@@ -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; 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 org.jetbrains.annotations.NotNull;
import java.util.function.Predicate; import java.util.function.Predicate;
// array-backed queue with additional support for fast bulk inserts // array-backed queue with additional support for fast bulk inserts
class BulkArrayQueue<T> { final class BulkArrayQueue<T> {
// maintain wrap-around queue using these pointers into myQueue // 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 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]; private Object[] myQueue = new Object[1024];
void enqueue(@NotNull T info) { void enqueue(@NotNull T info) {
@@ -69,7 +69,7 @@ class BulkArrayQueue<T> {
} }
// insert all from "elements" before "head" // insert all from "elements" before "head"
void bulkEnqueueFirst(@NotNull ObjectList<? extends @NotNull T> elements) { void bulkEnqueueFirst(@NotNull ObjectArrayList<? extends @NotNull T> elements) {
int insertSize = elements.size(); int insertSize = elements.size();
int oldCapacity = myQueue.length; int oldCapacity = myQueue.length;
int emptySpace = oldCapacity - size() - 1; int emptySpace = oldCapacity - size() - 1;
@@ -88,20 +88,20 @@ class BulkArrayQueue<T> {
} }
void removeAll(@NotNull Predicate<? super T> shouldRemove) { void removeAll(@NotNull Predicate<? super T> shouldRemove) {
int o;
if (head <= tail) { if (head <= tail) {
// shift alive items in [head..tail) left to head // shift alive items in [head..tail) left to head
int o = head; o = head;
for (int i=head; i<tail; i++) { for (int i=head; i<tail; i++) {
T info = getAndNullize(i); T info = getAndNullize(i);
if (!shouldRemove.test(info)) { if (!shouldRemove.test(info)) {
myQueue[o++] = info; myQueue[o++] = info;
} }
} }
tail = o;
} }
else { else {
// shift alive items in [head..capacity) right // shift living items in [head..capacity) right
int o = myQueue.length; o = myQueue.length;
for (int i= myQueue.length-1; i>=head; i--) { for (int i= myQueue.length-1; i>=head; i--) {
T info = getAndNullize(i); T info = getAndNullize(i);
if (!shouldRemove.test(info)) { if (!shouldRemove.test(info)) {
@@ -117,8 +117,8 @@ class BulkArrayQueue<T> {
myQueue[o++] = info; myQueue[o++] = info;
} }
} }
tail = o;
} }
tail = o;
} }
boolean isEmpty() { boolean isEmpty() {

View File

@@ -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; package com.intellij.openapi.application.impl;
import com.intellij.codeWithMe.ClientId; import com.intellij.codeWithMe.ClientId;
@@ -15,7 +15,6 @@ import com.intellij.openapi.util.Condition;
import com.intellij.util.ExceptionUtil; import com.intellij.util.ExceptionUtil;
import com.intellij.util.concurrency.ThreadingAssertions; import com.intellij.util.concurrency.ThreadingAssertions;
import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectList;
import org.jetbrains.annotations.*; import org.jetbrains.annotations.*;
import javax.swing.*; import javax.swing.*;
@@ -26,7 +25,7 @@ final class FlushQueue {
private static final Logger LOG = Logger.getInstance(FlushQueue.class); private static final Logger LOG = Logger.getInstance(FlushQueue.class);
private static final ThrottledLogger THROTTLED_LOG = new ThrottledLogger(LOG, MINUTES.toMillis(1)); private static final ThrottledLogger THROTTLED_LOG = new ThrottledLogger(LOG, MINUTES.toMillis(1));
private ObjectList<RunnableInfo> mySkippedItems = new ObjectArrayList<>(100); //guarded by getQueueLock() private ObjectArrayList<RunnableInfo> mySkippedItems = new ObjectArrayList<>(100); //guarded by getQueueLock()
private final BulkArrayQueue<RunnableInfo> myQueue = new BulkArrayQueue<>(); //guarded by getQueueLock() private final BulkArrayQueue<RunnableInfo> myQueue = new BulkArrayQueue<>(); //guarded by getQueueLock()
private void flushNow() { private void flushNow() {
@@ -110,7 +109,7 @@ final class FlushQueue {
// (in .reincludeSkippedItems()) and also reset queueSize/queuedTimeNs fields. // (in .reincludeSkippedItems()) and also reset queueSize/queuedTimeNs fields.
// This way we got queue loading info 'cleared' (kind of) from bypassing influence, // 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, // 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. // tasks waiting times stats are merged together.
mySkippedItems.add(info.wasSkipped()); mySkippedItems.add(info.wasSkipped());
} }

View File

@@ -49,8 +49,10 @@ import com.intellij.util.*;
import com.intellij.util.containers.*; import com.intellij.util.containers.*;
import com.intellij.util.io.ReplicatorInputStream; import com.intellij.util.io.ReplicatorInputStream;
import com.intellij.util.io.storage.HeavyProcessLatch; 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.IntArrayList;
import it.unimi.dsi.fastutil.ints.*;
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenCustomHashSet;
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
import org.jetbrains.annotations.*; import org.jetbrains.annotations.*;
@@ -1156,9 +1158,8 @@ public final class PersistentFSImpl extends PersistentFS implements Disposable {
} }
else { else {
if (createEvents instanceof VFileCreateEvent prevEvent) { if (createEvents instanceof VFileCreateEvent prevEvent) {
Set<VFileCreateEvent> children = parent.isCaseSensitive() Set<VFileCreateEvent> children;
? new LinkedHashSet<>() children = parent.isCaseSensitive() ? new LinkedHashSet<>() : new ObjectLinkedOpenCustomHashSet<>(CASE_INSENSITIVE_STRATEGY);
: CollectionFactory.createLinkedCustomHashingStrategySet(CASE_INSENSITIVE_STRATEGY);
children.add(prevEvent); children.add(prevEvent);
toCreate.put(parent, children); toCreate.put(parent, children);
createEvents = children; createEvents = children;
@@ -2467,7 +2468,7 @@ public final class PersistentFSImpl extends PersistentFS implements Disposable {
(areChildrenCaseSensitive ? Flags.CHILDREN_CASE_SENSITIVE : 0); (areChildrenCaseSensitive ? Flags.CHILDREN_CASE_SENSITIVE : 0);
} }
private static final HashingStrategy<VFileCreateEvent> CASE_INSENSITIVE_STRATEGY = new HashingStrategy<>() { private static final Hash.Strategy<VFileCreateEvent> CASE_INSENSITIVE_STRATEGY = new Hash.Strategy<>() {
@Override @Override
public int hashCode(@Nullable VFileCreateEvent object) { public int hashCode(@Nullable VFileCreateEvent object) {
return object == null ? 0 : Strings.stringHashCodeInsensitive(object.getChildName()); return object == null ? 0 : Strings.stringHashCodeInsensitive(object.getChildName());

View File

@@ -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; package com.intellij.openapi.util.io;
import com.intellij.openapi.diagnostic.LoggerRt; 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}. * 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. * 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 KILOBYTE = 1024;
private static final int DEFAULT_INTELLISENSE_LIMIT = 2500 * KILOBYTE; private static final int DEFAULT_INTELLISENSE_LIMIT = 2500 * KILOBYTE;
@@ -98,7 +98,7 @@ public class FileUtilRt {
} }
@Contract("null, _, _, _ -> null; !null,_,_,_->!null") @Contract("null, _, _, _ -> null; !null,_,_,_->!null")
protected static String toCanonicalPath(@Nullable String path, static String toCanonicalPath(@Nullable String path,
char separatorChar, char separatorChar,
boolean removeLastSlash, boolean removeLastSlash,
@Nullable SymlinkResolver resolver) { @Nullable SymlinkResolver resolver) {
@@ -522,16 +522,18 @@ public class FileUtilRt {
if (attempts > maxFileNumber / 2 || attempts > MAX_ATTEMPTS) { if (attempts > maxFileNumber / 2 || attempts > MAX_ATTEMPTS) {
String[] children = dir.list(); String[] children = dir.list();
int size = children == null ? 0 : children.length; 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) { if (attempts > MAX_ATTEMPTS) {
throw exception != null ? exception: new IOException("Unable to create a temporary file " + f + "\nDirectory '" + dir + throw exception != null ? exception: new IOException("Unable to create a temporary file " + f + "\nDirectory '" + dir +
"' list ("+size+" children): " + Arrays.toString(children)); "' 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) { 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 * Get parent for the file.
* processes "." and ".." in file names. The name * The method correctly processes `.` and `..` in file names.
* remains relative if was relative before. * The name remains relative if it was relative before.
* *
* @param file a file to analyze * @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 @Nullable
public static File getParentFile(@NotNull File file) { public static File getParentFile(@NotNull File file) {
@@ -893,7 +895,7 @@ public class FileUtilRt {
private static DirectoryNotEmptyException directoryNotEmptyExceptionWithMoreDiagnostic(@NotNull Path path) throws IOException { private static DirectoryNotEmptyException directoryNotEmptyExceptionWithMoreDiagnostic(@NotNull Path path) throws IOException {
DirectoryStream.Filter<Path> alwaysTrue = new DirectoryStream.Filter<Path>() { DirectoryStream.Filter<Path> alwaysTrue = new DirectoryStream.Filter<Path>() {
@Override @Override
public boolean accept(Path entry) throws IOException { public boolean accept(Path entry) {
return true; return true;
} }
}; };
@@ -938,8 +940,12 @@ public class FileUtilRt {
} }
public static boolean ensureCanCreateFile(@NotNull File file) { public static boolean ensureCanCreateFile(@NotNull File file) {
if (file.exists()) return file.canWrite(); if (file.exists()) {
if (!createIfNotExists(file)) return false; return file.canWrite();
}
if (!createIfNotExists(file)) {
return false;
}
return delete(file); return delete(file);
} }
@@ -1080,8 +1086,9 @@ public class FileUtilRt {
file2 == null ? null : file2.getPath()); file2 == null ? null : file2.getPath());
} }
@SuppressWarnings("RedundantSuppression")
public static boolean pathsEqual(@Nullable String path1, @Nullable String path2) { public static boolean pathsEqual(@Nullable String path1, @Nullable String path2) {
//noinspection StringEquality //noinspection StringEquality,SSBasedInspection
if (path1 == path2) { if (path1 == path2) {
return true; return true;
} }

View File

@@ -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; package com.intellij.util.containers;
import com.intellij.openapi.util.SystemInfoRt; 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 * 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; * 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 HashMap}. * in all other cases please prefer {@link java.util.HashMap}.
*/ */
@Contract(value = "-> new", pure = true) @Contract(value = "-> new", pure = true)
public static <K, V> @NotNull Map<K, V> createSmallMemoryFootprintMap() { public static <K, V> @NotNull Map<K, V> createSmallMemoryFootprintMap() {
@@ -381,8 +381,7 @@ public final class CollectionFactory {
return new Object2ObjectOpenCustomHashMap<>(adaptStrategy(strategy)); return new Object2ObjectOpenCustomHashMap<>(adaptStrategy(strategy));
} }
@NotNull private static @NotNull <K> Hash.Strategy<K> adaptStrategy(@NotNull HashingStrategy<? super K> strategy) {
private static <K> Hash.Strategy<K> adaptStrategy(@NotNull HashingStrategy<? super K> strategy) {
return new FastUtilHashingStrategies.SerializableHashStrategy<K>() { return new FastUtilHashingStrategies.SerializableHashStrategy<K>() {
@Override @Override
public int hashCode(@Nullable K o) { public int hashCode(@Nullable K o) {
@@ -399,12 +398,15 @@ public final class CollectionFactory {
public static <K,V> @NotNull Map<K,V> createCustomHashingStrategyMap(int expected, @NotNull HashingStrategy<? super K> strategy) { public static <K,V> @NotNull Map<K,V> createCustomHashingStrategyMap(int expected, @NotNull HashingStrategy<? super K> strategy) {
return new Object2ObjectOpenCustomHashMap<>(expected, adaptStrategy(strategy)); return new Object2ObjectOpenCustomHashMap<>(expected, adaptStrategy(strategy));
} }
public static <K> @NotNull Set<K> createCustomHashingStrategySet(@NotNull HashingStrategy<? super K> strategy) { public static <K> @NotNull Set<K> createCustomHashingStrategySet(@NotNull HashingStrategy<? super K> strategy) {
return new ObjectOpenCustomHashSet<>(adaptStrategy(strategy)); return new ObjectOpenCustomHashSet<>(adaptStrategy(strategy));
} }
public static <K,V> @NotNull Map<K, V> createLinkedCustomHashingStrategyMap(@NotNull HashingStrategy<? super K> strategy) { public static <K,V> @NotNull Map<K, V> createLinkedCustomHashingStrategyMap(@NotNull HashingStrategy<? super K> strategy) {
return new Object2ObjectLinkedOpenCustomHashMap<>(adaptStrategy(strategy)); return new Object2ObjectLinkedOpenCustomHashMap<>(adaptStrategy(strategy));
} }
public static <K> @NotNull Set<K> createLinkedCustomHashingStrategySet(@NotNull HashingStrategy<? super K> strategy) { public static <K> @NotNull Set<K> createLinkedCustomHashingStrategySet(@NotNull HashingStrategy<? super K> strategy) {
return new ObjectLinkedOpenCustomHashSet<>(adaptStrategy(strategy)); return new ObjectLinkedOpenCustomHashSet<>(adaptStrategy(strategy));
} }

View File

@@ -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; package com.intellij.util.containers;
import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.io.FileUtilRt;
@@ -24,6 +24,18 @@ public final class FastUtilHashingStrategies {
private FastUtilHashingStrategies() { private FastUtilHashingStrategies() {
} }
public static final Hash.Strategy<String> FILE_PATH_HASH_STRATEGY = new Hash.Strategy<String>() {
@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> FILE_HASH_STRATEGY = new SerializableHashStrategy<File>() { public static final Hash.Strategy<File> FILE_HASH_STRATEGY = new SerializableHashStrategy<File>() {
@Override @Override
public int hashCode(@Nullable File o) { public int hashCode(@Nullable File o) {

View File

@@ -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; package com.intellij.util.containers;
import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.io.FileUtilRt;
import it.unimi.dsi.fastutil.Hash; import it.unimi.dsi.fastutil.Hash;
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenCustomHashMap; 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.ObjectLinkedOpenCustomHashSet;
import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -20,8 +21,9 @@ import java.util.Set;
* Creates map or set with canonicalized path hash strategy. * Creates map or set with canonicalized path hash strategy.
*/ */
public final class FileCollectionFactory { public final class FileCollectionFactory {
private interface SerializableHashingStrategy<T> extends HashingStrategy<T>, Serializable {} private interface SerializableHashingStrategy<T> extends Hash.Strategy<T>, Serializable {}
private static final HashingStrategy<File> FILE_HASH_STRATEGY = new SerializableHashingStrategy<File>() {
private static final SerializableHashingStrategy<File> FILE_HASH_STRATEGY = new SerializableHashingStrategy<File>() {
@Override @Override
public int hashCode(@Nullable File o) { public int hashCode(@Nullable File o) {
return FileUtilRt.pathHashCode(o == null ? null : o.getPath()); 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()); return FileUtilRt.pathsEqual(a == null ? null : a.getPath(), b == null ? null : b.getPath());
} }
}; };
public static final HashingStrategy<String> FILE_PATH_HASH_STRATEGY = new HashingStrategy<String>() {
@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. * Create linked map with canonicalized key hash strategy.
@@ -69,11 +60,11 @@ public final class FileCollectionFactory {
} }
public static @NotNull <V> Map<File, V> createCanonicalFileMap() { public static @NotNull <V> Map<File, V> createCanonicalFileMap() {
return CollectionFactory.createCustomHashingStrategyMap(FILE_HASH_STRATEGY); return new Object2ObjectOpenCustomHashMap<>(FILE_HASH_STRATEGY);
} }
public static @NotNull <V> Map<File, V> createCanonicalFileMap(int expected) { public static @NotNull <V> Map<File, V> createCanonicalFileMap(int expected) {
return CollectionFactory.createCustomHashingStrategyMap(expected, FILE_HASH_STRATEGY); return new Object2ObjectOpenCustomHashMap<>(expected, FILE_HASH_STRATEGY);
} }
public static @NotNull <V> Map<File, V> createCanonicalFileMap(@NotNull Map<? extends File, ? extends V> map) { public static @NotNull <V> Map<File, V> createCanonicalFileMap(@NotNull Map<? extends File, ? extends V> map) {
@@ -83,7 +74,7 @@ public final class FileCollectionFactory {
} }
public static @NotNull Set<File> createCanonicalFileSet() { public static @NotNull Set<File> createCanonicalFileSet() {
return CollectionFactory.createCustomHashingStrategySet(FILE_HASH_STRATEGY); return new ObjectOpenCustomHashSet<>(FILE_HASH_STRATEGY);
} }
public static @NotNull Set<File> createCanonicalFileSet(@NotNull Collection<? extends File> files) { public static @NotNull Set<File> createCanonicalFileSet(@NotNull Collection<? extends File> files) {
@@ -101,7 +92,7 @@ public final class FileCollectionFactory {
} }
public static @NotNull Set<String> createCanonicalFilePathSet() { public static @NotNull Set<String> createCanonicalFilePathSet() {
return CollectionFactory.createCustomHashingStrategySet(FILE_PATH_HASH_STRATEGY); return new ObjectOpenCustomHashSet<>(FastUtilHashingStrategies.FILE_PATH_HASH_STRATEGY);
} }
public static @NotNull Set<File> createCanonicalFileLinkedSet() { public static @NotNull Set<File> createCanonicalFileLinkedSet() {

View File

@@ -35,9 +35,8 @@ import static java.nio.file.attribute.PosixFilePermission.*;
/** /**
* Utilities for working with {@link File}. * Utilities for working with {@link File}.
*/ */
@SuppressWarnings("MethodOverridesStaticMethodOfSuperclass")
@ApiStatus.NonExtendable @ApiStatus.NonExtendable
public class FileUtil extends FileUtilRt { public class FileUtil {
public static final String ASYNC_DELETE_EXTENSION = ".__del__"; public static final String ASYNC_DELETE_EXTENSION = ".__del__";
public static final int REGEX_PATTERN_FLAGS = SystemInfoRt.isFileSystemCaseSensitive ? 0 : Pattern.CASE_INSENSITIVE; 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"); 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."); 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); 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. * 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)} * 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) * @see FileUtilRt#doDelete(Path)
*/ */
public static void delete(@NotNull Path path) throws IOException { public static void delete(@NotNull Path path) throws IOException {
deleteRecursively(path, null); FileUtilRt.deleteRecursively(path, null);
} }
public static boolean createParentDirs(@NotNull File file) { public static boolean createParentDirs(@NotNull File file) {
@@ -385,6 +388,10 @@ public class FileUtil extends FileUtilRt {
return FileUtilRt.ensureCanCreateFile(file); 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 { public static void copy(@NotNull File fromFile, @NotNull File toFile) throws IOException {
performCopy(fromFile, toFile, true); performCopy(fromFile, toFile, true);
} }
@@ -586,6 +593,10 @@ public class FileUtil extends FileUtilRt {
return FileUtilRt.toSystemDependentName(filePath); 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 * 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. * 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") @Contract("null -> null; !null->!null")
public static String toCanonicalPath(@Nullable String path) { 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") @Contract("null, _ -> null; !null,_->!null")
public static String toCanonicalPath(@Nullable String path, char separatorChar) { 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") @Contract("null -> null; !null->!null")
public static String toCanonicalUriPath(@Nullable String path) { 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 @Override
public @NotNull String resolveSymlinksAndCanonicalize(@NotNull String path, char separatorChar, boolean removeLastSlash) { public @NotNull String resolveSymlinksAndCanonicalize(@NotNull String path, char separatorChar, boolean removeLastSlash) {
try { try {
@@ -659,8 +674,8 @@ public class FileUtil extends FileUtilRt {
char separatorChar, char separatorChar,
boolean removeLastSlash, boolean removeLastSlash,
boolean resolveSymlinks) { boolean resolveSymlinks) {
SymlinkResolver symlinkResolver = resolveSymlinks ? SYMLINK_RESOLVER : null; FileUtilRt.SymlinkResolver symlinkResolver = resolveSymlinks ? SYMLINK_RESOLVER : null;
return toCanonicalPath(path, separatorChar, removeLastSlash, symlinkResolver); return FileUtilRt.toCanonicalPath(path, separatorChar, removeLastSlash, symlinkResolver);
} }
/** /**
@@ -799,6 +814,14 @@ public class FileUtil extends FileUtilRt {
return Strings.toLowerCase(FileUtilRt.getExtension(fileName)); 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 { public static @NotNull @NlsSafe String resolveShortWindowsName(@NotNull String path) throws IOException {
try { try {
return SystemInfoRt.isWindows && containsWindowsShortName(path) ? Paths.get(path).toRealPath(LinkOption.NOFOLLOW_LINKS).toString() : path; 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(); 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 { public static void setExecutable(@NotNull File file) throws IOException {
NioFiles.setExecutable(file.toPath()); NioFiles.setExecutable(file.toPath());
} }
@@ -1395,7 +1422,11 @@ public class FileUtil extends FileUtilRt {
return FileUtilRt.loadFileText(file); 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); return FileUtilRt.loadFileText(file, encoding);
} }
@@ -1432,7 +1463,11 @@ public class FileUtil extends FileUtilRt {
} }
public static @NotNull List<String> splitPath(@NotNull String path) { public static @NotNull List<String> splitPath(@NotNull String path) {
return splitPath(path, File.separatorChar); return FileUtilRt.splitPath(path, File.separatorChar);
}
public static @NotNull List<String> splitPath(@NotNull String path, char separatorChar) {
return FileUtilRt.splitPath(path, separatorChar);
} }
public static boolean visitFiles(@NotNull File root, @NotNull Processor<? super File> processor) { public static boolean visitFiles(@NotNull File root, @NotNull Processor<? super File> processor) {
@@ -1482,4 +1517,13 @@ public class FileUtil extends FileUtilRt {
public static @NotNull URI fileToUri(@NotNull File file) { public static @NotNull URI fileToUri(@NotNull File file) {
return FileUtilRt.fileToUri(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);
}
} }

View File

@@ -18,7 +18,8 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.ProjectJdkTable import com.intellij.openapi.projectRoots.ProjectJdkTable
import com.intellij.openapi.util.UserDataHolderBase 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.platform.externalSystem.rt.ExternalSystemRtClass
import com.intellij.util.PathMapper import com.intellij.util.PathMapper
import com.intellij.util.PathMappingSettings import com.intellij.util.PathMappingSettings
@@ -122,29 +123,33 @@ internal class GradleServerEnvironmentSetupImpl(private val project: Project,
val pathsToUpload: MutableSet<String> = HashSet() val pathsToUpload: MutableSet<String> = HashSet()
val workingDir = consumerOperationParameters.projectDir val workingDir = consumerOperationParameters.projectDir
val gradleProjectDirectory = toSystemDependentName(workingDir.path) val gradleProjectDirectory = FileUtilRt.toSystemDependentName(workingDir.path)
pathsToUpload.add(gradleProjectDirectory) pathsToUpload.add(gradleProjectDirectory)
val projectSettings = GradleSettings.getInstance(project).getLinkedProjectSettings( val projectSettings = GradleSettings.getInstance(project).getLinkedProjectSettings(
ExternalSystemApiUtil.toCanonicalPath(workingDir.path)) ExternalSystemApiUtil.toCanonicalPath(workingDir.path))
projectSettings?.modules projectSettings?.modules
?.filter { Files.exists(Path.of(it)) } ?.filter { Files.exists(Path.of(it)) }
?.mapTo(pathsToUpload) { toSystemDependentName(it) } ?.mapTo(pathsToUpload) { FileUtilRt.toSystemDependentName(it) }
val commonAncestor = findCommonAncestor(pathsToUpload) 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()) val uploadRoot = TargetEnvironment.UploadRoot(uploadPath, TargetEnvironment.TargetPath.Temporary())
request.uploadVolumes += uploadRoot request.uploadVolumes += uploadRoot
val targetFileSeparator = request.targetPlatform.platform.fileSeparator val targetFileSeparator = request.targetPlatform.platform.fileSeparator
var targetWorkingDirectory: TargetValue<String>? = null var targetWorkingDirectory: TargetValue<String>? = null
for (path in pathsToUpload) { 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!!) val targetValue = targetEnvironmentProvider.upload(uploadRoot, path, relativePath!!)
if (targetWorkingDirectory == null && isAncestor(path, gradleProjectDirectory, false)) { if (targetWorkingDirectory == null && FileUtil.isAncestor(path, gradleProjectDirectory, false)) {
val workingDirRelativePath = getRelativePath(path, gradleProjectDirectory, File.separatorChar)!! val workingDirRelativePath = FileUtilRt.getRelativePath(path, gradleProjectDirectory, File.separatorChar)!!
val targetWorkingDirRelativePath = if (workingDirRelativePath == ".") "" val targetWorkingDirRelativePath = if (workingDirRelativePath == ".") {
else toSystemDependentName(workingDirRelativePath, targetFileSeparator) ""
}
else {
FileUtilRt.toSystemDependentName(workingDirRelativePath, targetFileSeparator)
}
targetWorkingDirectory = TargetValue.map(targetValue) { "$it$targetFileSeparator$targetWorkingDirRelativePath" } targetWorkingDirectory = TargetValue.map(targetValue) { "$it$targetFileSeparator$targetWorkingDirRelativePath" }
} }
} }
@@ -155,7 +160,7 @@ internal class GradleServerEnvironmentSetupImpl(private val project: Project,
private fun findCommonAncestor(paths: Set<String>): String? { private fun findCommonAncestor(paths: Set<String>): String? {
var commonRoot: File? = null var commonRoot: File? = null
for (path in paths) { 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" } requireNotNull(commonRoot) { "no common root found" }
} }
assert(commonRoot != null) assert(commonRoot != null)
@@ -207,7 +212,7 @@ internal class GradleServerEnvironmentSetupImpl(private val project: Project,
if (request is LocalTargetEnvironmentRequest) { if (request is LocalTargetEnvironmentRequest) {
javaParameters.vmParametersList.addProperty(Main.LOCAL_BUILD_PROPERTY, "true") javaParameters.vmParametersList.addProperty(Main.LOCAL_BUILD_PROPERTY, "true")
val javaHomePath = consumerOperationParameters.javaHome.path 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 { else {
if (environmentConfiguration.runtimes.findByType(JavaLanguageRuntimeConfiguration::class.java) == null) { if (environmentConfiguration.runtimes.findByType(JavaLanguageRuntimeConfiguration::class.java) == null) {
@@ -382,7 +387,7 @@ internal class GradleServerEnvironmentSetupImpl(private val project: Project,
fun requestUploadIntoTarget(path: String, fun requestUploadIntoTarget(path: String,
request: TargetEnvironmentRequest, request: TargetEnvironmentRequest,
environmentConfiguration: TargetEnvironmentConfiguration): TargetValue<String> { environmentConfiguration: TargetEnvironmentConfiguration): TargetValue<String> {
val uploadPath = Paths.get(toSystemDependentName(path)) val uploadPath = Paths.get(FileUtilRt.toSystemDependentName(path))
val localRootPath = uploadPath.parent val localRootPath = uploadPath.parent
val languageRuntime = environmentConfiguration.runtimes.findByType(JavaLanguageRuntimeConfiguration::class.java) val languageRuntime = environmentConfiguration.runtimes.findByType(JavaLanguageRuntimeConfiguration::class.java)