use of com.intellij.openapi.util.TextRange in project intellij-community by JetBrains.
the class PyInjectionUtil method processStringLiteral.
@NotNull
private static InjectionResult processStringLiteral(@NotNull PsiElement element, @NotNull MultiHostRegistrar registrar, @NotNull String prefix, @NotNull String suffix, @NotNull Formatting formatting) {
final String missingValue = "missing_value";
if (element instanceof PyStringLiteralExpression) {
boolean injected = false;
boolean strict = true;
final PyStringLiteralExpression expr = (PyStringLiteralExpression) element;
final List<TextRange> ranges = expr.getStringValueTextRanges();
final String text = expr.getText();
for (TextRange range : ranges) {
if (formatting != Formatting.NONE) {
final String part = range.substring(text);
final List<FormatStringChunk> chunks = formatting == Formatting.NEW_STYLE ? parseNewStyleFormat(part) : parsePercentFormat(part);
if (!filterSubstitutions(chunks).isEmpty()) {
strict = false;
}
for (int i = 0; i < chunks.size(); i++) {
final FormatStringChunk chunk = chunks.get(i);
if (chunk instanceof ConstantChunk) {
final int nextIndex = i + 1;
final String chunkPrefix;
if (i == 1 && chunks.get(0) instanceof SubstitutionChunk) {
chunkPrefix = missingValue;
} else if (i == 0) {
chunkPrefix = prefix;
} else {
chunkPrefix = "";
}
final String chunkSuffix;
if (nextIndex < chunks.size() && chunks.get(nextIndex) instanceof SubstitutionChunk) {
chunkSuffix = missingValue;
} else if (nextIndex == chunks.size()) {
chunkSuffix = suffix;
} else {
chunkSuffix = "";
}
final TextRange chunkRange = chunk.getTextRange().shiftRight(range.getStartOffset());
registrar.addPlace(chunkPrefix, chunkSuffix, expr, chunkRange);
injected = true;
}
}
} else {
registrar.addPlace(prefix, suffix, expr, range);
injected = true;
}
}
return new InjectionResult(injected, strict);
} else if (element instanceof PyParenthesizedExpression) {
final PyExpression contained = ((PyParenthesizedExpression) element).getContainedExpression();
if (contained != null) {
return processStringLiteral(contained, registrar, prefix, suffix, formatting);
}
} else if (element instanceof PyBinaryExpression) {
final PyBinaryExpression expr = (PyBinaryExpression) element;
final PyExpression left = expr.getLeftExpression();
final PyExpression right = expr.getRightExpression();
final boolean isLeftString = isStringLiteralPart(left, null);
if (expr.isOperator("+")) {
final boolean isRightString = right != null && isStringLiteralPart(right, null);
InjectionResult result = InjectionResult.EMPTY;
if (isLeftString) {
result = result.append(processStringLiteral(left, registrar, prefix, isRightString ? "" : missingValue, formatting));
}
if (isRightString) {
result = result.append(processStringLiteral(right, registrar, isLeftString ? "" : missingValue, suffix, formatting));
}
return result;
} else if (expr.isOperator("%")) {
return processStringLiteral(left, registrar, prefix, suffix, Formatting.PERCENT);
}
} else if (element instanceof PyCallExpression) {
final PyExpression qualifier = getFormatCallQualifier((PyCallExpression) element);
if (qualifier != null) {
return processStringLiteral(qualifier, registrar, prefix, suffix, Formatting.NEW_STYLE);
}
}
return InjectionResult.EMPTY;
}
use of com.intellij.openapi.util.TextRange in project intellij-community by JetBrains.
the class PyCompletionConfidence method shouldSkipAutopopup.
@NotNull
@Override
public ThreeState shouldSkipAutopopup(@NotNull PsiElement contextElement, @NotNull PsiFile psiFile, int offset) {
ASTNode node = contextElement.getNode();
if (node != null) {
if (node.getElementType() == PyTokenTypes.FLOAT_LITERAL) {
return ThreeState.YES;
}
if (PyTokenTypes.STRING_NODES.contains(node.getElementType())) {
final PsiElement parent = contextElement.getParent();
if (parent instanceof PyStringLiteralExpression) {
final List<TextRange> ranges = ((PyStringLiteralExpression) parent).getStringValueTextRanges();
int relativeOffset = offset - parent.getTextRange().getStartOffset();
if (ranges.size() > 0 && relativeOffset < ranges.get(0).getStartOffset()) {
return ThreeState.YES;
}
}
}
}
return super.shouldSkipAutopopup(contextElement, psiFile, offset);
}
use of com.intellij.openapi.util.TextRange in project intellij-community by JetBrains.
the class PythonFoldingBuilder method foldCollectionLiteral.
private static void foldCollectionLiteral(ASTNode node, List<FoldingDescriptor> descriptors) {
if (StringUtil.countNewLines(node.getChars()) > 0) {
TextRange range = node.getTextRange();
int delta = node.getElementType() == PyElementTypes.TUPLE_EXPRESSION ? 0 : 1;
descriptors.add(new FoldingDescriptor(node, TextRange.create(range.getStartOffset() + delta, range.getEndOffset() - delta)));
}
}
use of com.intellij.openapi.util.TextRange in project intellij-community by JetBrains.
the class PythonFoldingBuilder method appendDescriptors.
private static void appendDescriptors(ASTNode node, List<FoldingDescriptor> descriptors) {
IElementType elementType = node.getElementType();
if (elementType instanceof PyFileElementType) {
final List<PyImportStatementBase> imports = ((PyFile) node.getPsi()).getImportBlock();
if (imports.size() > 1) {
final PyImportStatementBase firstImport = imports.get(0);
final PyImportStatementBase lastImport = imports.get(imports.size() - 1);
descriptors.add(new FoldingDescriptor(firstImport, new TextRange(firstImport.getTextRange().getStartOffset(), lastImport.getTextRange().getEndOffset())));
}
} else if (elementType == PyElementTypes.STATEMENT_LIST) {
foldStatementList(node, descriptors);
} else if (elementType == PyElementTypes.STRING_LITERAL_EXPRESSION) {
foldLongStrings(node, descriptors);
} else if (FOLDABLE_COLLECTIONS_LITERALS.contains(elementType)) {
foldCollectionLiteral(node, descriptors);
} else if (elementType == PyTokenTypes.END_OF_LINE_COMMENT) {
foldSequentialComments(node, descriptors);
}
ASTNode child = node.getFirstChildNode();
while (child != null) {
appendDescriptors(child, descriptors);
child = child.getTreeNext();
}
}
use of com.intellij.openapi.util.TextRange in project intellij-community by JetBrains.
the class IntroduceHandler method generateSuggestedNames.
protected Collection<String> generateSuggestedNames(PyExpression expression) {
Collection<String> candidates = new LinkedHashSet<String>() {
@Override
public boolean add(String s) {
if (PyNames.isReserved(s)) {
return false;
}
return super.add(s);
}
};
String text = expression.getText();
final Pair<PsiElement, TextRange> selection = expression.getUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE);
if (selection != null) {
text = selection.getSecond().substring(selection.getFirst().getText());
}
if (expression instanceof PyCallExpression) {
final PyExpression callee = ((PyCallExpression) expression).getCallee();
if (callee != null) {
text = callee.getText();
}
}
if (text != null) {
candidates.addAll(NameSuggesterUtil.generateNames(text));
}
final TypeEvalContext context = TypeEvalContext.userInitiated(expression.getProject(), expression.getContainingFile());
PyType type = context.getType(expression);
if (type != null && type != PyNoneType.INSTANCE) {
String typeName = type.getName();
if (typeName != null) {
if (type.isBuiltin()) {
typeName = typeName.substring(0, 1);
}
candidates.addAll(NameSuggesterUtil.generateNamesByType(typeName));
}
}
final PyKeywordArgument kwArg = PsiTreeUtil.getParentOfType(expression, PyKeywordArgument.class);
if (kwArg != null && kwArg.getValueExpression() == expression) {
candidates.add(kwArg.getKeyword());
}
Optional.ofNullable(PsiTreeUtil.getParentOfType(expression, PyArgumentList.class)).map(PyArgumentList::getCallExpression).ifPresent(call -> StreamEx.of(call.multiMapArguments(PyResolveContext.noImplicits())).map(mapping -> mapping.getMappedParameters().get(expression)).nonNull().map(PyNamedParameter::getName).forEach(candidates::add));
return candidates;
}
Aggregations