summaryrefslogtreecommitdiff
path: root/platform/util/src/com/intellij
diff options
context:
space:
mode:
Diffstat (limited to 'platform/util/src/com/intellij')
-rw-r--r--platform/util/src/com/intellij/execution/configurations/CommandLineTokenizer.java10
-rw-r--r--platform/util/src/com/intellij/icons/AllIcons.java1
-rw-r--r--platform/util/src/com/intellij/openapi/application/PathManager.java8
-rw-r--r--platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java27
-rw-r--r--platform/util/src/com/intellij/openapi/util/JDOMUtil.java22
-rw-r--r--platform/util/src/com/intellij/openapi/util/io/FileUtil.java9
-rw-r--r--platform/util/src/com/intellij/openapi/util/text/StringUtil.java268
-rw-r--r--platform/util/src/com/intellij/util/ArrayUtil.java63
-rw-r--r--platform/util/src/com/intellij/util/ReflectionUtil.java52
-rw-r--r--platform/util/src/com/intellij/util/Restarter.java13
-rw-r--r--platform/util/src/com/intellij/util/containers/ContainerUtil.java227
-rw-r--r--platform/util/src/com/intellij/util/containers/FactoryMap.java10
-rw-r--r--platform/util/src/com/intellij/util/containers/TransferToEDTQueue.java3
-rw-r--r--platform/util/src/com/intellij/util/io/AppendableStorageBackedByResizableMappedFile.java3
-rw-r--r--platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java4
-rw-r--r--platform/util/src/com/intellij/util/messages/impl/MessageListenerList.java10
-rw-r--r--platform/util/src/com/intellij/util/ui/JBSwingUtilities.java53
-rw-r--r--platform/util/src/com/intellij/util/ui/UIUtil.java19
-rw-r--r--platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java3
19 files changed, 724 insertions, 81 deletions
diff --git a/platform/util/src/com/intellij/execution/configurations/CommandLineTokenizer.java b/platform/util/src/com/intellij/execution/configurations/CommandLineTokenizer.java
index a62af9aa62dc..3f351b9a573e 100644
--- a/platform/util/src/com/intellij/execution/configurations/CommandLineTokenizer.java
+++ b/platform/util/src/com/intellij/execution/configurations/CommandLineTokenizer.java
@@ -20,9 +20,9 @@ import java.util.List;
import java.util.StringTokenizer;
/**
- * Splits input String to tokens being aware of quoted tokens ("foo bar") and escaped spaces (foo\ bar),
+ * Splits input String to tokens being aware of quoted tokens ("foo bar") and escaped spaces & quotes (\"foo\ bar\"),
* usually used for splitting command line to separate arguments that may contain space symbols.
- * Escaped symbols are not handled so there's no way to get token that itself contains quotation mark.
+ * Space and quote are the only symbols that can be escaped
*/
public class CommandLineTokenizer extends StringTokenizer {
@@ -103,8 +103,10 @@ public class CommandLineTokenizer extends StringTokenizer {
do {
while ((i = nextToken.indexOf('"')) >= 0) {
- quotationMarks++;
- buffer.append(nextToken.substring(0, i));
+ boolean isEscapedQuote = i > 0 && nextToken.charAt(i - 1) == '\\';
+ if (!isEscapedQuote) quotationMarks++;
+ buffer.append(nextToken.substring(0, isEscapedQuote ? i - 1 : i));
+ if (isEscapedQuote) buffer.append('"');
nextToken = nextToken.substring(i + 1);
}
diff --git a/platform/util/src/com/intellij/icons/AllIcons.java b/platform/util/src/com/intellij/icons/AllIcons.java
index a80ffccdd58e..f31f9b94b058 100644
--- a/platform/util/src/com/intellij/icons/AllIcons.java
+++ b/platform/util/src/com/intellij/icons/AllIcons.java
@@ -204,6 +204,7 @@ public class AllIcons {
public static final Icon AutoVariablesMode = IconLoader.getIcon("/debugger/autoVariablesMode.png"); // 16x16
public static final Icon BreakpointAlert = IconLoader.getIcon("/debugger/breakpointAlert.png"); // 16x16
public static final Icon Class_filter = IconLoader.getIcon("/debugger/class_filter.png"); // 16x16
+ public static final Icon CommandLine = IconLoader.getIcon("/debugger/commandLine.png"); // 16x16
public static final Icon Console = IconLoader.getIcon("/debugger/console.png"); // 16x16
public static final Icon Db_array = IconLoader.getIcon("/debugger/db_array.png"); // 16x16
public static final Icon Db_db_object = IconLoader.getIcon("/debugger/db_db_object.png"); // 16x16
diff --git a/platform/util/src/com/intellij/openapi/application/PathManager.java b/platform/util/src/com/intellij/openapi/application/PathManager.java
index 9956959f0e22..0188203cde33 100644
--- a/platform/util/src/com/intellij/openapi/application/PathManager.java
+++ b/platform/util/src/com/intellij/openapi/application/PathManager.java
@@ -45,7 +45,6 @@ public class PathManager {
@NonNls public static final String PROPERTY_HOME_PATH = "idea.home.path";
@NonNls public static final String PROPERTY_LOG_PATH = "idea.log.path";
@NonNls public static final String PROPERTY_PATHS_SELECTOR = "idea.paths.selector";
- @NonNls public static final String PROPERTY_ORIGINAL_WORKING_DIR = "original.working.dir";
@NonNls public static final String DEFAULT_OPTIONS_FILE_NAME = "other";
@NonNls private static final String LIB_FOLDER = "lib";
@@ -253,11 +252,6 @@ public class PathManager {
// misc stuff
- @Nullable
- public static String getOriginalWorkingDir() {
- return System.getProperty(PROPERTY_ORIGINAL_WORKING_DIR);
- }
-
/**
* Attempts to detect classpath entry which contains given resource.
*/
@@ -418,7 +412,7 @@ public class PathManager {
private static String getAbsolutePath(String path) {
path = FileUtil.expandUserHome(path);
- return FileUtil.toCanonicalPath(new File(FileUtil.toCanonicalPath(path)).getAbsolutePath());
+ return FileUtil.toCanonicalPath(new File(path).getAbsolutePath());
}
private static String trimPathQuotes(String path){
diff --git a/platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java b/platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java
index 909c44db199b..cd5e8630a087 100644
--- a/platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java
+++ b/platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java
@@ -22,7 +22,10 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.*;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
public class JDOMExternalizer {
private JDOMExternalizer() {
@@ -66,7 +69,7 @@ public class JDOMExternalizer {
return null;
}
- public static void writeMap(Element root, Map<String, String>map, @NonNls @Nullable String rootName, @NonNls String entryName) {
+ public static void writeMap(Element root, Map<String, String> map, @NonNls @Nullable String rootName, @NonNls String entryName) {
Element mapRoot;
if (StringUtil.isNotEmpty(rootName)) {
mapRoot = new Element(rootName);
@@ -106,6 +109,26 @@ public class JDOMExternalizer {
}
}
+ /**
+ * Saves a pack of strings to some attribte. I.e: [tag attr="value"]
+ * @param parent parent element (where to add newly created tags)
+ * @param nodeName node name (tag, in our example)
+ * @param attrName attribute name (attr, in our example)
+ * @param values a pack of values to add
+ * @see #loadStringsList(org.jdom.Element, String, String)
+ */
+ public static void saveStringsList(@NotNull final Element parent,
+ @NotNull final String nodeName,
+ @NotNull final String attrName,
+ @NotNull final String... values) {
+ for (final String value : values) {
+ final Element node = new Element(nodeName);
+ node.setAttribute(attrName, value);
+ parent.addContent(node);
+ }
+ }
+
+ @NotNull
public static List<String> loadStringsList(Element element, String rootName, String attrName) {
final List<String> paths = new LinkedList<String>();
if (element != null) {
diff --git a/platform/util/src/com/intellij/openapi/util/JDOMUtil.java b/platform/util/src/com/intellij/openapi/util/JDOMUtil.java
index c82ee6df346b..dfee1dbed2df 100644
--- a/platform/util/src/com/intellij/openapi/util/JDOMUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/JDOMUtil.java
@@ -398,9 +398,13 @@ public class JDOMUtil {
}
public static void writeDocument(@NotNull Document document, @NotNull File file, String lineSeparator) throws IOException {
+ writeParent(document, file, lineSeparator);
+ }
+
+ public static void writeParent(@NotNull Parent element, @NotNull File file, String lineSeparator) throws IOException {
OutputStream stream = new BufferedOutputStream(new FileOutputStream(file));
try {
- writeDocument(document, stream, lineSeparator);
+ writeParent(element, stream, lineSeparator);
}
finally {
stream.close();
@@ -408,9 +412,23 @@ public class JDOMUtil {
}
public static void writeDocument(@NotNull Document document, @NotNull OutputStream stream, String lineSeparator) throws IOException {
- writeDocument(document, new OutputStreamWriter(stream, CharsetToolkit.UTF8_CHARSET), lineSeparator);
+ writeParent(document, stream, lineSeparator);
}
+ public static void writeParent(@NotNull Parent element, @NotNull OutputStream stream, @NotNull String lineSeparator) throws IOException {
+ OutputStreamWriter writer = new OutputStreamWriter(stream, CharsetToolkit.UTF8_CHARSET);
+ try {
+ if (element instanceof Document) {
+ writeDocument((Document)element, writer, lineSeparator);
+ }
+ else {
+ writeElement((Element) element, writer, lineSeparator);
+ }
+ }
+ finally {
+ writer.close();
+ }
+ }
@NotNull
public static byte[] printDocument(@NotNull Document document, String lineSeparator) throws IOException {
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 7d3d6f557249..bc41f70e933a 100644
--- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
@@ -1249,18 +1249,15 @@ public class FileUtil extends FileUtilRt {
}
public static boolean isWindowsAbsolutePath(@NotNull String pathString) {
- if (pathString.length() >= 2 && Character.isLetter(pathString.charAt(0)) && pathString.charAt(1) == ':') {
- return true;
- }
- return false;
+ return pathString.length() >= 2 && Character.isLetter(pathString.charAt(0)) && pathString.charAt(1) == ':';
}
- @Contract("null -> null")
+ @Contract("null -> null; !null -> !null")
public static String getLocationRelativeToUserHome(@Nullable String path) {
return getLocationRelativeToUserHome(path, true);
}
- @Contract("null,_ -> null")
+ @Contract("null,_ -> null; !null,_ -> !null")
public static String getLocationRelativeToUserHome(@Nullable String path, boolean unixOnly) {
if (path == null) return null;
diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
index af2b3dd4293e..c2b7de8ba7ed 100644
--- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
@@ -64,6 +64,7 @@ public class StringUtil extends StringUtilRt {
};
@NotNull
+ @Contract(pure = true)
public static List<String> getWordsInStringLongestFirst(@NotNull String find) {
List<String> words = getWordsIn(find);
// hope long words are rare
@@ -77,11 +78,13 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String escapePattern(@NotNull final String text) {
return replace(replace(text, "'", "''"), "{", "'{'");
}
@NotNull
+ @Contract(pure = true)
public static <T> Function<T, String> createToStringFunction(@NotNull Class<T> cls) {
return new Function<T, String>() {
@Override
@@ -101,11 +104,13 @@ public class StringUtil extends StringUtilRt {
};
@NotNull
+ @Contract(pure = true)
public static String replace(@NonNls @NotNull String text, @NonNls @NotNull String oldS, @NonNls @NotNull String newS) {
return replace(text, oldS, newS, false);
}
@NotNull
+ @Contract(pure = true)
public static String replaceIgnoreCase(@NonNls @NotNull String text, @NonNls @NotNull String oldS, @NonNls @NotNull String newS) {
return replace(text, oldS, newS, true);
}
@@ -120,6 +125,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String replaceChar(@NotNull String buffer, char oldChar, char newChar) {
StringBuilder newBuffer = null;
for (int i = 0; i < buffer.length(); i++) {
@@ -139,6 +145,7 @@ public class StringUtil extends StringUtilRt {
return newBuffer == null ? buffer : newBuffer.toString();
}
+ @Contract(pure = true)
public static String replace(@NonNls @NotNull final String text, @NonNls @NotNull final String oldS, @NonNls @NotNull final String newS, final boolean ignoreCase) {
if (text.length() < oldS.length()) return text;
@@ -146,17 +153,26 @@ public class StringUtil extends StringUtilRt {
int i = 0;
while (i < text.length()) {
- final int i1 = ignoreCase? indexOfIgnoreCase(text, oldS, i) : text.indexOf(oldS, i);
- if (i1 < 0) {
- if (i == 0) return text;
+ final int index = ignoreCase? indexOfIgnoreCase(text, oldS, i) : text.indexOf(oldS, i);
+ if (index < 0) {
+ if (i == 0) {
+ return text;
+ }
+
newText.append(text, i, text.length());
break;
}
else {
- if (newText == null) newText = new StringBuilder(text.length() - i);
- newText.append(text, i, i1);
+ if (newText == null) {
+ if (text.length() == oldS.length()) {
+ return newS;
+ }
+ newText = new StringBuilder(text.length() - i);
+ }
+
+ newText.append(text, i, index);
newText.append(newS);
- i = i1 + oldS.length();
+ i = index + oldS.length();
}
}
return newText != null ? newText.toString() : "";
@@ -165,6 +181,7 @@ public class StringUtil extends StringUtilRt {
/**
* Implementation copied from {@link String#indexOf(String, int)} except character comparisons made case insensitive
*/
+ @Contract(pure = true)
public static int indexOfIgnoreCase(@NotNull String where, @NotNull String what, int fromIndex) {
int targetCount = what.length();
int sourceCount = where.length();
@@ -206,6 +223,7 @@ public class StringUtil extends StringUtilRt {
return -1;
}
+ @Contract(pure = true)
public static int indexOfIgnoreCase(@NotNull String where, char what, int fromIndex) {
int sourceCount = where.length();
@@ -226,18 +244,22 @@ public class StringUtil extends StringUtilRt {
return -1;
}
+ @Contract(pure = true)
public static boolean containsIgnoreCase(@NotNull String where, @NotNull String what) {
return indexOfIgnoreCase(where, what, 0) >= 0;
}
+ @Contract(pure = true)
public static boolean endsWithIgnoreCase(@NonNls @NotNull String str, @NonNls @NotNull String suffix) {
return StringUtilRt.endsWithIgnoreCase(str, suffix);
}
+ @Contract(pure = true)
public static boolean startsWithIgnoreCase(@NonNls @NotNull String str, @NonNls @NotNull String prefix) {
return StringUtilRt.startsWithIgnoreCase(str, prefix);
}
+ @Contract(pure = true)
public static String stripHtml(@NotNull String html, boolean convertBreaks) {
if (convertBreaks) {
html = html.replaceAll("<br/?>", "\n\n");
@@ -246,18 +268,20 @@ public class StringUtil extends StringUtilRt {
return html.replaceAll("<(.|\n)*?>", "");
}
- @Contract("null -> null; !null -> !null")
+ @Contract(value = "null -> null; !null -> !null", pure = true)
public static String toLowerCase(@Nullable final String str) {
//noinspection ConstantConditions
return str == null ? null : str.toLowerCase();
}
@NotNull
+ @Contract(pure = true)
public static String getPackageName(@NotNull String fqName) {
return getPackageName(fqName, '.');
}
@NotNull
+ @Contract(pure = true)
public static String getPackageName(@NotNull String fqName, char separator) {
int lastPointIdx = fqName.lastIndexOf(separator);
if (lastPointIdx >= 0) {
@@ -266,6 +290,7 @@ public class StringUtil extends StringUtilRt {
return "";
}
+ @Contract(pure = true)
public static int getLineBreakCount(@NotNull CharSequence text) {
int count = 0;
for (int i = 0; i < text.length(); i++) {
@@ -287,6 +312,7 @@ public class StringUtil extends StringUtilRt {
return count;
}
+ @Contract(pure = true)
public static boolean containsLineBreak(@NotNull CharSequence text) {
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
@@ -295,11 +321,13 @@ public class StringUtil extends StringUtilRt {
return false;
}
+ @Contract(pure = true)
public static boolean isLineBreak(char c) {
return c == '\n' || c == '\r';
}
@NotNull
+ @Contract(pure = true)
public static String escapeLineBreak(@NotNull String text) {
StringBuilder buffer = new StringBuilder(text.length());
for (int i = 0; i < text.length(); i++) {
@@ -318,11 +346,13 @@ public class StringUtil extends StringUtilRt {
return buffer.toString();
}
+ @Contract(pure = true)
public static boolean endsWithLineBreak(@NotNull CharSequence text) {
int len = text.length();
return len > 0 && isLineBreak(text.charAt(len - 1));
}
+ @Contract(pure = true)
public static int lineColToOffset(@NotNull CharSequence text, int line, int col) {
int curLine = 0;
int offset = 0;
@@ -343,6 +373,7 @@ public class StringUtil extends StringUtilRt {
return offset + col;
}
+ @Contract(pure = true)
public static int offsetToLineNumber(@NotNull CharSequence text, int offset) {
int curLine = 0;
int curOffset = 0;
@@ -366,6 +397,7 @@ public class StringUtil extends StringUtilRt {
/**
* Classic dynamic programming algorithm for string differences.
*/
+ @Contract(pure = true)
public static int difference(@NotNull String s1, @NotNull String s2) {
int[][] a = new int[s1.length()][s2.length()];
@@ -388,11 +420,13 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String wordsToBeginFromUpperCase(@NotNull String s) {
return toTitleCase(s, ourPrepositions);
}
@NotNull
+ @Contract(pure = true)
public static String toTitleCase(@NotNull String s) {
return toTitleCase(s, ArrayUtil.EMPTY_STRING_ARRAY);
}
@@ -435,10 +469,12 @@ public class StringUtil extends StringUtilRt {
"per", "nor", "the", "to", "up", "upon", "via", "with"
};
+ @Contract(pure = true)
public static boolean isPreposition(@NotNull String s, int firstChar, int lastChar) {
return isPreposition(s, firstChar, lastChar, ourPrepositions);
}
+ @Contract(pure = true)
public static boolean isPreposition(@NotNull String s, int firstChar, int lastChar, @NotNull String[] prepositions) {
for (String preposition : prepositions) {
boolean found = false;
@@ -458,6 +494,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static NotNullFunction<String, String> escaper(final boolean escapeSlash, @Nullable final String additionalChars) {
return new NotNullFunction<String, String>() {
@NotNull
@@ -538,6 +575,7 @@ public class StringUtil extends StringUtilRt {
return buffer;
}
+ @Contract(pure = true)
private static boolean isPrintableUnicode(char c) {
int t = Character.getType(c);
return t != Character.UNASSIGNED && t != Character.LINE_SEPARATOR && t != Character.PARAGRAPH_SEPARATOR &&
@@ -545,6 +583,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String escapeStringCharacters(@NotNull String s) {
StringBuilder buffer = new StringBuilder(s.length());
escapeStringCharacters(s.length(), s, "\"", buffer);
@@ -552,6 +591,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String escapeCharCharacters(@NotNull String s) {
StringBuilder buffer = new StringBuilder(s.length());
escapeStringCharacters(s.length(), s, "\'", buffer);
@@ -559,6 +599,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String unescapeStringCharacters(@NotNull String s) {
StringBuilder buffer = new StringBuilder(s.length());
unescapeStringCharacters(s.length(), s, buffer);
@@ -566,6 +607,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String unquoteString(@NotNull String s) {
char c;
if (s.length() <= 1 || (c = s.charAt(0)) != '"' && c != '\'' || s.charAt(s.length() - 1) != c) {
@@ -575,6 +617,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String unquoteString(@NotNull String s, char quotationChar) {
char c;
if (s.length() <= 1 || (c = s.charAt(0)) != quotationChar || s.charAt(s.length() - 1) != c) {
@@ -587,6 +630,7 @@ public class StringUtil extends StringUtilRt {
* This is just an optimized version of Matcher.quoteReplacement
*/
@NotNull
+ @Contract(pure = true)
public static String quoteReplacement(@NotNull String s) {
boolean needReplacements = false;
@@ -693,6 +737,7 @@ public class StringUtil extends StringUtilRt {
@SuppressWarnings({"HardCodedStringLiteral"})
@NotNull
+ @Contract(pure = true)
public static String pluralize(@NotNull String suggestion) {
if (suggestion.endsWith("Child") || suggestion.endsWith("child")) {
return suggestion + "ren";
@@ -718,12 +763,14 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String capitalizeWords(@NotNull String text,
boolean allWords) {
return capitalizeWords(text, " \t\n\r\f", allWords, false);
}
@NotNull
+ @Contract(pure = true)
public static String capitalizeWords(@NotNull String text,
@NotNull String tokenizerDelim,
boolean allWords,
@@ -744,15 +791,18 @@ public class StringUtil extends StringUtilRt {
return out.toString();
}
+ @Contract(pure = true)
public static String decapitalize(String s) {
return Introspector.decapitalize(s);
}
+ @Contract(pure = true)
public static boolean isVowel(char c) {
return VOWELS.indexOf(c) >= 0;
}
@NotNull
+ @Contract(pure = true)
public static String capitalize(@NotNull String s) {
if (s.isEmpty()) return s;
if (s.length() == 1) return StringUtilRt.toUpperCase(s);
@@ -762,12 +812,13 @@ public class StringUtil extends StringUtilRt {
return toUpperCase(s.charAt(0)) + s.substring(1);
}
- @Contract("null -> false")
+ @Contract(value = "null -> false", pure = true)
public static boolean isCapitalized(@Nullable String s) {
return s != null && !s.isEmpty() && Character.isUpperCase(s.charAt(0));
}
@NotNull
+ @Contract(pure = true)
public static String capitalizeWithJavaBeanConvention(@NotNull String s) {
if (s.length() > 1 && Character.isUpperCase(s.charAt(1))) {
return s;
@@ -775,6 +826,7 @@ public class StringUtil extends StringUtilRt {
return capitalize(s);
}
+ @Contract(pure = true)
public static int stringHashCode(@NotNull CharSequence chars) {
if (chars instanceof String) return chars.hashCode();
if (chars instanceof CharSequenceWithStringHash) return chars.hashCode();
@@ -783,6 +835,7 @@ public class StringUtil extends StringUtilRt {
return stringHashCode(chars, 0, chars.length());
}
+ @Contract(pure = true)
public static int stringHashCode(@NotNull CharSequence chars, int from, int to) {
int h = 0;
for (int off = from; off < to; off++) {
@@ -791,6 +844,7 @@ public class StringUtil extends StringUtilRt {
return h;
}
+ @Contract(pure = true)
public static int stringHashCode(char[] chars, int from, int to) {
int h = 0;
for (int off = from; off < to; off++) {
@@ -799,6 +853,7 @@ public class StringUtil extends StringUtilRt {
return h;
}
+ @Contract(pure = true)
public static int stringHashCodeInsensitive(@NotNull char[] chars, int from, int to) {
int h = 0;
for (int off = from; off < to; off++) {
@@ -807,6 +862,7 @@ public class StringUtil extends StringUtilRt {
return h;
}
+ @Contract(pure = true)
public static int stringHashCodeInsensitive(@NotNull CharSequence chars, int from, int to) {
int h = 0;
for (int off = from; off < to; off++) {
@@ -815,6 +871,7 @@ public class StringUtil extends StringUtilRt {
return h;
}
+ @Contract(pure = true)
public static int stringHashCodeInsensitive(@NotNull CharSequence chars) {
return stringHashCodeInsensitive(chars, 0, chars.length());
}
@@ -822,6 +879,7 @@ public class StringUtil extends StringUtilRt {
/**
* Equivalent to string.startsWith(prefixes[0] + prefixes[1] + ...) but avoids creating an object for concatenation.
*/
+ @Contract(pure = true)
public static boolean startsWithConcatenation(@NotNull String string, @NotNull String... prefixes) {
int offset = 0;
for (String prefix : prefixes) {
@@ -838,6 +896,7 @@ public class StringUtil extends StringUtilRt {
* @deprecated use {@link #startsWithConcatenation(String, String...)} (to remove in IDEA 14).
*/
@SuppressWarnings("UnusedDeclaration")
+ @Contract(pure = true)
public static boolean startsWithConcatenationOf(@NotNull String string, @NotNull String firstPrefix, @NotNull String secondPrefix) {
return startsWithConcatenation(string, firstPrefix, secondPrefix);
}
@@ -846,6 +905,7 @@ public class StringUtil extends StringUtilRt {
* @deprecated use {@link #startsWithConcatenation(String, String...)} (to remove in IDEA 14).
*/
@SuppressWarnings("UnusedDeclaration")
+ @Contract(pure = true)
public static boolean startsWithConcatenationOf(@NotNull String string,
@NotNull String firstPrefix,
@NotNull String secondPrefix,
@@ -853,12 +913,13 @@ public class StringUtil extends StringUtilRt {
return startsWithConcatenation(string, firstPrefix, secondPrefix, thirdPrefix);
}
- @Contract("null -> null; !null -> !null")
+ @Contract(value = "null -> null; !null -> !null", pure = true)
public static String trim(@Nullable String s) {
return s == null ? null : s.trim();
}
@NotNull
+ @Contract(pure = true)
public static String trimEnd(@NotNull String s, @NonNls @NotNull String suffix) {
if (s.endsWith(suffix)) {
return s.substring(0, s.length() - suffix.length());
@@ -867,6 +928,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String trimLog(@NotNull final String text, final int limit) {
if (limit > 5 && text.length() > limit) {
return text.substring(0, limit - 5) + " ...\n";
@@ -875,6 +937,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String trimLeading(@NotNull String string) {
int index = 0;
while (index < string.length() && Character.isWhitespace(string.charAt(index))) index++;
@@ -882,6 +945,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String trimLeading(@NotNull String string, char symbol) {
int index = 0;
while (index < string.length() && string.charAt(index) == symbol) index++;
@@ -889,21 +953,25 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String trimTrailing(@NotNull String string) {
int index = string.length() - 1;
while (index >= 0 && Character.isWhitespace(string.charAt(index))) index--;
return string.substring(0, index + 1);
}
+ @Contract(pure = true)
public static boolean startsWithChar(@Nullable CharSequence s, char prefix) {
return s != null && s.length() != 0 && s.charAt(0) == prefix;
}
+ @Contract(pure = true)
public static boolean endsWithChar(@Nullable CharSequence s, char suffix) {
return StringUtilRt.endsWithChar(s, suffix);
}
@NotNull
+ @Contract(pure = true)
public static String trimStart(@NotNull String s, @NonNls @NotNull String prefix) {
if (s.startsWith(prefix)) {
return s.substring(prefix.length());
@@ -912,6 +980,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String pluralize(@NotNull String base, int n) {
if (n == 1) return base;
return pluralize(base);
@@ -929,45 +998,51 @@ public class StringUtil extends StringUtilRt {
}
}
+ @Contract(pure = true)
public static String defaultIfEmpty(@Nullable String value, String defaultValue) {
return isEmpty(value) ? defaultValue : value;
}
- @Contract("null -> false")
+ @Contract(value = "null -> false", pure = true)
public static boolean isNotEmpty(@Nullable String s) {
return s != null && !s.isEmpty();
}
- @Contract("null -> true")
+ @Contract(value = "null -> true", pure=true)
public static boolean isEmpty(@Nullable String s) {
return s == null || s.isEmpty();
}
- @Contract("null -> true")
+ @Contract(value = "null -> true",pure = true)
public static boolean isEmpty(@Nullable CharSequence cs) {
return cs == null || cs.length() == 0;
}
+ @Contract(pure = true)
public static int length(@Nullable CharSequence cs) {
return cs == null ? 0 : cs.length();
}
@NotNull
+ @Contract(pure = true)
public static String notNullize(@Nullable final String s) {
return notNullize(s, "");
}
@NotNull
+ @Contract(pure = true)
public static String notNullize(@Nullable final String s, @NotNull String defaultValue) {
return s == null ? defaultValue : s;
}
@Nullable
+ @Contract(pure = true)
public static String nullize(@Nullable final String s) {
return nullize(s, false);
}
@Nullable
+ @Contract(pure = true)
public static String nullize(@Nullable final String s, boolean nullizeSpaces) {
if (nullizeSpaces) {
if (isEmptyOrSpaces(s)) return null;
@@ -978,13 +1053,13 @@ public class StringUtil extends StringUtilRt {
return s;
}
- @Contract("null -> true")
+ @Contract(value = "null -> true",pure = true)
// we need to keep this method to preserve backward compatibility
public static boolean isEmptyOrSpaces(@Nullable String s) {
return isEmptyOrSpaces(((CharSequence)s));
}
- @Contract("null -> true")
+ @Contract(value = "null -> true", pure = true)
public static boolean isEmptyOrSpaces(@Nullable CharSequence s) {
if (isEmpty(s)) {
return true;
@@ -1003,26 +1078,31 @@ public class StringUtil extends StringUtilRt {
* @param c symbol to check
* @return <code>true</code> if given symbol is white space, tabulation or line feed; <code>false</code> otherwise
*/
+ @Contract(pure = true)
public static boolean isWhiteSpace(char c) {
return c == '\n' || c == '\t' || c == ' ';
}
@NotNull
+ @Contract(pure = true)
public static String getThrowableText(@NotNull Throwable aThrowable) {
return ExceptionUtil.getThrowableText(aThrowable);
}
@NotNull
+ @Contract(pure = true)
public static String getThrowableText(@NotNull Throwable aThrowable, @NonNls @NotNull final String stackFrameSkipPattern) {
return ExceptionUtil.getThrowableText(aThrowable, stackFrameSkipPattern);
}
@Nullable
+ @Contract(pure = true)
public static String getMessage(@NotNull Throwable e) {
return ExceptionUtil.getMessage(e);
}
@NotNull
+ @Contract(pure = true)
public static String repeatSymbol(final char aChar, final int count) {
char[] buffer = new char[count];
Arrays.fill(buffer, aChar);
@@ -1030,6 +1110,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String repeat(@NotNull String s, int count) {
assert count >= 0 : count;
StringBuilder sb = new StringBuilder(s.length() * count);
@@ -1040,6 +1121,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static List<String> splitHonorQuotes(@NotNull String s, char separator) {
final List<String> result = new ArrayList<String>();
final StringBuilder builder = new StringBuilder(s.length());
@@ -1068,17 +1150,20 @@ public class StringUtil extends StringUtilRt {
@NotNull
+ @Contract(pure = true)
public static List<String> split(@NotNull String s, @NotNull String separator) {
return split(s, separator, true);
}
@NotNull
+ @Contract(pure = true)
public static List<String> split(@NotNull String s, @NotNull String separator,
boolean excludeSeparator) {
return split(s, separator, excludeSeparator, true);
}
@NotNull
+ @Contract(pure = true)
public static List<String> split(@NotNull String s, @NotNull String separator,
boolean excludeSeparator, boolean excludeEmptyStrings) {
if (separator.isEmpty()) {
@@ -1103,6 +1188,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static Iterable<String> tokenize(@NotNull String s, @NotNull String separators) {
final com.intellij.util.text.StringTokenizer tokenizer = new com.intellij.util.text.StringTokenizer(s, separators);
return new Iterable<String>() {
@@ -1130,6 +1216,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static Iterable<String> tokenize(@NotNull final StringTokenizer tokenizer) {
return new Iterable<String>() {
@NotNull
@@ -1160,6 +1247,7 @@ public class StringUtil extends StringUtilRt {
* The <b>word</b> here means the maximum sub-string consisting entirely of characters which are <code>Character.isJavaIdentifierPart(c)</code>.
*/
@NotNull
+ @Contract(pure = true)
public static List<String> getWordsIn(@NotNull String text) {
List<String> result = null;
int start = -1;
@@ -1190,6 +1278,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static List<TextRange> getWordIndicesIn(@NotNull String text) {
List<TextRange> result = new SmartList<TextRange>();
int start = -1;
@@ -1211,11 +1300,13 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String join(@NotNull final String[] strings, @NotNull final String separator) {
return join(strings, 0, strings.length, separator);
}
@NotNull
+ @Contract(pure = true)
public static String join(@NotNull final String[] strings, int startIndex, int endIndex, @NotNull final String separator) {
final StringBuilder result = new StringBuilder();
for (int i = startIndex; i < endIndex; i++) {
@@ -1226,6 +1317,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String[] zip(@NotNull String[] strings1, @NotNull String[] strings2, String separator) {
if (strings1.length != strings2.length) throw new IllegalArgumentException();
@@ -1238,6 +1330,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String[] surround(@NotNull String[] strings1, String prefix, String suffix) {
String[] result = ArrayUtil.newStringArray(strings1.length);
for (int i = 0; i < result.length; i++) {
@@ -1248,11 +1341,13 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static <T> String join(@NotNull T[] items, @NotNull Function<T, String> f, @NotNull @NonNls String separator) {
return join(Arrays.asList(items), f, separator);
}
@NotNull
+ @Contract(pure = true)
public static <T> String join(@NotNull Collection<? extends T> items,
@NotNull Function<? super T, String> f,
@NotNull @NonNls String separator) {
@@ -1260,6 +1355,7 @@ public class StringUtil extends StringUtilRt {
return join((Iterable<? extends T>)items, f, separator);
}
+ @Contract(pure = true)
public static String join(@NotNull Iterable<?> items, @NotNull @NonNls String separator) {
StringBuilder result = new StringBuilder();
for (Object item : items) {
@@ -1272,6 +1368,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static <T> String join(@NotNull Iterable<? extends T> items,
@NotNull Function<? super T, String> f,
@NotNull @NonNls String separator) {
@@ -1287,6 +1384,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String join(@NotNull Collection<? extends String> strings, @NotNull String separator) {
StringBuilder result = new StringBuilder();
join(strings, separator, result);
@@ -1309,6 +1407,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String join(@NotNull final int[] strings, @NotNull final String separator) {
final StringBuilder result = new StringBuilder();
for (int i = 0; i < strings.length; i++) {
@@ -1319,6 +1418,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String join(@Nullable final String... strings) {
if (strings == null || strings.length == 0) return "";
@@ -1330,12 +1430,14 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String stripQuotesAroundValue(@NotNull String text) {
if (startsWithChar(text, '\"') || startsWithChar(text, '\'')) text = text.substring(1);
if (endsWithChar(text, '\"') || endsWithChar(text, '\'')) text = text.substring(0, text.length() - 1);
return text;
}
+ @Contract(pure = true)
public static boolean isQuotedString(@NotNull String text) {
if (text.length() < 2) return false;
return startsWithChar(text, '\"') && endsWithChar(text, '\"')
@@ -1350,6 +1452,7 @@ public class StringUtil extends StringUtilRt {
* @since 5.0.1
*/
@NotNull
+ @Contract(pure = true)
public static String formatFileSize(final long fileSize) {
if (fileSize < 0x400) {
return CommonBundle.message("format.file.size.bytes", fileSize);
@@ -1365,6 +1468,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String formatDuration(long duration) {
final long minutes = duration / 60000;
final long seconds = ((duration + 500L) % 60000) / 1000;
@@ -1375,6 +1479,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
private static String formatMinor(long number) {
if (number > 0L && number <= 9L) {
return "0" + number;
@@ -1391,6 +1496,7 @@ public class StringUtil extends StringUtilRt {
*/
@SuppressWarnings({"HardCodedStringLiteral"})
@Nullable
+ @Contract(pure = true)
public static String unpluralize(@NotNull final String name) {
if (name.endsWith("sses") || name.endsWith("shes") || name.endsWith("ches") || name.endsWith("xes")) { //?
return name.substring(0, name.length() - 2);
@@ -1430,6 +1536,7 @@ public class StringUtil extends StringUtilRt {
}
@Nullable
+ @Contract(pure = true)
private static String stripEnding(@NotNull String name, @NotNull String ending) {
if (name.endsWith(ending)) {
if (name.equals(ending)) return name; // do not return empty string
@@ -1438,6 +1545,7 @@ public class StringUtil extends StringUtilRt {
return null;
}
+ @Contract(pure = true)
public static boolean containsAlphaCharacters(@NotNull String value) {
for (int i = 0; i < value.length(); i++) {
if (Character.isLetter(value.charAt(i))) return true;
@@ -1445,6 +1553,7 @@ public class StringUtil extends StringUtilRt {
return false;
}
+ @Contract(pure = true)
public static boolean containsAnyChar(@NotNull final String value, @NotNull final String chars) {
if (chars.length() > value.length()) {
return containsAnyChar(value, chars, 0, value.length());
@@ -1454,6 +1563,7 @@ public class StringUtil extends StringUtilRt {
}
}
+ @Contract(pure = true)
public static boolean containsAnyChar(@NotNull final String value,
@NotNull final String chars,
final int start, final int end) {
@@ -1466,6 +1576,7 @@ public class StringUtil extends StringUtilRt {
return false;
}
+ @Contract(pure = true)
public static boolean containsChar(@NotNull final String value, final char ch) {
return value.indexOf(ch) >= 0;
}
@@ -1473,7 +1584,7 @@ public class StringUtil extends StringUtilRt {
/**
* @deprecated use #capitalize(String)
*/
- @Contract("null -> null; !null -> !null")
+ @Contract(value = "null -> null; !null -> !null", pure = true)
public static String firstLetterToUpperCase(@Nullable final String displayString) {
if (displayString == null || displayString.isEmpty()) return displayString;
char firstChar = displayString.charAt(0);
@@ -1494,6 +1605,7 @@ public class StringUtil extends StringUtilRt {
* @return stripped string e.g. "mystring"
*/
@NotNull
+ @Contract(pure = true)
public static String strip(@NotNull final String s, @NotNull final CharFilter filter) {
final StringBuilder result = new StringBuilder(s.length());
for (int i = 0; i < s.length(); i++) {
@@ -1506,11 +1618,13 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static List<String> findMatches(@NotNull String s, @NotNull Pattern pattern) {
return findMatches(s, pattern, 1);
}
@NotNull
+ @Contract(pure = true)
public static List<String> findMatches(@NotNull String s, @NotNull Pattern pattern, int groupIndex) {
List<String> result = new SmartList<String>();
Matcher m = pattern.matcher(s);
@@ -1530,6 +1644,7 @@ public class StringUtil extends StringUtilRt {
* @param filter search filter
* @return position of the first character accepted or -1 if not found
*/
+ @Contract(pure = true)
public static int findFirst(@NotNull final CharSequence s, @NotNull CharFilter filter) {
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
@@ -1541,18 +1656,22 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String replaceSubstring(@NotNull String string, @NotNull TextRange range, @NotNull String replacement) {
return range.replace(string, replacement);
}
+ @Contract(pure = true)
public static boolean startsWithWhitespace(@NotNull String text) {
return !text.isEmpty() && Character.isWhitespace(text.charAt(0));
}
+ @Contract(pure = true)
public static boolean isChar(CharSequence seq, int index, char c) {
return index >= 0 && index < seq.length() && seq.charAt(index) == c;
}
+ @Contract(pure = true)
public static boolean startsWith(@NotNull CharSequence text, @NotNull CharSequence prefix) {
int l1 = text.length();
int l2 = prefix.length();
@@ -1565,6 +1684,7 @@ public class StringUtil extends StringUtilRt {
return true;
}
+ @Contract(pure = true)
public static boolean startsWith(@NotNull CharSequence text, int startIndex, @NotNull CharSequence prefix) {
int l1 = text.length() - startIndex;
int l2 = prefix.length();
@@ -1577,6 +1697,7 @@ public class StringUtil extends StringUtilRt {
return true;
}
+ @Contract(pure = true)
public static boolean endsWith(@NotNull CharSequence text, @NotNull CharSequence suffix) {
int l1 = text.length();
int l2 = suffix.length();
@@ -1590,10 +1711,12 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String commonPrefix(@NotNull String s1, @NotNull String s2) {
return s1.substring(0, commonPrefixLength(s1, s2));
}
+ @Contract(pure = true)
public static int commonPrefixLength(@NotNull CharSequence s1, @NotNull CharSequence s2) {
int i;
int minLength = Math.min(s1.length(), s2.length());
@@ -1606,10 +1729,12 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String commonSuffix(@NotNull String s1, @NotNull String s2) {
return s1.substring(s1.length() - commonSuffixLength(s1, s2));
}
+ @Contract(pure = true)
public static int commonSuffixLength(@NotNull CharSequence s1, @NotNull CharSequence s2) {
int s1Length = s1.length();
int s2Length = s2.length();
@@ -1633,10 +1758,12 @@ public class StringUtil extends StringUtilRt {
* @return <code>true</code> if given symbol is contained at the target range of the given char sequence;
* <code>false</code> otherwise
*/
+ @Contract(pure = true)
public static boolean contains(@NotNull CharSequence s, int start, int end, char c) {
return indexOf(s, c, start, end) >= 0;
}
+ @Contract(pure = true)
public static boolean containsWhitespaces(@Nullable CharSequence s) {
if (s == null) return false;
@@ -1646,14 +1773,17 @@ public class StringUtil extends StringUtilRt {
return false;
}
+ @Contract(pure = true)
public static int indexOf(@NotNull CharSequence s, char c) {
return indexOf(s, c, 0, s.length());
}
+ @Contract(pure = true)
public static int indexOf(@NotNull CharSequence s, char c, int start) {
return indexOf(s, c, start, s.length());
}
+ @Contract(pure = true)
public static int indexOf(@NotNull CharSequence s, char c, int start, int end) {
for (int i = start; i < end; i++) {
if (s.charAt(i) == c) return i;
@@ -1661,10 +1791,12 @@ public class StringUtil extends StringUtilRt {
return -1;
}
+ @Contract(pure = true)
public static boolean contains(@NotNull CharSequence sequence, @NotNull CharSequence infix) {
return indexOf(sequence, infix) >= 0;
}
-
+
+ @Contract(pure = true)
public static int indexOf(@NotNull CharSequence sequence, @NotNull CharSequence infix) {
for (int i = 0; i < sequence.length() - infix.length(); i++) {
if (startsWith(sequence, i, infix)) {
@@ -1674,6 +1806,7 @@ public class StringUtil extends StringUtilRt {
return -1;
}
+ @Contract(pure = true)
public static int indexOf(@NotNull CharSequence s, char c, int start, int end, boolean caseSensitive) {
for (int i = start; i < end; i++) {
if (charsMatch(s.charAt(i), c, !caseSensitive)) return i;
@@ -1681,6 +1814,7 @@ public class StringUtil extends StringUtilRt {
return -1;
}
+ @Contract(pure = true)
public static int indexOf(@NotNull char[] s, char c, int start, int end, boolean caseSensitive) {
for (int i = start; i < end; i++) {
if (charsMatch(s[i], c, !caseSensitive)) return i;
@@ -1688,24 +1822,29 @@ public class StringUtil extends StringUtilRt {
return -1;
}
+ @Contract(pure = true)
public static int indexOfSubstringEnd(@NotNull String text, @NotNull String subString) {
int i = text.indexOf(subString);
if (i == -1) return -1;
return i + subString.length();
}
+ @Contract(pure = true)
public static int indexOfAny(@NotNull final String s, @NotNull final String chars) {
return indexOfAny(s, chars, 0, s.length());
}
+ @Contract(pure = true)
public static int indexOfAny(@NotNull final CharSequence s, @NotNull final String chars) {
return indexOfAny(s, chars, 0, s.length());
}
+ @Contract(pure = true)
public static int indexOfAny(@NotNull final String s, @NotNull final String chars, final int start, final int end) {
return indexOfAny((CharSequence)s, chars, start, end);
}
+ @Contract(pure = true)
public static int indexOfAny(@NotNull final CharSequence s, @NotNull final String chars, final int start, final int end) {
for (int i = start; i < end; i++) {
if (containsChar(chars, s.charAt(i))) return i;
@@ -1714,6 +1853,7 @@ public class StringUtil extends StringUtilRt {
}
@Nullable
+ @Contract(pure = true)
public static String substringBefore(@NotNull String text, @NotNull String subString) {
int i = text.indexOf(subString);
if (i == -1) return null;
@@ -1721,6 +1861,7 @@ public class StringUtil extends StringUtilRt {
}
@Nullable
+ @Contract(pure = true)
public static String substringAfter(@NotNull String text, @NotNull String subString) {
int i = text.indexOf(subString);
if (i == -1) return null;
@@ -1737,26 +1878,31 @@ public class StringUtil extends StringUtilRt {
* @return index of the last occurrence of the given symbol at the target sub-sequence of the given text if any;
* <code>-1</code> otherwise
*/
+ @Contract(pure = true)
public static int lastIndexOf(@NotNull CharSequence s, char c, int start, int end) {
return StringUtilRt.lastIndexOf(s, c, start, end);
}
@NotNull
+ @Contract(pure = true)
public static String first(@NotNull String text, final int maxLength, final boolean appendEllipsis) {
return text.length() > maxLength ? text.substring(0, maxLength) + (appendEllipsis ? "..." : "") : text;
}
@NotNull
+ @Contract(pure = true)
public static CharSequence first(@NotNull CharSequence text, final int length, final boolean appendEllipsis) {
return text.length() > length ? text.subSequence(0, length) + (appendEllipsis ? "..." : "") : text;
}
@NotNull
+ @Contract(pure = true)
public static CharSequence last(@NotNull CharSequence text, final int length, boolean prependEllipsis) {
return text.length() > length ? (prependEllipsis ? "..." : "") + text.subSequence(text.length() - length, text.length()) : text;
}
@NotNull
+ @Contract(pure = true)
public static String escapeChar(@NotNull final String str, final char character) {
final StringBuilder buf = new StringBuilder(str);
escapeChar(buf, character);
@@ -1772,6 +1918,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String escapeQuotes(@NotNull final String str) {
return escapeChar(str, '"');
}
@@ -1781,11 +1928,13 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String escapeSlashes(@NotNull final String str) {
return escapeChar(str, '/');
}
@NotNull
+ @Contract(pure = true)
public static String escapeBackSlashes(@NotNull final String str) {
return escapeChar(str, '\\');
}
@@ -1795,6 +1944,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String unescapeSlashes(@NotNull final String str) {
final StringBuilder buf = new StringBuilder(str.length());
unescapeSlashes(buf, str);
@@ -1826,6 +1976,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String wrapWithDoubleQuote(@NotNull String str) {
return '\"' + str + "\"";
}
@@ -1833,25 +1984,27 @@ public class StringUtil extends StringUtilRt {
@NonNls private static final String[] REPLACES_REFS = {"&lt;", "&gt;", "&amp;", "&#39;", "&quot;"};
@NonNls private static final String[] REPLACES_DISP = {"<", ">", "&", "'", "\""};
- @Contract("null -> null; !null -> !null")
+ @Contract(value = "null -> null; !null -> !null",pure = true)
public static String unescapeXml(@Nullable final String text) {
if (text == null) return null;
return replace(text, REPLACES_REFS, REPLACES_DISP);
}
- @Contract("null -> null; !null -> !null")
+ @Contract(value = "null -> null; !null -> !null",pure = true)
public static String escapeXml(@Nullable final String text) {
if (text == null) return null;
return replace(text, REPLACES_DISP, REPLACES_REFS);
}
@NotNull
- public static String htmlEmphasize(String text) {
+ @Contract(pure = true)
+ public static String htmlEmphasize(@NotNull String text) {
return "<b><code>" + escapeXml(text) + "</code></b>";
}
@NotNull
+ @Contract(pure = true)
public static String escapeToRegexp(@NotNull String text) {
final StringBuilder result = new StringBuilder(text.length());
return escapeToRegexp(text, result).toString();
@@ -1875,6 +2028,7 @@ public class StringUtil extends StringUtilRt {
return builder;
}
+ @Contract(pure = true)
public static boolean isNotEscapedBackslash(@NotNull char[] chars, int startOffset, int backslashOffset) {
if (chars[backslashOffset] != '\\') {
return false;
@@ -1891,6 +2045,7 @@ public class StringUtil extends StringUtilRt {
return !escaped;
}
+ @Contract(pure = true)
public static boolean isNotEscapedBackslash(@NotNull CharSequence text, int startOffset, int backslashOffset) {
if (text.charAt(backslashOffset) != '\\') {
return false;
@@ -1908,6 +2063,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String replace(@NotNull String text, @NotNull String[] from, @NotNull String[] to) {
final StringBuilder result = new StringBuilder(text.length());
replace:
@@ -1929,6 +2085,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String[] filterEmptyStrings(@NotNull String[] strings) {
int emptyCount = 0;
for (String string : strings) {
@@ -1946,14 +2103,17 @@ public class StringUtil extends StringUtilRt {
return result;
}
+ @Contract(pure = true)
public static int countNewLines(@NotNull CharSequence text) {
return countChars(text, '\n');
}
+ @Contract(pure = true)
public static int countChars(@NotNull CharSequence text, char c) {
return countChars(text, c, 0, false);
}
+ @Contract(pure = true)
public static int countChars(@NotNull CharSequence text, char c, int offset, boolean continuous) {
int count = 0;
for (int i = offset; i < text.length(); ++i) {
@@ -1968,6 +2128,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String capitalsOnly(@NotNull String s) {
StringBuilder b = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
@@ -1984,6 +2145,7 @@ public class StringUtil extends StringUtilRt {
* @return {@code null} if any of given Strings is {@code null}.
*/
@Nullable
+ @Contract(pure = true)
public static String joinOrNull(@NotNull String... args) {
StringBuilder r = new StringBuilder();
for (String arg : args) {
@@ -1994,6 +2156,7 @@ public class StringUtil extends StringUtilRt {
}
@Nullable
+ @Contract(pure = true)
public static String getPropertyName(@NonNls @NotNull String methodName) {
if (methodName.startsWith("get")) {
return Introspector.decapitalize(methodName.substring(3));
@@ -2009,14 +2172,17 @@ public class StringUtil extends StringUtilRt {
}
}
+ @Contract(pure = true)
public static boolean isJavaIdentifierStart(char c) {
return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || Character.isJavaIdentifierStart(c);
}
+ @Contract(pure = true)
public static boolean isJavaIdentifierPart(char c) {
return c >= '0' && c <= '9' || isJavaIdentifierStart(c);
}
+ @Contract(pure = true)
public static boolean isJavaIdentifier(@NotNull String text) {
int len = text.length();
if (len == 0) return false;
@@ -2038,6 +2204,7 @@ public class StringUtil extends StringUtilRt {
* @return an escaped string
*/
@NotNull
+ @Contract(pure = true)
public static String escapeProperty(@NotNull String input, final boolean isKey) {
final StringBuilder escaped = new StringBuilder(input.length());
for (int i = 0; i < input.length(); i++) {
@@ -2087,6 +2254,7 @@ public class StringUtil extends StringUtilRt {
return escaped.toString();
}
+ @Contract(pure = true)
public static String getQualifiedName(@Nullable String packageName, String className) {
if (packageName == null || packageName.isEmpty()) {
return className;
@@ -2094,6 +2262,7 @@ public class StringUtil extends StringUtilRt {
return packageName + '.' + className;
}
+ @Contract(pure = true)
public static int compareVersionNumbers(@Nullable String v1, @Nullable String v2) {
// todo duplicates com.intellij.util.text.VersionComparatorUtil.compare
// todo please refactor next time you make changes here
@@ -2147,6 +2316,7 @@ public class StringUtil extends StringUtilRt {
}
}
+ @Contract(pure = true)
public static int getOccurrenceCount(@NotNull String text, final char c) {
int res = 0;
int i = 0;
@@ -2163,6 +2333,7 @@ public class StringUtil extends StringUtilRt {
return res;
}
+ @Contract(pure = true)
public static int getOccurrenceCount(@NotNull String text, @NotNull String s) {
int res = 0;
int i = 0;
@@ -2180,6 +2351,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String fixVariableNameDerivedFromPropertyName(@NotNull String name) {
if (isEmptyOrSpaces(name)) return name;
char c = name.charAt(0);
@@ -2190,6 +2362,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String sanitizeJavaIdentifier(@NotNull String name) {
final StringBuilder result = new StringBuilder(name.length());
@@ -2236,6 +2409,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String tail(@NotNull String s, final int idx) {
return idx >= s.length() ? "" : s.substring(idx, s.length());
}
@@ -2247,6 +2421,7 @@ public class StringUtil extends StringUtilRt {
* @return array of strings
*/
@NotNull
+ @Contract(pure = true)
public static String[] splitByLines(@NotNull String string) {
return splitByLines(string, true);
}
@@ -2259,11 +2434,13 @@ public class StringUtil extends StringUtilRt {
* @return array of strings
*/
@NotNull
+ @Contract(pure = true)
public static String[] splitByLines(@NotNull String string, boolean excludeEmptyStrings) {
return (excludeEmptyStrings ? EOL_SPLIT_PATTERN : EOL_SPLIT_PATTERN_WITH_EMPTY).split(string);
}
@NotNull
+ @Contract(pure = true)
public static String[] splitByLinesDontTrim(@NotNull String string) {
return EOL_SPLIT_DONT_TRIM_PATTERN.split(string);
}
@@ -2280,14 +2457,16 @@ public class StringUtil extends StringUtilRt {
* \r<br>
* </blockquote>
* will return the following array: foo\r\n, \n, bar\n, \r\n, baz\r, \r
- *
+ *
*/
@NotNull
+ @Contract(pure = true)
public static String[] splitByLinesKeepSeparators(@NotNull String string) {
return EOL_SPLIT_KEEP_SEPARATORS.split(string);
}
@NotNull
+ @Contract(pure = true)
public static List<Pair<String, Integer>> getWordsWithOffset(@NotNull String s) {
List<Pair<String, Integer>> res = ContainerUtil.newArrayList();
s += " ";
@@ -2315,10 +2494,12 @@ public class StringUtil extends StringUtilRt {
* Implementation of "Sorting for Humans: Natural Sort Order":
* http://www.codinghorror.com/blog/2007/12/sorting-for-humans-natural-sort-order.html
*/
+ @Contract(pure = true)
public static int naturalCompare(@Nullable String string1, @Nullable String string2) {
return naturalCompare(string1, string2, false);
}
+ @Contract(pure = true)
private static int naturalCompare(@Nullable String string1, @Nullable String string2, boolean caseSensitive) {
//noinspection StringEquality
if (string1 == string2) {
@@ -2333,7 +2514,8 @@ public class StringUtil extends StringUtilRt {
final int string1Length = string1.length();
final int string2Length = string2.length();
- int i = 0, j = 0;
+ int i = 0;
+ int j = 0;
for (; i < string1Length && j < string2Length; i++, j++) {
char ch1 = string1.charAt(i);
char ch2 = string2.charAt(j);
@@ -2404,10 +2586,12 @@ public class StringUtil extends StringUtilRt {
return string1Length - string2Length;
}
+ @Contract(pure = true)
public static boolean isDecimalDigit(char c) {
return c >= '0' && c <= '9';
}
+ @Contract(pure = true)
public static int compare(@Nullable String s1, @Nullable String s2, boolean ignoreCase) {
//noinspection StringEquality
if (s1 == s2) return 0;
@@ -2416,15 +2600,18 @@ public class StringUtil extends StringUtilRt {
return ignoreCase ? s1.compareToIgnoreCase(s2) : s1.compareTo(s2);
}
+ @Contract(pure = true)
public static int comparePairs(@Nullable String s1, @Nullable String t1, @Nullable String s2, @Nullable String t2, boolean ignoreCase) {
final int compare = compare(s1, s2, ignoreCase);
return compare != 0 ? compare : compare(t1, t2, ignoreCase);
}
+ @Contract(pure = true)
public static int hashCode(@NotNull CharSequence s) {
return stringHashCode(s);
}
+ @Contract(pure = true)
public static boolean equals(@Nullable CharSequence s1, @Nullable CharSequence s2) {
if (s1 == null ^ s2 == null) {
return false;
@@ -2445,6 +2632,7 @@ public class StringUtil extends StringUtilRt {
return true;
}
+ @Contract(pure = true)
public static boolean equalsIgnoreCase(@Nullable CharSequence s1, @Nullable CharSequence s2) {
if (s1 == null ^ s2 == null) {
return false;
@@ -2465,6 +2653,7 @@ public class StringUtil extends StringUtilRt {
return true;
}
+ @Contract(pure = true)
public static int compare(char c1, char c2, boolean ignoreCase) {
// duplicating String.equalsIgnoreCase logic
int d = c1 - c2;
@@ -2488,11 +2677,13 @@ public class StringUtil extends StringUtilRt {
return d;
}
+ @Contract(pure = true)
public static boolean charsMatch(char c1, char c2, boolean ignoreCase) {
return compare(c1, c2, ignoreCase) == 0;
}
@NotNull
+ @Contract(pure = true)
public static String formatLinks(@NotNull String message) {
Pattern linkPattern = Pattern.compile("http://[a-zA-Z0-9\\./\\-\\+]+");
StringBuffer result = new StringBuffer();
@@ -2504,25 +2695,30 @@ public class StringUtil extends StringUtilRt {
return result.toString();
}
+ @Contract(pure = true)
public static boolean isHexDigit(char c) {
return '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F';
}
+ @Contract(pure = true)
public static boolean isOctalDigit(char c) {
return '0' <= c && c <= '7';
}
@NotNull
+ @Contract(pure = true)
public static String shortenTextWithEllipsis(@NotNull final String text, final int maxLength, final int suffixLength) {
return shortenTextWithEllipsis(text, maxLength, suffixLength, false);
}
@NotNull
+ @Contract(pure = true)
public static String trimMiddle(@NotNull String text, int maxLength) {
return shortenTextWithEllipsis(text, maxLength, maxLength >> 1, true);
}
@NotNull
+ @Contract(pure = true)
public static String shortenTextWithEllipsis(@NotNull final String text,
final int maxLength,
final int suffixLength,
@@ -2539,6 +2735,7 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String shortenTextWithEllipsis(@NotNull final String text,
final int maxLength,
final int suffixLength,
@@ -2548,47 +2745,57 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ @Contract(pure = true)
public static String shortenPathWithEllipsis(@NotNull final String path, final int maxLength, boolean useEllipsisSymbol) {
return shortenTextWithEllipsis(path, maxLength, (int)(maxLength * 0.7), useEllipsisSymbol);
}
@NotNull
+ @Contract(pure = true)
public static String shortenPathWithEllipsis(@NotNull final String path, final int maxLength) {
return shortenPathWithEllipsis(path, maxLength, false);
}
+ @Contract(pure = true)
public static boolean charsEqual(char a, char b, boolean ignoreCase) {
return ignoreCase ? charsEqualIgnoreCase(a, b) : a == b;
}
+ @Contract(pure = true)
public static boolean charsEqualIgnoreCase(char a, char b) {
return StringUtilRt.charsEqualIgnoreCase(a, b);
}
+ @Contract(pure = true)
public static char toUpperCase(char a) {
return StringUtilRt.toUpperCase(a);
}
@NotNull
+ @Contract(pure = true)
public static String toUpperCase(@NotNull String a) {
return StringUtilRt.toUpperCase(a);
}
+ @Contract(pure = true)
public static char toLowerCase(final char a) {
return StringUtilRt.toLowerCase(a);
}
@NotNull
+ @Contract(pure = true)
public static String convertLineSeparators(@NotNull String text) {
return StringUtilRt.convertLineSeparators(text);
}
@NotNull
+ @Contract(pure = true)
public static String convertLineSeparators(@NotNull String text, boolean keepCarriageReturn) {
return StringUtilRt.convertLineSeparators(text, keepCarriageReturn);
}
@NotNull
+ @Contract(pure = true)
public static String convertLineSeparators(@NotNull String text, @NotNull String newSeparator) {
return StringUtilRt.convertLineSeparators(text, newSeparator);
}
@@ -2606,34 +2813,41 @@ public class StringUtil extends StringUtilRt {
return StringUtilRt.convertLineSeparators(text, newSeparator, offsetsToKeep, keepCarriageReturn);
}
+ @Contract(pure = true)
public static int parseInt(final String string, final int defaultValue) {
return StringUtilRt.parseInt(string, defaultValue);
}
+ @Contract(pure = true)
public static double parseDouble(final String string, final double defaultValue) {
return StringUtilRt.parseDouble(string, defaultValue);
}
+ @Contract(pure = true)
public static boolean parseBoolean(String string, final boolean defaultValue) {
return StringUtilRt.parseBoolean(string, defaultValue);
}
@NotNull
+ @Contract(pure = true)
public static String getShortName(@NotNull Class aClass) {
return StringUtilRt.getShortName(aClass);
}
@NotNull
+ @Contract(pure = true)
public static String getShortName(@NotNull String fqName) {
return StringUtilRt.getShortName(fqName);
}
@NotNull
+ @Contract(pure = true)
public static String getShortName(@NotNull String fqName, char separator) {
return StringUtilRt.getShortName(fqName, separator);
}
@NotNull
+ @Contract(pure = true)
public static CharSequence newBombedCharSequence(@NotNull CharSequence sequence, long delay) {
final long myTime = System.currentTimeMillis() + delay;
return new BombedCharSequence(sequence) {
@@ -2655,23 +2869,17 @@ public class StringUtil extends StringUtilRt {
return false;
}
- private static boolean trimStart(@NotNull StringBuilder buffer, @NotNull CharSequence start) {
- if (startsWith(buffer, start)) {
- buffer.delete(0, start.length());
- return true;
- }
- return false;
- }
-
/**
* Say smallPart = "op" and bigPart="open". Method returns true for "Ope" and false for "ops"
*/
+ @Contract(pure = true)
public static boolean isBetween(@NotNull String string, @NotNull String smallPart, @NotNull String bigPart) {
final String s = string.toLowerCase();
return s.startsWith(smallPart.toLowerCase()) && bigPart.toLowerCase().startsWith(s);
}
- public static String getShortened(String s, int maxWidth) {
+ @Contract(pure = true)
+ public static String getShortened(@NotNull String s, int maxWidth) {
int length = s.length();
if (isEmpty(s) || length <= maxWidth) return s;
ArrayList<String> words = new ArrayList<String>();
diff --git a/platform/util/src/com/intellij/util/ArrayUtil.java b/platform/util/src/com/intellij/util/ArrayUtil.java
index d0419de9e820..0dcfdb307ae0 100644
--- a/platform/util/src/com/intellij/util/ArrayUtil.java
+++ b/platform/util/src/com/intellij/util/ArrayUtil.java
@@ -18,6 +18,7 @@ package com.intellij.util;
import com.intellij.openapi.util.Comparing;
import com.intellij.util.text.CharArrayCharSequence;
import gnu.trove.Equality;
+import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -64,6 +65,7 @@ public class ArrayUtil extends ArrayUtilRt {
private ArrayUtil() { }
@NotNull
+ @Contract(pure=true)
public static byte[] realloc(@NotNull byte[] array, final int newSize) {
if (newSize == 0) {
return EMPTY_BYTE_ARRAY;
@@ -79,6 +81,7 @@ public class ArrayUtil extends ArrayUtilRt {
return result;
}
@NotNull
+ @Contract(pure=true)
public static boolean[] realloc(@NotNull boolean[] array, final int newSize) {
if (newSize == 0) {
return EMPTY_BOOLEAN_ARRAY;
@@ -95,6 +98,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static int[] realloc(@NotNull int[] array, final int newSize) {
if (newSize == 0) {
return EMPTY_INT_ARRAY;
@@ -110,6 +114,7 @@ public class ArrayUtil extends ArrayUtilRt {
return result;
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] realloc(@NotNull T[] array, final int newSize, @NotNull ArrayFactory<T> factory) {
final int oldSize = array.length;
if (oldSize == newSize) {
@@ -126,12 +131,14 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static int[] append(@NotNull int[] array, int value) {
array = realloc(array, array.length + 1);
array[array.length - 1] = value;
return array;
}
@NotNull
+ @Contract(pure=true)
public static int[] insert(@NotNull int[] array, int index, int value) {
int[] result = new int[array.length + 1];
System.arraycopy(array, 0, result, 0, index);
@@ -141,12 +148,14 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static byte[] append(@NotNull byte[] array, byte value) {
array = realloc(array, array.length + 1);
array[array.length - 1] = value;
return array;
}
@NotNull
+ @Contract(pure=true)
public static boolean[] append(@NotNull boolean[] array, boolean value) {
array = realloc(array, array.length + 1);
array[array.length - 1] = value;
@@ -154,6 +163,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static char[] realloc(@NotNull char[] array, final int newSize) {
if (newSize == 0) {
return EMPTY_CHAR_ARRAY;
@@ -170,12 +180,14 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] toObjectArray(@NotNull Collection<T> collection, @NotNull Class<T> aClass) {
@SuppressWarnings("unchecked") T[] array = (T[])Array.newInstance(aClass, collection.size());
return collection.toArray(array);
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] toObjectArray(@NotNull Class<T> aClass, @NotNull Object... source) {
@SuppressWarnings("unchecked") T[] array = (T[])Array.newInstance(aClass, source.length);
System.arraycopy(source, 0, array, 0, array.length);
@@ -183,6 +195,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static Object[] toObjectArray(@NotNull Collection<?> collection) {
if (collection.isEmpty()) return EMPTY_OBJECT_ARRAY;
//noinspection SSBasedInspection
@@ -190,6 +203,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static int[] toIntArray(@NotNull Collection<Integer> list) {
int[] ret = newIntArray(list.size());
int i = 0;
@@ -200,6 +214,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] mergeArrays(@NotNull T[] a1, @NotNull T[] a2) {
if (a1.length == 0) {
return a2;
@@ -219,6 +234,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] mergeCollections(@NotNull Collection<? extends T> c1, @NotNull Collection<? extends T> c2, @NotNull ArrayFactory<T> factory) {
T[] res = factory.create(c1.size() + c2.size());
@@ -236,6 +252,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] mergeArrays(@NotNull T[] a1, @NotNull T[] a2, @NotNull ArrayFactory<T> factory) {
if (a1.length == 0) {
return a2;
@@ -250,11 +267,13 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static String[] mergeArrays(@NotNull String[] a1, @NotNull String... a2) {
return mergeArrays(a1, a2, STRING_ARRAY_FACTORY);
}
@NotNull
+ @Contract(pure=true)
public static int[] mergeArrays(@NotNull int[] a1, @NotNull int[] a2) {
if (a1.length == 0) {
return a2;
@@ -269,6 +288,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static byte[] mergeArrays(@NotNull byte[] a1, @NotNull byte[] a2) {
if (a1.length == 0) {
return a2;
@@ -292,6 +312,7 @@ public class ArrayUtil extends ArrayUtilRt {
* @return destination array
*/
@NotNull
+ @Contract(pure=true)
public static <T> T[] mergeArrayAndCollection(@NotNull T[] array,
@NotNull Collection<T> collection,
@NotNull final ArrayFactory<T> factory) {
@@ -326,16 +347,19 @@ public class ArrayUtil extends ArrayUtilRt {
* @return new array
*/
@NotNull
+ @Contract(pure=true)
public static <T> T[] append(@NotNull final T[] src, @Nullable final T element) {
return append(src, element, (Class<T>)src.getClass().getComponentType());
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] prepend(final T element, @NotNull final T[] array) {
return prepend(element, array, (Class<T>)array.getClass().getComponentType());
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] prepend(T element, @NotNull T[] array, @NotNull Class<T> type) {
int length = array.length;
T[] result = (T[])Array.newInstance(type, length + 1);
@@ -345,6 +369,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static byte[] prepend(byte element, @NotNull byte[] array) {
int length = array.length;
final byte[] result = new byte[length + 1];
@@ -353,8 +378,8 @@ public class ArrayUtil extends ArrayUtilRt {
return result;
}
+ @Contract(pure=true)
public static <T> T[] append(@NotNull final T[] src, final T element, @NotNull ArrayFactory<T> factory) {
-
int length = src.length;
T[] result = factory.create(length + 1);
System.arraycopy(src, 0, result, 0, length);
@@ -363,6 +388,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] append(@NotNull T[] src, @Nullable final T element, @NotNull Class<T> componentType) {
int length = src.length;
T[] result = (T[])Array.newInstance(componentType, length + 1);
@@ -379,6 +405,7 @@ public class ArrayUtil extends ArrayUtilRt {
* @return modified array.
*/
@NotNull
+ @Contract(pure=true)
public static <T> T[] remove(@NotNull final T[] src, int idx) {
int length = src.length;
if (idx < 0 || idx >= length) {
@@ -391,6 +418,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] remove(@NotNull final T[] src, int idx, @NotNull ArrayFactory<T> factory) {
int length = src.length;
if (idx < 0 || idx >= length) {
@@ -403,6 +431,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] remove(@NotNull final T[] src, T element) {
final int idx = find(src, element);
if (idx == -1) return src;
@@ -411,6 +440,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] remove(@NotNull final T[] src, T element, @NotNull ArrayFactory<T> factory) {
final int idx = find(src, element);
if (idx == -1) return src;
@@ -419,6 +449,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static int[] remove(@NotNull final int[] src, int idx) {
int length = src.length;
if (idx < 0 || idx >= length) {
@@ -430,6 +461,7 @@ public class ArrayUtil extends ArrayUtilRt {
return result;
}
@NotNull
+ @Contract(pure=true)
public static short[] remove(@NotNull final short[] src, int idx) {
int length = src.length;
if (idx < 0 || idx >= length) {
@@ -441,6 +473,7 @@ public class ArrayUtil extends ArrayUtilRt {
return result;
}
+ @Contract(pure=true)
public static <T> int lastIndexOf(@NotNull final T[] src, final T obj) {
for (int i = src.length - 1; i >= 0; i--) {
final T o = src[i];
@@ -458,14 +491,17 @@ public class ArrayUtil extends ArrayUtilRt {
return -1;
}
+ @Contract(pure=true)
public static int find(@NotNull int[] src, int obj) {
return indexOf(src, obj);
}
+ @Contract(pure=true)
public static <T> int find(@NotNull final T[] src, final T obj) {
return ArrayUtilRt.find(src, obj);
}
+ @Contract(pure=true)
public static boolean startsWith(@NotNull byte[] array, @NotNull byte[] prefix) {
if (array == prefix) {
return true;
@@ -484,6 +520,7 @@ public class ArrayUtil extends ArrayUtilRt {
return true;
}
+ @Contract(pure=true)
public static <E> boolean startsWith(@NotNull E[] array, @NotNull E[] subArray) {
if (array == subArray) {
return true;
@@ -502,6 +539,7 @@ public class ArrayUtil extends ArrayUtilRt {
return true;
}
+ @Contract(pure=true)
public static boolean startsWith(@NotNull byte[] array, int start, @NotNull byte[] subArray) {
int length = subArray.length;
if (array.length - start < length) {
@@ -517,6 +555,7 @@ public class ArrayUtil extends ArrayUtilRt {
return true;
}
+ @Contract(pure=true)
public static <T> boolean equals(@NotNull T[] a1, @NotNull T[] a2, @NotNull Equality<? super T> comparator) {
if (a1 == a2) {
return true;
@@ -535,6 +574,7 @@ public class ArrayUtil extends ArrayUtilRt {
return true;
}
+ @Contract(pure=true)
public static <T> boolean equals(@NotNull T[] a1, @NotNull T[] a2, @NotNull Comparator<? super T> comparator) {
if (a1 == a2) {
return true;
@@ -553,6 +593,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] reverseArray(@NotNull T[] array) {
T[] newArray = array.clone();
for (int i = 0; i < array.length; i++) {
@@ -562,6 +603,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static int[] reverseArray(@NotNull int[] array) {
int[] newArray = array.clone();
for (int i = 0; i < array.length; i++) {
@@ -576,6 +618,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
}
+ @Contract(pure=true)
public static int lexicographicCompare(@NotNull String[] obj1, @NotNull String[] obj2) {
for (int i = 0; i < Math.max(obj1.length, obj2.length); i++) {
String o1 = i < obj1.length ? obj1[i] : null;
@@ -589,6 +632,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
//must be Comparables
+ @Contract(pure=true)
public static <T> int lexicographicCompare(@NotNull T[] obj1, @NotNull T[] obj2) {
for (int i = 0; i < Math.max(obj1.length, obj2.length); i++) {
T o1 = i < obj1.length ? obj1[i] : null;
@@ -637,10 +681,12 @@ public class ArrayUtil extends ArrayUtilRt {
array[i1] = t;
}
+ @Contract(pure=true)
public static int indexOf(@NotNull Object[] objects, @Nullable Object object) {
return indexOf(objects, object, 0, objects.length);
}
+ @Contract(pure=true)
public static int indexOf(@NotNull Object[] objects, Object object, int start, int end) {
if (object == null) {
for (int i = start; i < end; i++) {
@@ -655,6 +701,7 @@ public class ArrayUtil extends ArrayUtilRt {
return -1;
}
+ @Contract(pure=true)
public static <T> int indexOf(@NotNull List<T> objects, T object, @NotNull Equality<T> comparator) {
for (int i = 0; i < objects.size(); i++) {
if (comparator.equals(objects.get(i), object)) return i;
@@ -662,6 +709,7 @@ public class ArrayUtil extends ArrayUtilRt {
return -1;
}
+ @Contract(pure=true)
public static <T> int indexOf(@NotNull List<T> objects, T object, @NotNull Comparator<T> comparator) {
for (int i = 0; i < objects.size(); i++) {
if (comparator.compare(objects.get(i), object) == 0) return i;
@@ -669,6 +717,7 @@ public class ArrayUtil extends ArrayUtilRt {
return -1;
}
+ @Contract(pure=true)
public static <T> int indexOf(@NotNull T[] objects, T object, @NotNull Equality<T> comparator) {
for (int i = 0; i < objects.length; i++) {
if (comparator.equals(objects[i], object)) return i;
@@ -676,6 +725,7 @@ public class ArrayUtil extends ArrayUtilRt {
return -1;
}
+ @Contract(pure=true)
public static int indexOf(@NotNull int[] ints, int value) {
for (int i = 0; i < ints.length; i++) {
if (ints[i] == value) return i;
@@ -683,6 +733,7 @@ public class ArrayUtil extends ArrayUtilRt {
return -1;
}
+ @Contract(pure=true)
public static int indexOf(@NotNull short[] ints, short value) {
for (int i = 0; i < ints.length; i++) {
if (ints[i] == value) return i;
@@ -691,10 +742,12 @@ public class ArrayUtil extends ArrayUtilRt {
return -1;
}
+ @Contract(pure=true)
public static boolean contains(@Nullable final Object o, @NotNull Object... objects) {
return indexOf(objects, o) >= 0;
}
+ @Contract(pure=true)
public static boolean contains(@Nullable final String s, @NotNull String... strings) {
if (s == null) {
for (String str : strings) {
@@ -711,26 +764,31 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static int[] newIntArray(int count) {
return count == 0 ? EMPTY_INT_ARRAY : new int[count];
}
@NotNull
+ @Contract(pure=true)
public static long[] newLongArray(int count) {
return count == 0 ? EMPTY_LONG_ARRAY : new long[count];
}
@NotNull
+ @Contract(pure=true)
public static String[] newStringArray(int count) {
return count == 0 ? EMPTY_STRING_ARRAY : new String[count];
}
@NotNull
+ @Contract(pure=true)
public static Object[] newObjectArray(int count) {
return count == 0 ? EMPTY_OBJECT_ARRAY : new Object[count];
}
@NotNull
+ @Contract(pure=true)
public static <E> E[] ensureExactSize(int count, @NotNull E[] sample) {
if (count == sample.length) return sample;
@SuppressWarnings({"unchecked"}) final E[] array = (E[])Array.newInstance(sample.getClass().getComponentType(), count);
@@ -738,16 +796,19 @@ public class ArrayUtil extends ArrayUtilRt {
}
@Nullable
+ @Contract(pure=true)
public static <T> T getFirstElement(@NotNull T[] array) {
return array.length > 0 ? array[0] : null;
}
@Nullable
+ @Contract(pure=true)
public static <T> T getLastElement(@NotNull T[] array) {
return array.length > 0 ? array[array.length - 1] : null;
}
@NotNull
+ @Contract(pure=true)
public static String[] toStringArray(@Nullable Collection<String> collection) {
return ArrayUtilRt.toStringArray(collection);
}
diff --git a/platform/util/src/com/intellij/util/ReflectionUtil.java b/platform/util/src/com/intellij/util/ReflectionUtil.java
index d5f6a58dc951..8e2204415988 100644
--- a/platform/util/src/com/intellij/util/ReflectionUtil.java
+++ b/platform/util/src/com/intellij/util/ReflectionUtil.java
@@ -19,17 +19,15 @@ package com.intellij.util;
import com.intellij.Patches;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Condition;
-import com.intellij.util.containers.ContainerUtil;
+import com.intellij.openapi.util.DifferenceFilter;
+import com.intellij.util.containers.*;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import sun.reflect.ConstructorAccessor;
import java.lang.reflect.*;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
+import java.util.*;
public class ReflectionUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.util.ReflectionUtil");
@@ -479,6 +477,50 @@ public class ReflectionUtil {
return callerClass;
}
+ public static void copyFields(@NotNull Field[] fields, @NotNull Object from, @NotNull Object to) {
+ copyFields(fields, from, to, null);
+ }
+
+ public static boolean copyFields(@NotNull Field[] fields, @NotNull Object from, @NotNull Object to, @Nullable DifferenceFilter diffFilter) {
+ Set<Field> sourceFields = new com.intellij.util.containers.HashSet<Field>(Arrays.asList(from.getClass().getFields()));
+ boolean valuesChanged = false;
+ for (Field field : fields) {
+ if (sourceFields.contains(field)) {
+ if (isPublic(field) && !isFinal(field)) {
+ try {
+ if (diffFilter == null || diffFilter.isAccept(field)) {
+ copyFieldValue(from, to, field);
+ valuesChanged = true;
+ }
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+ return valuesChanged;
+ }
+
+ public static void copyFieldValue(@NotNull Object from, @NotNull Object to, @NotNull Field field)
+ throws IllegalAccessException {
+ Class<?> fieldType = field.getType();
+ if (fieldType.isPrimitive() || fieldType.equals(String.class)) {
+ field.set(to, field.get(from));
+ }
+ else {
+ throw new RuntimeException("Field '" + field.getName()+"' not copied: unsupported type: "+field.getType());
+ }
+ }
+
+ private static boolean isPublic(final Field field) {
+ return (field.getModifiers() & Modifier.PUBLIC) != 0;
+ }
+
+ private static boolean isFinal(final Field field) {
+ return (field.getModifiers() & Modifier.FINAL) != 0;
+ }
+
private static class MySecurityManager extends SecurityManager {
private static final MySecurityManager INSTANCE = new MySecurityManager();
diff --git a/platform/util/src/com/intellij/util/Restarter.java b/platform/util/src/com/intellij/util/Restarter.java
index 01e7fc494f5b..1eb1691808be 100644
--- a/platform/util/src/com/intellij/util/Restarter.java
+++ b/platform/util/src/com/intellij/util/Restarter.java
@@ -153,11 +153,16 @@ public class Restarter {
}
public static File createTempExecutable(File executable) throws IOException {
- File copy = new File(System.getProperty("user.home") + "/." + System.getProperty("idea.paths.selector") + "/restart/" + executable.getName());
- if (FileUtilRt.ensureCanCreateFile(copy)) {
- FileUtilRt.copy(executable, copy);
- if (!copy.setExecutable(executable.canExecute())) throw new IOException("Cannot make file executable: " + copy);
+ File executableDir = new File(System.getProperty("user.home") + "/." + System.getProperty("idea.paths.selector") + "/restart");
+ File copy = new File(executableDir.getPath() + "/" + executable.getName());
+ if (!FileUtilRt.ensureCanCreateFile(copy)) {
+ String ext = FileUtilRt.getExtension(executable.getName());
+ copy = FileUtilRt.createTempFile(executableDir, FileUtilRt.getNameWithoutExtension(copy.getName()),
+ StringUtil.isEmptyOrSpaces(ext) ? ".tmp" : ("." + ext),
+ true, false);
}
+ FileUtilRt.copy(executable, copy);
+ if (!copy.setExecutable(executable.canExecute())) throw new IOException("Cannot make file executable: " + copy);
return copy;
}
diff --git a/platform/util/src/com/intellij/util/containers/ContainerUtil.java b/platform/util/src/com/intellij/util/containers/ContainerUtil.java
index 40bd75a2eff8..0047217285a5 100644
--- a/platform/util/src/com/intellij/util/containers/ContainerUtil.java
+++ b/platform/util/src/com/intellij/util/containers/ContainerUtil.java
@@ -33,135 +33,166 @@ import java.util.LinkedHashSet;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
-@SuppressWarnings({"UtilityClassWithoutPrivateConstructor", "MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
+@SuppressWarnings({"UtilityClassWithoutPrivateConstructor", "MethodOverridesStaticMethodOfSuperclass"})
public class ContainerUtil extends ContainerUtilRt {
private static final int INSERTION_SORT_THRESHOLD = 10;
private static final int DEFAULT_CONCURRENCY_LEVEL = Math.min(16, Runtime.getRuntime().availableProcessors());
@NotNull
+ @Contract(pure=true)
public static <T> T[] ar(@NotNull T... elements) {
return elements;
}
@NotNull
+ @Contract(pure=true)
public static <K, V> HashMap<K, V> newHashMap() {
return ContainerUtilRt.newHashMap();
}
@NotNull
+ @Contract(pure=true)
public static <K, V> HashMap<K, V> newHashMap(@NotNull Map<K, V> map) {
return ContainerUtilRt.newHashMap(map);
}
@NotNull
+ @Contract(pure=true)
public static <K, V> Map<K, V> newHashMap(@NotNull Pair<K, V> first, Pair<K, V>... entries) {
return ContainerUtilRt.newHashMap(first, entries);
}
@NotNull
+ @Contract(pure=true)
public static <K, V> Map<K, V> newHashMap(@NotNull List<K> keys, @NotNull List<V> values) {
return ContainerUtilRt.newHashMap(keys, values);
}
@NotNull
+ @Contract(pure=true)
public static <K extends Comparable, V> TreeMap<K, V> newTreeMap() {
return ContainerUtilRt.newTreeMap();
}
@NotNull
+ @Contract(pure=true)
public static <K extends Comparable, V> TreeMap<K, V> newTreeMap(@NotNull Map<K, V> map) {
return ContainerUtilRt.newTreeMap(map);
}
@NotNull
+ @Contract(pure=true)
public static <K, V> LinkedHashMap<K, V> newLinkedHashMap() {
return ContainerUtilRt.newLinkedHashMap();
}
@NotNull
+ @Contract(pure=true)
+ public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(int capacity) {
+ return ContainerUtilRt.newLinkedHashMap(capacity);
+ }
+
+ @NotNull
+ @Contract(pure=true)
public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(@NotNull Map<K, V> map) {
return ContainerUtilRt.newLinkedHashMap(map);
}
@NotNull
+ @Contract(pure=true)
public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(@NotNull Pair<K, V> first, Pair<K, V>... entries) {
return ContainerUtilRt.newLinkedHashMap(first, entries);
}
@NotNull
+ @Contract(pure=true)
public static <K, V> THashMap<K, V> newTroveMap() {
return new THashMap<K, V>();
}
@NotNull
+ @Contract(pure=true)
public static <K, V> THashMap<K, V> newTroveMap(@NotNull TObjectHashingStrategy<K> strategy) {
return new THashMap<K, V>(strategy);
}
@NotNull
+ @Contract(pure=true)
public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap(@NotNull Class<K> keyType) {
return new EnumMap<K, V>(keyType);
}
@SuppressWarnings("unchecked")
@NotNull
+ @Contract(pure=true)
public static <T> TObjectHashingStrategy<T> canonicalStrategy() {
return TObjectHashingStrategy.CANONICAL;
}
@SuppressWarnings("unchecked")
@NotNull
+ @Contract(pure=true)
public static <T> TObjectHashingStrategy<T> identityStrategy() {
return TObjectHashingStrategy.IDENTITY;
}
@NotNull
+ @Contract(pure=true)
public static <K, V> IdentityHashMap<K, V> newIdentityHashMap() {
return new IdentityHashMap<K, V>();
}
@NotNull
+ @Contract(pure=true)
public static <T> LinkedList<T> newLinkedList() {
return ContainerUtilRt.newLinkedList();
}
@NotNull
+ @Contract(pure=true)
public static <T> LinkedList<T> newLinkedList(@NotNull T... elements) {
return ContainerUtilRt.newLinkedList(elements);
}
@NotNull
+ @Contract(pure=true)
public static <T> LinkedList<T> newLinkedList(@NotNull Iterable<? extends T> elements) {
return ContainerUtilRt.newLinkedList(elements);
}
@NotNull
+ @Contract(pure=true)
public static <T> ArrayList<T> newArrayList() {
return ContainerUtilRt.newArrayList();
}
@NotNull
+ @Contract(pure=true)
public static <E> ArrayList<E> newArrayList(@NotNull E... array) {
return ContainerUtilRt.newArrayList(array);
}
@NotNull
+ @Contract(pure=true)
public static <E> ArrayList<E> newArrayList(@NotNull Iterable<? extends E> iterable) {
return ContainerUtilRt.newArrayList(iterable);
}
/** @deprecated Use {@link #newArrayListWithCapacity(int)} (to remove in IDEA 15) */
@SuppressWarnings("deprecation")
+ @Contract(pure=true)
public static <T> ArrayList<T> newArrayListWithExpectedSize(int size) {
return ContainerUtilRt.newArrayListWithCapacity(size);
}
@NotNull
+ @Contract(pure=true)
public static <T> ArrayList<T> newArrayListWithCapacity(int size) {
return ContainerUtilRt.newArrayListWithCapacity(size);
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> newArrayList(@NotNull final T[] elements, final int start, final int end) {
if (start < 0 || start > end || end > elements.length) {
throw new IllegalArgumentException("start:" + start + " end:" + end + " length:" + elements.length);
@@ -184,31 +215,37 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> newSmartList(T element) {
return new SmartList<T>(element);
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> newSmartList(@NotNull T... elements) {
return new SmartList<T>(elements);
}
@NotNull
+ @Contract(pure=true)
public static <T> HashSet<T> newHashSet() {
return ContainerUtilRt.newHashSet();
}
@NotNull
+ @Contract(pure=true)
public static <T> HashSet<T> newHashSet(int initialCapacity) {
return ContainerUtilRt.newHashSet(initialCapacity);
}
@NotNull
+ @Contract(pure=true)
public static <T> HashSet<T> newHashSet(@NotNull T... elements) {
return ContainerUtilRt.newHashSet(elements);
}
@NotNull
+ @Contract(pure=true)
public static <T> HashSet<T> newHashSet(@NotNull Iterable<? extends T> iterable) {
return ContainerUtilRt.newHashSet(iterable);
}
@@ -219,117 +256,141 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> Set<T> newHashOrEmptySet(@Nullable Iterable<? extends T> iterable) {
boolean empty = iterable == null || iterable instanceof Collection && ((Collection)iterable).isEmpty();
return empty ? Collections.<T>emptySet() : ContainerUtilRt.newHashSet(iterable);
}
@NotNull
+ @Contract(pure=true)
public static <T> LinkedHashSet<T> newLinkedHashSet() {
return ContainerUtilRt.newLinkedHashSet();
}
@NotNull
+ @Contract(pure=true)
public static <T> LinkedHashSet<T> newLinkedHashSet(@NotNull Iterable<? extends T> elements) {
return ContainerUtilRt.newLinkedHashSet(elements);
}
@NotNull
+ @Contract(pure=true)
public static <T> LinkedHashSet<T> newLinkedHashSet(@NotNull T... elements) {
return ContainerUtilRt.newLinkedHashSet(elements);
}
@NotNull
+ @Contract(pure=true)
public static <T> THashSet<T> newTroveSet() {
return new THashSet<T>();
}
@NotNull
+ @Contract(pure=true)
public static <T> THashSet<T> newTroveSet(@NotNull TObjectHashingStrategy<T> strategy) {
return new THashSet<T>(strategy);
}
@NotNull
+ @Contract(pure=true)
public static <T> THashSet<T> newTroveSet(@NotNull T... elements) {
return newTroveSet(Arrays.asList(elements));
}
@NotNull
+ @Contract(pure=true)
public static <T> THashSet<T> newTroveSet(@NotNull TObjectHashingStrategy<T> strategy, @NotNull T... elements) {
return new THashSet<T>(Arrays.asList(elements), strategy);
}
@NotNull
+ @Contract(pure=true)
public static <T> THashSet<T> newTroveSet(@NotNull TObjectHashingStrategy<T> strategy, @NotNull Collection<T> elements) {
return new THashSet<T>(elements, strategy);
}
@NotNull
+ @Contract(pure=true)
public static <T> THashSet<T> newTroveSet(@NotNull Collection<T> elements) {
return new THashSet<T>(elements);
}
@NotNull
+ @Contract(pure=true)
public static <K> THashSet<K> newIdentityTroveSet() {
return new THashSet<K>(ContainerUtil.<K>identityStrategy());
}
@NotNull
+ @Contract(pure=true)
public static <K> THashSet<K> newIdentityTroveSet(int initialCapacity) {
return new THashSet<K>(initialCapacity, ContainerUtil.<K>identityStrategy());
}
@NotNull
+ @Contract(pure=true)
public static <K> THashSet<K> newIdentityTroveSet(@NotNull Collection<K> collection) {
return new THashSet<K>(collection, ContainerUtil.<K>identityStrategy());
}
@NotNull
+ @Contract(pure=true)
public static <K,V> THashMap<K,V> newIdentityTroveMap() {
return new THashMap<K,V>(ContainerUtil.<K>identityStrategy());
}
@NotNull
+ @Contract(pure=true)
public static <T> TreeSet<T> newTreeSet() {
return ContainerUtilRt.newTreeSet();
}
@NotNull
+ @Contract(pure=true)
public static <T> TreeSet<T> newTreeSet(@NotNull Iterable<? extends T> elements) {
return ContainerUtilRt.newTreeSet(elements);
}
@NotNull
+ @Contract(pure=true)
public static <T> TreeSet<T> newTreeSet(@NotNull T... elements) {
return ContainerUtilRt.newTreeSet(elements);
}
@NotNull
+ @Contract(pure=true)
public static <T> TreeSet<T> newTreeSet(@Nullable Comparator<? super T> comparator) {
return ContainerUtilRt.newTreeSet(comparator);
}
@NotNull
+ @Contract(pure=true)
public static <K, V> ConcurrentMap<K, V> newConcurrentMap() {
return CHM_FACTORY.createMap();
}
+ @Contract(pure=true)
public static <K, V> ConcurrentMap<K,V> newConcurrentMap(@NotNull TObjectHashingStrategy<K> hashStrategy) {
return CHM_FACTORY.createMap(hashStrategy);
}
+ @Contract(pure=true)
public static <K, V> ConcurrentMap<K,V> newConcurrentMap(int initialCapacity) {
return CHM_FACTORY.createMap(initialCapacity);
}
+ @Contract(pure=true)
public static <K, V> ConcurrentMap<K,V> newConcurrentMap(int initialCapacity, float loadFactor, int concurrencyLevel, @NotNull TObjectHashingStrategy<K> hashStrategy) {
return CHM_FACTORY.createMap(initialCapacity, loadFactor, concurrencyLevel, hashStrategy);
}
+ @Contract(pure=true)
public static <K, V> ConcurrentMap<K,V> newConcurrentMap(int initialCapacity, float loadFactor, int concurrencyLevel) {
return CHM_FACTORY.createMap(initialCapacity, loadFactor, concurrencyLevel);
}
@NotNull
+ @Contract(pure=true)
public static <E> List<E> reverse(@NotNull final List<E> elements) {
if (elements.isEmpty()) {
return ContainerUtilRt.emptyList();
@@ -349,37 +410,43 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <K, V> Map<K, V> union(@NotNull Map<? extends K, ? extends V> map, @NotNull Map<? extends K, ? extends V> map2) {
- THashMap<K, V> result = new THashMap<K, V>(map.size() + map2.size());
+ Map<K, V> result = new THashMap<K, V>(map.size() + map2.size());
result.putAll(map);
result.putAll(map2);
return result;
}
@NotNull
+ @Contract(pure=true)
public static <T> Set<T> union(@NotNull Set<T> set, @NotNull Set<T> set2) {
- THashSet<T> result = new THashSet<T>(set.size() + set2.size());
+ Set<T> result = new THashSet<T>(set.size() + set2.size());
result.addAll(set);
result.addAll(set2);
return result;
}
@NotNull
+ @Contract(pure=true)
public static <E> Set<E> immutableSet(@NotNull E ... elements) {
return Collections.unmodifiableSet(new THashSet<E>(Arrays.asList(elements)));
}
@NotNull
+ @Contract(pure=true)
public static <E> ImmutableList<E> immutableList(@NotNull E ... array) {
return new ImmutableListBackedByArray<E>(array);
}
@NotNull
+ @Contract(pure=true)
public static <E> ImmutableList<E> immutableList(@NotNull List<E> list) {
return new ImmutableListBackedByList<E>(list);
}
@NotNull
+ @Contract(pure=true)
public static <K, V> ImmutableMapBuilder<K, V> immutableMapBuilder() {
return new ImmutableMapBuilder<K, V>();
}
@@ -392,6 +459,7 @@ public class ContainerUtil extends ContainerUtilRt {
return this;
}
+ @Contract(pure=true)
public Map<K, V> build() {
return Collections.unmodifiableMap(myMap);
}
@@ -434,6 +502,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <K, V> Map<K, V> intersection(@NotNull Map<K, V> map1, @NotNull Map<K, V> map2) {
final Map<K, V> res = newHashMap();
final Set<K> keys = newHashSet();
@@ -450,6 +519,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <K, V> Map<K,Couple<V>> diff(@NotNull Map<K, V> map1, @NotNull Map<K, V> map2) {
final Map<K, Couple<V>> res = newHashMap();
final Set<K> keys = newHashSet();
@@ -505,6 +575,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> mergeSortedLists(@NotNull List<T> list1,
@NotNull List<T> list2,
@NotNull Comparator<? super T> comparator,
@@ -521,6 +592,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> mergeSortedArrays(@NotNull T[] list1, @NotNull T[] list2, @NotNull Comparator<? super T> comparator, boolean mergeEqualItems, @Nullable Processor<? super T> filter) {
int index1 = 0;
int index2 = 0;
@@ -572,6 +644,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> subList(@NotNull List<T> list, int from) {
return list.subList(from, list.size());
}
@@ -658,16 +731,19 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> Iterator<T> emptyIterator() {
return EmptyIterator.getInstance();
}
@NotNull
+ @Contract(pure=true)
public static <T> Iterable<T> emptyIterable() {
return EmptyIterable.getInstance();
}
@Nullable
+ @Contract(pure=true)
public static <T> T find(@NotNull T[] array, @NotNull Condition<T> condition) {
for (T element : array) {
if (condition.value(element)) return element;
@@ -714,11 +790,13 @@ public class ContainerUtil extends ContainerUtilRt {
}
@Nullable
+ @Contract(pure=true)
public static <T, V extends T> V find(@NotNull Iterable<V> iterable, @NotNull Condition<T> condition) {
return find(iterable.iterator(), condition);
}
@Nullable
+ @Contract(pure=true)
public static <T> T find(@NotNull Iterable<? extends T> iterable, final T equalTo) {
return find(iterable, new Condition<T>() {
@Override
@@ -738,11 +816,13 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T, KEY, VALUE> Map<KEY, VALUE> map2Map(@NotNull T[] collection, @NotNull Function<T, Pair<KEY, VALUE>> mapper) {
return map2Map(Arrays.asList(collection), mapper);
}
@NotNull
+ @Contract(pure=true)
public static <T, KEY, VALUE> Map<KEY, VALUE> map2Map(@NotNull Collection<? extends T> collection,
@NotNull Function<T, Pair<KEY, VALUE>> mapper) {
final Map<KEY, VALUE> set = new THashMap<KEY, VALUE>(collection.size());
@@ -754,6 +834,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <KEY, VALUE> Map<KEY, VALUE> map2Map(@NotNull Collection<Pair<KEY, VALUE>> collection) {
final Map<KEY, VALUE> result = new THashMap<KEY, VALUE>(collection.size());
for (Pair<KEY, VALUE> pair : collection) {
@@ -763,21 +844,25 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> Object[] map2Array(@NotNull T[] array, @NotNull Function<T, Object> mapper) {
return map2Array(array, Object.class, mapper);
}
@NotNull
+ @Contract(pure=true)
public static <T> Object[] map2Array(@NotNull Collection<T> array, @NotNull Function<T, Object> mapper) {
return map2Array(array, Object.class, mapper);
}
@NotNull
+ @Contract(pure=true)
public static <T, V> V[] map2Array(@NotNull T[] array, @NotNull Class<? extends V> aClass, @NotNull Function<T, V> mapper) {
return map2Array(Arrays.asList(array), aClass, mapper);
}
@NotNull
+ @Contract(pure=true)
public static <T, V> V[] map2Array(@NotNull Collection<? extends T> collection, @NotNull Class<? extends V> aClass, @NotNull Function<T, V> mapper) {
final List<V> list = map2List(collection, mapper);
@SuppressWarnings("unchecked") V[] array = (V[])Array.newInstance(aClass, list.size());
@@ -785,16 +870,19 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T, V> V[] map2Array(@NotNull Collection<? extends T> collection, @NotNull V[] to, @NotNull Function<T, V> mapper) {
return map2List(collection, mapper).toArray(to);
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> filter(@NotNull T[] collection, @NotNull Condition<? super T> condition) {
return findAll(collection, condition);
}
@NotNull
+ @Contract(pure=true)
public static int[] filter(@NotNull int[] collection, @NotNull TIntProcedure condition) {
TIntArrayList result = new TIntArrayList();
for (int t : collection) {
@@ -806,11 +894,13 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> filter(@NotNull Condition<? super T> condition, @NotNull T... collection) {
return findAll(collection, condition);
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> findAll(@NotNull T[] collection, @NotNull Condition<? super T> condition) {
final List<T> result = new SmartList<T>();
for (T t : collection) {
@@ -822,11 +912,13 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> filter(@NotNull Collection<? extends T> collection, @NotNull Condition<? super T> condition) {
return findAll(collection, condition);
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> findAll(@NotNull Collection<? extends T> collection, @NotNull Condition<? super T> condition) {
if (collection.isEmpty()) return emptyList();
final List<T> result = new SmartList<T>();
@@ -839,16 +931,19 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> skipNulls(@NotNull Collection<? extends T> collection) {
return findAll(collection, Condition.NOT_NULL);
}
@NotNull
+ @Contract(pure=true)
public static <T, V> List<V> findAll(@NotNull T[] collection, @NotNull Class<V> instanceOf) {
return findAll(Arrays.asList(collection), instanceOf);
}
@NotNull
+ @Contract(pure=true)
public static <T, V> V[] findAllAsArray(@NotNull T[] collection, @NotNull Class<V> instanceOf) {
List<V> list = findAll(Arrays.asList(collection), instanceOf);
@SuppressWarnings("unchecked") V[] array = (V[])Array.newInstance(instanceOf, list.size());
@@ -856,6 +951,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T, V> V[] findAllAsArray(@NotNull Collection<? extends T> collection, @NotNull Class<V> instanceOf) {
List<V> list = findAll(collection, instanceOf);
@SuppressWarnings("unchecked") V[] array = (V[])Array.newInstance(instanceOf, list.size());
@@ -863,6 +959,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] findAllAsArray(@NotNull T[] collection, @NotNull Condition<? super T> instanceOf) {
List<T> list = findAll(collection, instanceOf);
@SuppressWarnings("unchecked") T[] array = (T[])Array.newInstance(collection.getClass().getComponentType(), list.size());
@@ -870,6 +967,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T, V> List<V> findAll(@NotNull Collection<? extends T> collection, @NotNull Class<V> instanceOf) {
final List<V> result = new SmartList<V>();
for (final T t : collection) {
@@ -895,6 +993,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static Map<String, String> stringMap(@NotNull final String... keyValues) {
final Map<String, String> result = newHashMap();
for (int i = 0; i < keyValues.length - 1; i+=2) {
@@ -905,11 +1004,13 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> Iterator<T> iterate(@NotNull T[] arrays) {
return Arrays.asList(arrays).iterator();
}
@NotNull
+ @Contract(pure=true)
public static <T> Iterator<T> iterate(@NotNull final Enumeration<T> enumeration) {
return new Iterator<T>() {
@Override
@@ -930,11 +1031,13 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> Iterable<T> iterate(@NotNull T[] arrays, @NotNull Condition<? super T> condition) {
return iterate(Arrays.asList(arrays), condition);
}
@NotNull
+ @Contract(pure=true)
public static <T> Iterable<T> iterate(@NotNull final Collection<? extends T> collection, @NotNull final Condition<? super T> condition) {
if (collection.isEmpty()) return emptyIterable();
return new Iterable<T>() {
@@ -977,6 +1080,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> Iterable<T> iterateBackward(@NotNull final List<? extends T> list) {
return new Iterable<T>() {
@Override
@@ -1068,6 +1172,7 @@ public class ContainerUtil extends ContainerUtilRt {
return modified;
}
+ @Contract(pure=true)
public static <T, U extends T> U findInstance(@NotNull Iterable<T> iterable, @NotNull Class<U> aClass) {
return findInstance(iterable.iterator(), aClass);
}
@@ -1079,11 +1184,13 @@ public class ContainerUtil extends ContainerUtilRt {
}
@Nullable
+ @Contract(pure=true)
public static <T, U extends T> U findInstance(@NotNull T[] array, @NotNull Class<U> aClass) {
return findInstance(Arrays.asList(array), aClass);
}
@NotNull
+ @Contract(pure=true)
public static <T, V> List<T> concat(@NotNull V[] array, @NotNull Function<V, Collection<? extends T>> fun) {
return concat(Arrays.asList(array), fun);
}
@@ -1092,6 +1199,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only list consisting of the elements from the collections stored in list added together
*/
@NotNull
+ @Contract(pure=true)
public static <T> List<T> concat(@NotNull Iterable<? extends Collection<T>> list) {
List<T> result = new ArrayList<T>();
for (final Collection<T> ts : list) {
@@ -1105,6 +1213,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only list consisting of the elements from specified list with some additional values
*/
@NotNull
+ @Contract(pure=true)
public static <T> List<T> concat(boolean appendTail, @NotNull List<? extends T> list, T... values) {
return appendTail ? concat(list, list(values)) : concat(list(values), list);
}
@@ -1113,6 +1222,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only list consisting of the two lists added together
*/
@NotNull
+ @Contract(pure=true)
public static <T> List<T> concat(@NotNull final List<? extends T> list1, @NotNull final List<? extends T> list2) {
if (list1.isEmpty() && list2.isEmpty()) {
return Collections.emptyList();
@@ -1139,6 +1249,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> Iterable<T> concat(@NotNull final Iterable<? extends T>... iterables) {
return new Iterable<T>() {
@Override
@@ -1155,16 +1266,19 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> Iterator<T> concatIterators(@NotNull Iterator<T>... iterators) {
return new SequenceIterator<T>(iterators);
}
@NotNull
+ @Contract(pure=true)
public static <T> Iterator<T> concatIterators(@NotNull Collection<Iterator<T>> iterators) {
return new SequenceIterator<T>(iterators);
}
@NotNull
+ @Contract(pure=true)
public static <T> Iterable<T> concat(@NotNull final T[]... iterables) {
return new Iterable<T>() {
@Override
@@ -1184,6 +1298,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only list consisting of the lists added together
*/
@NotNull
+ @Contract(pure=true)
public static <T> List<T> concat(@NotNull final List<? extends T>... lists) {
int size = 0;
for (List<? extends T> each : lists) {
@@ -1215,6 +1330,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only list consisting of the lists added together
*/
@NotNull
+ @Contract(pure=true)
public static <T> List<T> concat(@NotNull final List<List<? extends T>> lists) {
@SuppressWarnings("unchecked") List<? extends T>[] array = lists.toArray(new List[lists.size()]);
return concat(array);
@@ -1224,6 +1340,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only list consisting of the lists (made by listGenerator) added together
*/
@NotNull
+ @Contract(pure=true)
public static <T, V> List<T> concat(@NotNull Iterable<? extends V> list, @NotNull Function<V, Collection<? extends T>> listGenerator) {
List<T> result = new ArrayList<T>();
for (final V v : list) {
@@ -1232,6 +1349,7 @@ public class ContainerUtil extends ContainerUtilRt {
return result.isEmpty() ? ContainerUtil.<T>emptyList() : result;
}
+ @Contract(pure=true)
public static <T> boolean intersects(@NotNull Collection<? extends T> collection1, @NotNull Collection<? extends T> collection2) {
for (T t : collection1) {
//noinspection SuspiciousMethodCalls
@@ -1246,6 +1364,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only collection consisting of elements from both collections
*/
@NotNull
+ @Contract(pure=true)
public static <T> Collection<T> intersection(@NotNull Collection<? extends T> collection1, @NotNull Collection<? extends T> collection2) {
List<T> result = new ArrayList<T>();
for (T t : collection1) {
@@ -1257,15 +1376,18 @@ public class ContainerUtil extends ContainerUtilRt {
}
@Nullable
+ @Contract(pure=true)
public static <T> T getFirstItem(@Nullable Collection<T> items) {
return getFirstItem(items, null);
}
@Nullable
+ @Contract(pure=true)
public static <T> T getFirstItem(@Nullable List<T> items) {
return items == null || items.isEmpty() ? null : items.get(0);
}
+ @Contract(pure=true)
public static <T> T getFirstItem(@Nullable final Collection<T> items, @Nullable final T def) {
return items == null || items.isEmpty() ? def : items.iterator().next();
}
@@ -1280,11 +1402,13 @@ public class ContainerUtil extends ContainerUtilRt {
* @return new list with no more than <code>maxItems</code> first elements
*/
@NotNull
+ @Contract(pure=true)
public static <T> List<T> getFirstItems(@NotNull final List<T> items, int maxItems) {
return items.subList(0, Math.min(maxItems, items.size()));
}
@Nullable
+ @Contract(pure=true)
public static <T> T iterateAndGetLastItem(@NotNull Iterable<T> items) {
Iterator<T> itr = items.iterator();
T res = null;
@@ -1296,11 +1420,13 @@ public class ContainerUtil extends ContainerUtilRt {
}
@Nullable
+ @Contract(pure=true)
public static <T, L extends List<T>> T getLastItem(@NotNull L list, @Nullable T def) {
return list.isEmpty() ? def : list.get(list.size() - 1);
}
@Nullable
+ @Contract(pure=true)
public static <T, L extends List<T>> T getLastItem(@NotNull L list) {
return getLastItem(list, null);
}
@@ -1309,6 +1435,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only collection consisting of elements from the 'from' collection which are absent from the 'what' collection
*/
@NotNull
+ @Contract(pure=true)
public static <T> Collection<T> subtract(@NotNull Collection<T> from, @NotNull Collection<T> what) {
final Set<T> set = newHashSet(from);
set.removeAll(what);
@@ -1316,16 +1443,19 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] toArray(@Nullable Collection<T> c, @NotNull ArrayFactory<T> factory) {
return c != null ? c.toArray(factory.create(c.size())) : factory.create(0);
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] toArray(@NotNull Collection<? extends T> c1, @NotNull Collection<? extends T> c2, @NotNull ArrayFactory<T> factory) {
return ArrayUtil.mergeCollections(c1, c2, factory);
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] mergeCollectionsToArray(@NotNull Collection<? extends T> c1, @NotNull Collection<? extends T> c2, @NotNull ArrayFactory<T> factory) {
return ArrayUtil.mergeCollections(c1, c2, factory);
}
@@ -1424,6 +1554,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> sorted(@NotNull Collection<T> list, @NotNull Comparator<T> comparator) {
List<T> sorted = newArrayList(list);
sort(sorted, comparator);
@@ -1431,6 +1562,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T extends Comparable<T>> List<T> sorted(@NotNull Collection<T> list) {
return sorted(list, new Comparator<T>() {
@Override
@@ -1475,6 +1607,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only list consisting of the elements from the iterable converted by mapping
*/
@NotNull
+ @Contract(pure=true)
public static <T,V> List<V> map(@NotNull Iterable<? extends T> iterable, @NotNull Function<T, V> mapping) {
List<V> result = new ArrayList<V>();
for (T t : iterable) {
@@ -1487,6 +1620,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only list consisting of the elements from the iterable converted by mapping
*/
@NotNull
+ @Contract(pure=true)
public static <T,V> List<V> map(@NotNull Collection<? extends T> iterable, @NotNull Function<T, V> mapping) {
if (iterable.isEmpty()) return emptyList();
List<V> result = new ArrayList<V>(iterable.size());
@@ -1500,6 +1634,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only list consisting of the elements from the array converted by mapping with nulls filtered out
*/
@NotNull
+ @Contract(pure=true)
public static <T, V> List<V> mapNotNull(@NotNull T[] array, @NotNull Function<T, V> mapping) {
return mapNotNull(Arrays.asList(array), mapping);
}
@@ -1508,6 +1643,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only list consisting of the elements from the array converted by mapping with nulls filtered out
*/
@NotNull
+ @Contract(pure=true)
public static <T, V> V[] mapNotNull(@NotNull T[] array, @NotNull Function<T, V> mapping, @NotNull V[] emptyArray) {
List<V> result = new ArrayList<V>(array.length);
for (T t : array) {
@@ -1527,6 +1663,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only list consisting of the elements from the iterable converted by mapping with nulls filtered out
*/
@NotNull
+ @Contract(pure=true)
public static <T, V> List<V> mapNotNull(@NotNull Iterable<? extends T> iterable, @NotNull Function<T, V> mapping) {
List<V> result = new ArrayList<V>();
for (T t : iterable) {
@@ -1542,6 +1679,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only list consisting of the elements from the array converted by mapping with nulls filtered out
*/
@NotNull
+ @Contract(pure=true)
public static <T, V> List<V> mapNotNull(@NotNull Collection<? extends T> iterable, @NotNull Function<T, V> mapping) {
if (iterable.isEmpty()) {
return emptyList();
@@ -1561,6 +1699,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only list consisting of the elements with nulls filtered out
*/
@NotNull
+ @Contract(pure=true)
public static <T> List<T> packNullables(@NotNull T... elements) {
List<T> list = new ArrayList<T>();
for (T element : elements) {
@@ -1573,6 +1712,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only list consisting of the elements from the array converted by mapping
*/
@NotNull
+ @Contract(pure=true)
public static <T, V> List<V> map(@NotNull T[] array, @NotNull Function<T, V> mapping) {
List<V> result = new ArrayList<V>(array.length);
for (T t : array) {
@@ -1582,6 +1722,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T, V> V[] map(@NotNull T[] arr, @NotNull Function<T, V> mapping, @NotNull V[] emptyArray) {
if (arr.length==0) {
assert emptyArray.length == 0 : "You must pass an empty array";
@@ -1596,6 +1737,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> Set<T> set(@NotNull T ... items) {
return newHashSet(items);
}
@@ -1618,11 +1760,13 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> createMaybeSingletonList(@Nullable T element) {
return element == null ? ContainerUtil.<T>emptyList() : Collections.singletonList(element);
}
@NotNull
+ @Contract(pure=true)
public static <T> Set<T> createMaybeSingletonSet(@Nullable T element) {
return element == null ? Collections.<T>emptySet() : Collections.singleton(element);
}
@@ -1645,15 +1789,18 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T, V> V getOrElse(@NotNull Map<T, V> result, final T key, @NotNull V defValue) {
V value = result.get(key);
return value == null ? defValue : value;
}
+ @Contract(pure=true)
public static <T> boolean and(@NotNull T[] iterable, @NotNull Condition<T> condition) {
return and(Arrays.asList(iterable), condition);
}
+ @Contract(pure=true)
public static <T> boolean and(@NotNull Iterable<T> iterable, @NotNull Condition<T> condition) {
for (final T t : iterable) {
if (!condition.value(t)) return false;
@@ -1661,18 +1808,22 @@ public class ContainerUtil extends ContainerUtilRt {
return true;
}
+ @Contract(pure=true)
public static <T> boolean exists(@NotNull T[] iterable, @NotNull Condition<T> condition) {
return or(Arrays.asList(iterable), condition);
}
+ @Contract(pure=true)
public static <T> boolean exists(@NotNull Iterable<T> iterable, @NotNull Condition<T> condition) {
return or(iterable, condition);
}
+ @Contract(pure=true)
public static <T> boolean or(@NotNull T[] iterable, @NotNull Condition<T> condition) {
return or(Arrays.asList(iterable), condition);
}
+ @Contract(pure=true)
public static <T> boolean or(@NotNull Iterable<T> iterable, @NotNull Condition<T> condition) {
for (final T t : iterable) {
if (condition.value(t)) return true;
@@ -1681,10 +1832,11 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> unfold(@Nullable T t, @NotNull NullableFunction<T, T> next) {
if (t == null) return emptyList();
- final ArrayList<T> list = new ArrayList<T>();
+ List<T> list = new ArrayList<T>();
while (t != null) {
list.add(t);
t = next.fun(t);
@@ -1693,11 +1845,13 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> dropTail(@NotNull List<T> items) {
return items.subList(0, items.size() - 1);
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> list(@NotNull T... items) {
return Arrays.asList(items);
}
@@ -1845,6 +1999,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only set consisting of the only element o
*/
@NotNull
+ @Contract(pure=true)
public static <T> Set<T> singleton(final T o, @NotNull final TObjectHashingStrategy<T> strategy) {
return new SingletonSet<T>(o, strategy);
}
@@ -1853,6 +2008,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only list consisting of the elements from all of the collections
*/
@NotNull
+ @Contract(pure=true)
public static <E> List<E> flatten(@NotNull Collection<E>[] collections) {
return flatten(Arrays.asList(collections));
}
@@ -1861,6 +2017,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only list consisting of the elements from all of the collections
*/
@NotNull
+ @Contract(pure=true)
public static <E> List<E> flatten(@NotNull Iterable<? extends Collection<E>> collections) {
List<E> result = new ArrayList<E>();
for (Collection<E> list : collections) {
@@ -1874,6 +2031,7 @@ public class ContainerUtil extends ContainerUtilRt {
* @return read-only list consisting of the elements from all of the collections
*/
@NotNull
+ @Contract(pure=true)
public static <E> List<E> flattenIterables(@NotNull Iterable<? extends Iterable<E>> collections) {
List<E> result = new ArrayList<E>();
for (Iterable<E> list : collections) {
@@ -1885,6 +2043,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <K,V> V[] convert(@NotNull K[] from, @NotNull V[] to, @NotNull Function<K,V> fun) {
if (to.length < from.length) {
@SuppressWarnings("unchecked") V[] array = (V[])Array.newInstance(to.getClass().getComponentType(), from.length);
@@ -1896,6 +2055,7 @@ public class ContainerUtil extends ContainerUtilRt {
return to;
}
+ @Contract(pure=true)
public static <T> boolean containsIdentity(@NotNull Iterable<T> list, T element) {
for (T t : list) {
if (t == element) {
@@ -1905,6 +2065,7 @@ public class ContainerUtil extends ContainerUtilRt {
return false;
}
+ @Contract(pure=true)
public static <T> int indexOfIdentity(@NotNull List<T> list, T element) {
for (int i = 0, listSize = list.size(); i < listSize; i++) {
if (list.get(i) == element) {
@@ -1914,6 +2075,7 @@ public class ContainerUtil extends ContainerUtilRt {
return -1;
}
+ @Contract(pure=true)
public static <T> boolean equalsIdentity(@NotNull List<T> list1, @NotNull List<T> list2) {
int listSize = list1.size();
if (list2.size() != listSize) {
@@ -1928,6 +2090,7 @@ public class ContainerUtil extends ContainerUtilRt {
return true;
}
+ @Contract(pure=true)
public static <T> int indexOf(@NotNull List<T> list, @NotNull Condition<T> condition) {
for (int i = 0, listSize = list.size(); i < listSize; i++) {
T t = list.get(i);
@@ -1938,6 +2101,7 @@ public class ContainerUtil extends ContainerUtilRt {
return -1;
}
+ @Contract(pure=true)
public static <T> int indexOf(@NotNull List<T> list, @NotNull final T object) {
return indexOf(list, new Condition<T>() {
@Override
@@ -1948,6 +2112,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <A,B> Map<B,A> reverseMap(@NotNull Map<A,B> map) {
final Map<B,A> result = newHashMap();
for (Map.Entry<A, B> entry : map.entrySet()) {
@@ -1956,6 +2121,7 @@ public class ContainerUtil extends ContainerUtilRt {
return result;
}
+ @Contract(pure=true)
public static <T> boolean processRecursively(final T root, @NotNull PairProcessor<T, List<T>> processor) {
final LinkedList<T> list = new LinkedList<T>();
list.add(root);
@@ -1979,26 +2145,31 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> Stack<T> newStack() {
return ContainerUtilRt.newStack();
}
@NotNull
+ @Contract(pure=true)
public static <T> Stack<T> newStack(@NotNull Collection<T> initial) {
return ContainerUtilRt.newStack(initial);
}
@NotNull
+ @Contract(pure=true)
public static <T> Stack<T> newStack(@NotNull T... initial) {
return ContainerUtilRt.newStack(initial);
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> emptyList() {
return ContainerUtilRt.emptyList();
}
@NotNull
+ @Contract(pure=true)
public static <T> CopyOnWriteArrayList<T> createEmptyCOWList() {
return ContainerUtilRt.createEmptyCOWList();
}
@@ -2011,16 +2182,19 @@ public class ContainerUtil extends ContainerUtilRt {
* - slower modification in highly contented case (which is the kind of situation you shouldn't use COWAL anyway)
*/
@NotNull
+ @Contract(pure=true)
public static <T> List<T> createLockFreeCopyOnWriteList() {
return createConcurrentList();
}
@NotNull
+ @Contract(pure=true)
public static <T> List<T> createLockFreeCopyOnWriteList(@NotNull Collection<? extends T> c) {
return new LockFreeCopyOnWriteArrayList<T>(c);
}
@NotNull
+ @Contract(pure=true)
public static <T> ConcurrentList<T> createConcurrentList() {
return new LockFreeCopyOnWriteArrayList<T>();
}
@@ -2034,31 +2208,37 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T, V> List<V> map2List(@NotNull T[] array, @NotNull Function<T, V> mapper) {
return ContainerUtilRt.map2List(array, mapper);
}
@NotNull
+ @Contract(pure=true)
public static <T, V> List<V> map2List(@NotNull Collection<? extends T> collection, @NotNull Function<T, V> mapper) {
return ContainerUtilRt.map2List(collection, mapper);
}
@NotNull
+ @Contract(pure=true)
public static <T, V> Set<V> map2Set(@NotNull T[] collection, @NotNull Function<T, V> mapper) {
return ContainerUtilRt.map2Set(collection, mapper);
}
@NotNull
+ @Contract(pure=true)
public static <T, V> Set<V> map2Set(@NotNull Collection<? extends T> collection, @NotNull Function<T, V> mapper) {
return ContainerUtilRt.map2Set(collection, mapper);
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] toArray(@NotNull List<T> collection, @NotNull T[] array) {
return ContainerUtilRt.toArray(collection, array);
}
@NotNull
+ @Contract(pure=true)
public static <T> T[] toArray(@NotNull Collection<T> c, @NotNull T[] sample) {
return ContainerUtilRt.toArray(c, sample);
}
@@ -2075,6 +2255,7 @@ public class ContainerUtil extends ContainerUtilRt {
}
@NotNull
+ @Contract(pure=true)
public static <T> Collection<T> toCollection(@NotNull Iterable<T> iterable) {
return iterable instanceof Collection ? (Collection<T>)iterable : newArrayList(iterable);
}
@@ -2092,18 +2273,26 @@ public class ContainerUtil extends ContainerUtilRt {
return result;
}
- @Contract("null -> true")
+ @Contract(value = "null -> true", pure = true)
public static <T> boolean isEmpty(Collection<T> collection) {
return collection == null || collection.isEmpty();
}
@NotNull
- public static <T, C extends Collection<T>> C notNullize(@Nullable C collection) {
+ @Contract(pure=true)
+ public static <T> List<T> notNullize(@Nullable List<T> list) {
+ return list == null ? ContainerUtilRt.<T>emptyList() : list;
+ }
+
+ @NotNull
+ @Contract(pure=true)
+ public static <T> Set<T> notNullize(@Nullable Set<T> set) {
//noinspection unchecked
- return collection == null ? (C)ContainerUtilRt.emptyList() : collection;
+ return set == null ? Collections.<T>emptySet() : set;
}
@Nullable
+ @Contract(pure=true)
public static <T, C extends Collection<T>> C nullize(@Nullable C collection) {
return isEmpty(collection) ? null : collection;
}
@@ -2117,26 +2306,31 @@ public class ContainerUtil extends ContainerUtilRt {
}
private static final ConcurrentMapFactory V8_MAP_FACTORY = new ConcurrentMapFactory() {
+ @Override
@NotNull
public <T, V> ConcurrentMap<T, V> createMap() {
return new ConcurrentHashMap<T,V>();
}
+ @Override
@NotNull
public <T, V> ConcurrentMap<T, V> createMap(int initialCapacity) {
return new ConcurrentHashMap<T,V>(initialCapacity);
}
+ @Override
@NotNull
public <T, V> ConcurrentMap<T, V> createMap(@NotNull TObjectHashingStrategy<T> hashStrategy) {
return new ConcurrentHashMap<T,V>(hashStrategy);
}
+ @Override
@NotNull
public <T, V> ConcurrentMap<T, V> createMap(int initialCapacity, float loadFactor, int concurrencyLevel) {
return new ConcurrentHashMap<T,V>(initialCapacity, loadFactor, concurrencyLevel);
}
+ @Override
@NotNull
public <T, V> ConcurrentMap<T, V> createMap(int initialCapacity, float loadFactor, int concurrencyLevel, @NotNull TObjectHashingStrategy<T> hashingStrategy) {
return new ConcurrentHashMap<T,V>(initialCapacity, loadFactor, concurrencyLevel, hashingStrategy);
@@ -2144,16 +2338,19 @@ public class ContainerUtil extends ContainerUtilRt {
};
private static final ConcurrentMapFactory PLATFORM_MAP_FACTORY = new ConcurrentMapFactory() {
+ @Override
@NotNull
public <T, V> ConcurrentMap<T, V> createMap() {
return createMap(16, 0.75f, DEFAULT_CONCURRENCY_LEVEL);
}
+ @Override
@NotNull
public <T, V> ConcurrentMap<T, V> createMap(int initialCapacity) {
return new java.util.concurrent.ConcurrentHashMap<T,V>(initialCapacity);
}
+ @Override
@NotNull
public <T, V> ConcurrentMap<T, V> createMap(@NotNull TObjectHashingStrategy<T> hashingStrategy) {
if (hashingStrategy != canonicalStrategy()) {
@@ -2163,11 +2360,13 @@ public class ContainerUtil extends ContainerUtilRt {
return createMap();
}
+ @Override
@NotNull
public <T, V> ConcurrentMap<T, V> createMap(int initialCapacity, float loadFactor, int concurrencyLevel) {
return new java.util.concurrent.ConcurrentHashMap<T,V>(initialCapacity, loadFactor, concurrencyLevel);
}
+ @Override
@NotNull
public <T, V> ConcurrentMap<T, V> createMap(int initialCapacity, float loadFactor, int concurrencyLevel, @NotNull TObjectHashingStrategy<T> hashingStrategy) {
if (hashingStrategy != canonicalStrategy()) {
@@ -2185,7 +2384,8 @@ public class ContainerUtil extends ContainerUtilRt {
return StringUtil.compareVersionNumbers(SystemInfo.JAVA_VERSION, "1.7") >= 0;
}
- public static <T extends Comparable<T>> int compareLexicographically(List<T> o1, List<T> o2) {
+ @Contract(pure=true)
+ public static <T extends Comparable<T>> int compareLexicographically(@NotNull List<T> o1, @NotNull List<T> o2) {
for (int i = 0; i < Math.min(o1.size(), o2.size()); i++) {
int result = o1.get(i).compareTo(o2.get(i));
if (result != 0) {
@@ -2194,5 +2394,16 @@ public class ContainerUtil extends ContainerUtilRt {
}
return o1.size() < o2.size() ? -1 : o1.size() == o2.size() ? 0 : 1;
}
+
+ @Contract(pure=true)
+ public static <T> int compareLexicographically(@NotNull List<T> o1, @NotNull List<T> o2, @NotNull Comparator<T> comparator) {
+ for (int i = 0; i < Math.min(o1.size(), o2.size()); i++) {
+ int result = comparator.compare(o1.get(i), o2.get(i));
+ if (result != 0) {
+ return result;
+ }
+ }
+ return o1.size() < o2.size() ? -1 : o1.size() == o2.size() ? 0 : 1;
+ }
}
diff --git a/platform/util/src/com/intellij/util/containers/FactoryMap.java b/platform/util/src/com/intellij/util/containers/FactoryMap.java
index 30684d0e6dfa..3eea4d3dd984 100644
--- a/platform/util/src/com/intellij/util/containers/FactoryMap.java
+++ b/platform/util/src/com/intellij/util/containers/FactoryMap.java
@@ -15,6 +15,7 @@
*/
package com.intellij.util.containers;
+import com.intellij.util.ObjectUtils;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -92,7 +93,7 @@ public abstract class FactoryMap<K,V> implements Map<K, V> {
public Collection<V> notNullValues() {
if (myMap == null) return Collections.emptyList();
- final Collection<V> values = new ArrayList<V>(myMap.values());
+ final Collection<V> values = ContainerUtil.newArrayList(myMap.values());
for (Iterator<V> iterator = values.iterator(); iterator.hasNext();) {
if (iterator.next() == NULL) {
iterator.remove();
@@ -101,6 +102,13 @@ public abstract class FactoryMap<K,V> implements Map<K, V> {
return values;
}
+ public boolean removeValue(Object value) {
+ if (myMap == null) return false;
+ Object t = ObjectUtils.notNull(value, NULL);
+ return myMap.values().remove(t);
+ }
+
+
@Override
public void clear() {
if (myMap != null) {
diff --git a/platform/util/src/com/intellij/util/containers/TransferToEDTQueue.java b/platform/util/src/com/intellij/util/containers/TransferToEDTQueue.java
index 5db4de22b401..425947ba50cb 100644
--- a/platform/util/src/com/intellij/util/containers/TransferToEDTQueue.java
+++ b/platform/util/src/com/intellij/util/containers/TransferToEDTQueue.java
@@ -16,6 +16,7 @@
package com.intellij.util.containers;
import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Conditions;
import com.intellij.util.Processor;
import com.intellij.util.concurrency.Semaphore;
import gnu.trove.Equality;
@@ -80,7 +81,7 @@ public class TransferToEDTQueue<T> {
runnable.run();
return true;
}
- }, Condition.FALSE, maxUnitOfWorkThresholdMs);
+ }, Conditions.alwaysFalse(), maxUnitOfWorkThresholdMs);
}
private boolean isEmpty() {
diff --git a/platform/util/src/com/intellij/util/io/AppendableStorageBackedByResizableMappedFile.java b/platform/util/src/com/intellij/util/io/AppendableStorageBackedByResizableMappedFile.java
index c4381da1a406..1c43b652b02b 100644
--- a/platform/util/src/com/intellij/util/io/AppendableStorageBackedByResizableMappedFile.java
+++ b/platform/util/src/com/intellij/util/io/AppendableStorageBackedByResizableMappedFile.java
@@ -72,8 +72,7 @@ public class AppendableStorageBackedByResizableMappedFile extends ResizeableMapp
}
public <Data> boolean processAll(Processor<Data> processor, KeyDescriptor<Data> descriptor) throws IOException {
- force();
-
+ assert !isDirty();
DataInputStream keysStream = new DataInputStream(new BufferedInputStream(new LimitedInputStream(new FileInputStream(getPagedFileStorage().getFile()),
myFileLength) {
@Override
diff --git a/platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java b/platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java
index 9f879f67d99d..eb7cdef28d69 100644
--- a/platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java
+++ b/platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java
@@ -443,11 +443,13 @@ public abstract class PersistentEnumeratorBase<Data> implements Forceable, Close
lockStorage(); // todo locking in key storage
try {
- return myKeyStorage.processAll(processor, myDataDescriptor);
+ myKeyStorage.force();
}
finally {
unlockStorage();
}
+
+ return myKeyStorage.processAll(processor, myDataDescriptor);
}
private File keystreamFile() {
diff --git a/platform/util/src/com/intellij/util/messages/impl/MessageListenerList.java b/platform/util/src/com/intellij/util/messages/impl/MessageListenerList.java
index d054416846a1..6d7bf76ccde7 100644
--- a/platform/util/src/com/intellij/util/messages/impl/MessageListenerList.java
+++ b/platform/util/src/com/intellij/util/messages/impl/MessageListenerList.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,14 +15,14 @@
*/
package com.intellij.util.messages.impl;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.util.containers.ConcurrentHashMap;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.messages.Topic;
-import com.intellij.openapi.Disposable;
-import com.intellij.openapi.util.Disposer;
import org.jetbrains.annotations.NotNull;
-import java.util.HashMap;
import java.util.Map;
/**
@@ -31,7 +31,7 @@ import java.util.Map;
public class MessageListenerList<T> {
private final MessageBus myMessageBus;
private final Topic<T> myTopic;
- private final Map<T, MessageBusConnection> myListenerToConnectionMap = new HashMap<T, MessageBusConnection>();
+ private final Map<T, MessageBusConnection> myListenerToConnectionMap = new ConcurrentHashMap<T, MessageBusConnection>();
public MessageListenerList(@NotNull MessageBus messageBus, @NotNull Topic<T> topic) {
myTopic = topic;
diff --git a/platform/util/src/com/intellij/util/ui/JBSwingUtilities.java b/platform/util/src/com/intellij/util/ui/JBSwingUtilities.java
new file mode 100644
index 000000000000..d48aa5fc4ad2
--- /dev/null
+++ b/platform/util/src/com/intellij/util/ui/JBSwingUtilities.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2014 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.util.ui;
+
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+
+/**
+ * @author gregsh
+ */
+public class JBSwingUtilities {
+ /**
+ * Replaces SwingUtilities#isLeftMouseButton() for consistency with other button-related methods
+ *
+ * @see javax.swing.SwingUtilities#isLeftMouseButton(java.awt.event.MouseEvent)
+ */
+ public static boolean isLeftMouseButton(MouseEvent anEvent) {
+ return (anEvent.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) > 0;
+ }
+
+ /**
+ * Replaces SwingUtilities#isMiddleMouseButton() due to the fact that BUTTON2_MASK == Event.ALT_MASK
+ *
+ * @see javax.swing.SwingUtilities#isMiddleMouseButton(java.awt.event.MouseEvent)
+ * @see java.awt.event.InputEvent#BUTTON2_MASK
+ */
+ public static boolean isMiddleMouseButton(MouseEvent anEvent) {
+ return (anEvent.getModifiersEx() & InputEvent.BUTTON2_DOWN_MASK) > 0;
+ }
+
+ /**
+ * Replaces SwingUtilities#isRightMouseButton() due to the fact that BUTTON3_MASK == Event.META_MASK
+ *
+ * @see javax.swing.SwingUtilities#isRightMouseButton(java.awt.event.MouseEvent)
+ * @see java.awt.event.InputEvent#BUTTON3_MASK
+ */
+ public static boolean isRightMouseButton(MouseEvent anEvent) {
+ return (anEvent.getModifiersEx() & InputEvent.BUTTON3_DOWN_MASK) > 0;
+ }
+}
diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java
index aec2a356ded0..28c95b80763c 100644
--- a/platform/util/src/com/intellij/util/ui/UIUtil.java
+++ b/platform/util/src/com/intellij/util/ui/UIUtil.java
@@ -2085,7 +2085,7 @@ public class UIUtil {
* Invoke and wait in the event dispatch thread
* or in the current thread if the current thread
* is event queue thread.
- *
+ * DO NOT INVOKE THIS METHOD FROM UNDER READ ACTION.
* @param runnable a runnable to invoke
* @see #invokeAndWaitIfNeeded(com.intellij.util.ThrowableRunnable)
*/
@@ -2103,6 +2103,14 @@ public class UIUtil {
}
}
+ /**
+ * Invoke and wait in the event dispatch thread
+ * or in the current thread if the current thread
+ * is event queue thread.
+ * DO NOT INVOKE THIS METHOD FROM UNDER READ ACTION.
+ * @param computable a runnable to invoke
+ * @see #invokeAndWaitIfNeeded(com.intellij.util.ThrowableRunnable)
+ */
public static <T> T invokeAndWaitIfNeeded(@NotNull final Computable<T> computable) {
final Ref<T> result = Ref.create();
invokeAndWaitIfNeeded(new Runnable() {
@@ -2114,6 +2122,14 @@ public class UIUtil {
return result.get();
}
+ /**
+ * Invoke and wait in the event dispatch thread
+ * or in the current thread if the current thread
+ * is event queue thread.
+ * DO NOT INVOKE THIS METHOD FROM UNDER READ ACTION.
+ * @param runnable a runnable to invoke
+ * @see #invokeAndWaitIfNeeded(com.intellij.util.ThrowableRunnable)
+ */
public static void invokeAndWaitIfNeeded(@NotNull final ThrowableRunnable runnable) throws Throwable {
if (SwingUtilities.isEventDispatchThread()) {
runnable.run();
@@ -2890,6 +2906,7 @@ public class UIUtil {
new Thread(new Runnable() {
// The wrapper thread is unnecessary, unless it blocks on the
// Clip finishing; see comments.
+ @Override
public void run() {
try {
Clip clip = AudioSystem.getClip();
diff --git a/platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java b/platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java
index ba0eb265655e..9775ddb01be1 100644
--- a/platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java
+++ b/platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java
@@ -16,6 +16,7 @@
package com.intellij.util.ui.tree;
import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Conditions;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
@@ -53,7 +54,7 @@ public class WideSelectionTreeUI extends BasicTreeUI {
@SuppressWarnings("unchecked")
public WideSelectionTreeUI() {
- this(true, Condition.TRUE);
+ this(true, Conditions.<Integer>alwaysTrue());
}
/**