use of com.jetbrains.python.psi.types.PyType in project intellij-community by JetBrains.
the class PyStringConcatenationToFormatIntention method doInvoke.
public void doInvoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
PsiElement element = PsiTreeUtil.getTopmostParentOfType(file.findElementAt(editor.getCaretModel().getOffset()), PyBinaryExpression.class);
if (element == null)
return;
final LanguageLevel languageLevel = LanguageLevel.forElement(element);
final boolean useFormatMethod = languageLevel.isAtLeast(LanguageLevel.PYTHON27);
NotNullFunction<String, String> escaper = StringUtil.escaper(false, "\"\'\\");
StringBuilder stringLiteral = new StringBuilder();
List<String> parameters = new ArrayList<>();
Pair<String, String> quotes = Pair.create("\"", "\"");
boolean quotesDetected = false;
final TypeEvalContext context = TypeEvalContext.userInitiated(file.getProject(), file);
int paramCount = 0;
boolean isUnicode = false;
final PyClassTypeImpl unicodeType = PyBuiltinCache.getInstance(element).getObjectType("unicode");
for (PyExpression expression : getSimpleExpressions((PyBinaryExpression) element)) {
if (expression instanceof PyStringLiteralExpression) {
final PyType type = context.getType(expression);
if (type != null && type.equals(unicodeType)) {
isUnicode = true;
}
if (!quotesDetected) {
quotes = PyStringLiteralUtil.getQuotes(expression.getText());
quotesDetected = true;
}
String value = ((PyStringLiteralExpression) expression).getStringValue();
if (!useFormatMethod) {
value = value.replace("%", "%%");
}
stringLiteral.append(escaper.fun(value));
} else {
addParamToString(stringLiteral, paramCount, useFormatMethod);
parameters.add(expression.getText());
++paramCount;
}
}
if (quotes == null)
quotes = Pair.create("\"", "\"");
stringLiteral.insert(0, quotes.getFirst());
if (isUnicode && !quotes.getFirst().toLowerCase().contains("u"))
stringLiteral.insert(0, "u");
stringLiteral.append(quotes.getSecond());
PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project);
if (!parameters.isEmpty()) {
if (useFormatMethod) {
stringLiteral.append(".format(").append(StringUtil.join(parameters, ",")).append(")");
} else {
final String paramString = parameters.size() > 1 ? "(" + StringUtil.join(parameters, ",") + ")" : StringUtil.join(parameters, ",");
stringLiteral.append(" % ").append(paramString);
}
final PyExpression expression = elementGenerator.createFromText(LanguageLevel.getDefault(), PyExpressionStatement.class, stringLiteral.toString()).getExpression();
element.replace(expression);
} else {
PyStringLiteralExpression stringLiteralExpression = elementGenerator.createStringLiteralAlreadyEscaped(stringLiteral.toString());
element.replace(stringLiteralExpression);
}
}
use of com.jetbrains.python.psi.types.PyType in project intellij-community by JetBrains.
the class PyAddSpecifierToFormatQuickFix method applyFix.
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
final PyBinaryExpression expression = PsiTreeUtil.getParentOfType(element, PyBinaryExpression.class);
if (expression == null)
return;
PyExpression rightExpression = expression.getRightExpression();
if (rightExpression instanceof PyParenthesizedExpression) {
rightExpression = ((PyParenthesizedExpression) rightExpression).getContainedExpression();
}
if (rightExpression == null)
return;
final PsiFile file = element.getContainingFile();
final Document document = FileDocumentManager.getInstance().getDocument(file.getVirtualFile());
if (document == null)
return;
final int offset = element.getTextOffset();
final TypeEvalContext context = TypeEvalContext.userInitiated(file.getProject(), file);
final PyClassType strType = PyBuiltinCache.getInstance(element).getStrType();
final PyClassType floatType = PyBuiltinCache.getInstance(element).getFloatType();
final PyClassType intType = PyBuiltinCache.getInstance(element).getIntType();
final PyExpression leftExpression = expression.getLeftExpression();
if (leftExpression instanceof PyStringLiteralExpression) {
final List<PyStringFormatParser.SubstitutionChunk> chunks = filterSubstitutions(parsePercentFormat(((PyStringLiteralExpression) leftExpression).getStringValue()));
PyExpression[] elements;
if (rightExpression instanceof PyTupleExpression) {
elements = ((PyTupleExpression) rightExpression).getElements();
} else {
elements = new PyExpression[] { rightExpression };
}
int shift = 2;
for (int i = 0; i < chunks.size(); i++) {
final PyStringFormatParser.SubstitutionChunk chunk = chunks.get(i);
if (elements.length <= i)
return;
final PyType type = context.getType(elements[i]);
final char conversionType = chunk.getConversionType();
if (conversionType == '