Search in sources :

Example 71 with TextRange

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;
}
Also used : TextRange(com.intellij.openapi.util.TextRange) NotNull(org.jetbrains.annotations.NotNull)

Example 72 with TextRange

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);
}
Also used : PyStringLiteralExpression(com.jetbrains.python.psi.PyStringLiteralExpression) ASTNode(com.intellij.lang.ASTNode) TextRange(com.intellij.openapi.util.TextRange) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 73 with TextRange

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)));
    }
}
Also used : FoldingDescriptor(com.intellij.lang.folding.FoldingDescriptor) TextRange(com.intellij.openapi.util.TextRange)

Example 74 with TextRange

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();
    }
}
Also used : IElementType(com.intellij.psi.tree.IElementType) FoldingDescriptor(com.intellij.lang.folding.FoldingDescriptor) ASTNode(com.intellij.lang.ASTNode) TextRange(com.intellij.openapi.util.TextRange)

Example 75 with TextRange

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;
}
Also used : TextRange(com.intellij.openapi.util.TextRange) TypeEvalContext(com.jetbrains.python.psi.types.TypeEvalContext) PyType(com.jetbrains.python.psi.types.PyType)

Aggregations

TextRange (com.intellij.openapi.util.TextRange)1314 PsiElement (com.intellij.psi.PsiElement)261 NotNull (org.jetbrains.annotations.NotNull)237 Nullable (org.jetbrains.annotations.Nullable)167 Document (com.intellij.openapi.editor.Document)132 ArrayList (java.util.ArrayList)117 Project (com.intellij.openapi.project.Project)96 PsiFile (com.intellij.psi.PsiFile)96 ASTNode (com.intellij.lang.ASTNode)95 Editor (com.intellij.openapi.editor.Editor)75 PsiReference (com.intellij.psi.PsiReference)54 VirtualFile (com.intellij.openapi.vfs.VirtualFile)51 IElementType (com.intellij.psi.tree.IElementType)48 IncorrectOperationException (com.intellij.util.IncorrectOperationException)48 Pair (com.intellij.openapi.util.Pair)47 HighlightInfo (com.intellij.codeInsight.daemon.impl.HighlightInfo)33 ProperTextRange (com.intellij.openapi.util.ProperTextRange)32 FoldingDescriptor (com.intellij.lang.folding.FoldingDescriptor)31 XmlTag (com.intellij.psi.xml.XmlTag)31 List (java.util.List)31