PythonStringUtil -> python-psi-api

This commit is contained in:
Dmitry Jemerov
2012-08-08 18:16:10 +02:00
parent 38f20a645c
commit 5b4da4962b
@@ -0,0 +1,312 @@
package com.jetbrains.python;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.util.ObjectUtils;
import com.intellij.util.PathUtil;
import com.jetbrains.python.psi.PyExpression;
import com.jetbrains.python.psi.PyStringLiteralExpression;
import com.jetbrains.python.psi.impl.PyQualifiedName;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.intellij.openapi.util.text.StringUtil.endsWith;
import static com.intellij.openapi.util.text.StringUtil.startsWith;
/**
* @author Alexei Orischenko
* Date: Nov 26, 2009
*/
public class PythonStringUtil {
private PythonStringUtil() {
}
/**
* 'text' => text
* "text" => text
* text => text
* "text => "text
*
* @return string without heading and trailing pair of ' or "
*/
@NotNull
public static String getStringValue(@NotNull String s) {
return getStringValueTextRange(s).substring(s);
}
public static TextRange getStringValueTextRange(@NotNull String s) {
if ((s.charAt(0) == '\'' || s.charAt(0) == '"') && (s.charAt(0) == s.charAt(s.length() - 1)) && s.length() > 1) {
return TextRange.create(1, s.length() - 1);
}
else {
return TextRange.create(0, s.length());
}
}
@NotNull
public static String removeFirstPrefix(@Nullable String s, String separator) {
if (s != null) {
int pos = s.indexOf(separator);
if (pos != -1) {
return s.substring(pos + separator.length());
}
}
return "";
}
@NotNull
public static String removeLastSuffix(@Nullable String s, String separator) {
if (s != null) {
int pos = s.lastIndexOf(separator);
if (pos != -1) {
return s.substring(0, pos);
}
}
return "";
}
public static boolean isPath(@Nullable String s) {
if (!StringUtil.isEmpty(s)) {
s = ObjectUtils.assertNotNull(s);
s = FileUtil.toSystemIndependentName(s);
final List<String> components = StringUtil.split(s, "/");
for (String name : components) {
if (name == components.get(0) && SystemInfo.isWindows && name.endsWith(":")) {
continue;
}
if (!PathUtil.isValidFileName(name)) {
return false;
}
}
return true;
}
return false;
}
public static boolean isEmail(String s) {
if (!StringUtil.isEmpty(s)) {
Pattern p = Pattern.compile("^[\\w\\.-]+@([\\w\\-]+\\.)+[a-z]{2,4}$");
Matcher m = p.matcher(s);
return m.matches();
}
return false;
}
@NotNull
public static String getFirstPrefix(String s, String separator) {
if (s != null) {
int pos = s.indexOf(separator);
if (pos != -1) {
return s.substring(0, pos);
}
}
return s != null ? s : "";
}
public static String getLastSuffix(String s, String separator) {
if (s != null) {
int pos = s.lastIndexOf(separator);
if (pos != -1) {
return s.substring(pos + 1);
}
}
return "";
}
/**
* Replaces word after last dot from string s to newElementName.
* For example 'yy.xxx.foo' can be renamed to 'yy.xxx.bar'
*
* @param s
* @param newElementName
* @return
*/
public static String replaceLastSuffix(String s, String separator, String newElementName) {
Pair<String, String> quotes = null;
if (isQuoted(s)) {
quotes = getQuotes(s);
s = stripQuotesAroundValue(s);
}
s = removeLastSuffix(s, separator);
if (s.length() > 0) {
s += separator;
}
s += newElementName;
if (quotes != null) {
s = quotes.first + s + quotes.second;
}
return s;
}
public static TextRange lastSuffixTextRange(@NotNull String text, String separator) {
int offset = text.lastIndexOf(separator) + 1;
int length = text.length() - offset;
return TextRange.from(offset + 1, length);
}
/**
* Handles unicode and raw strings
*
* @param text
* @return false if no quotes found, true otherwise
* sdfs -> false
* ur'x' -> true
* "string" -> true
*/
public static boolean isQuoted(@Nullable String text) {
if (text == null) {
return false;
}
if (text.toLowerCase().startsWith("u")) {
text = text.substring(1);
}
assert text != null;
if (text.toLowerCase().startsWith("r")) {
text = text.substring(1);
}
assert text != null;
if (text.length() > 1 && text.charAt(0) == text.charAt(text.length() - 1) && (text.charAt(0) == '\'' || text.charAt(0) == '"')) {
return true;
}
return false;
}
/**
* Handles unicode and raw strings
*
* @param text
* @return open and close quote (including raw/unicode prefixes), null if no quotes present in string
* 'string' -> (', ')
* UR"unicode raw string" -> (UR", ")
*/
@Nullable
public static Pair<String, String> getQuotes(@NotNull String text) {
String first = "";
if (text.toLowerCase().startsWith("u")) {
first += text.substring(0, 1);
text = text.substring(1);
}
if (text.toLowerCase().startsWith("r")) {
first += text.substring(0, 1);
text = text.substring(1);
}
int last = text.length() - 1;
if (text.length() > 2 && (text.charAt(0) == '\'' || text.charAt(0) == '"') && (text.charAt(last) == '\'' || text.charAt(last) == '"')) {
return Pair.create(first + text.substring(0, 1), text.substring(last));
}
else {
return null;
}
}
@Nullable
public static String intersect(String fullName, String elementStringValue) {
PyQualifiedName fullQName = PyQualifiedName.fromDottedString(fullName);
PyQualifiedName stringQName = PyQualifiedName.fromDottedString(elementStringValue);
String[] s1 = stringQName.getComponents().toArray(new String[stringQName.getComponentCount()]);
String[] s2 = fullQName.getComponents().toArray(new String[fullQName.getComponentCount()]);
for (int i = s1.length - 1; i >= 0; i--) {
boolean flag = true;
if (i > s2.length - 1) {
continue;
}
for (int j = 0; j <= i; j++) {
if (!s1[i - j].equals(s2[s2.length - j - 1])) {
flag = false;
break;
}
}
if (flag) {
StringBuilder res = new StringBuilder("");
for (int j = 0; j <= i; j++) {
if (j > 0) {
res.append(".");
}
res.append(s1[j]);
}
return res.toString();
}
}
return null;
}
public static TextRange getTextRange(PsiElement element) {
if (element instanceof PyStringLiteralExpression) {
final List<TextRange> ranges = ((PyStringLiteralExpression)element).getStringValueTextRanges();
return ranges.get(0);
}
else {
return new TextRange(0, element.getTextLength());
}
}
@Nullable
public static String getText(@Nullable PyExpression ex) {
if (ex == null) {
return null;
}
else {
return ex.getText();
}
}
@Nullable
public static String getStringValue(@Nullable PsiElement o) {
if (o == null) {
return null;
}
if (o instanceof PyStringLiteralExpression) {
PyStringLiteralExpression literalExpression = (PyStringLiteralExpression)o;
return literalExpression.getStringValue();
}
else {
return o.getText();
}
}
public static String stripQuotesAroundValue(String text) {
Pair<String, String> quotes = getQuotes(text);
if (quotes == null) {
return text;
}
return text.substring(quotes.first.length(), text.length() - quotes.second.length());
}
public static boolean isRawString(String text) {
text = text.toLowerCase();
if (text.startsWith("u")) {
text = text.substring(1);
}
return isStringPrefixedBy(text.toLowerCase(), "r");
}
private static boolean isStringPrefixedBy(String text, String prefix) {
return (startsWith(text, prefix + "\"") && endsWith(text, "\"")) || (startsWith(text, prefix + "\'") && endsWith(text, "\'"));
}
}