Search in sources :

Example 1 with Fragment

use of com.jetbrains.python.codeInsight.fstrings.FStringParser.Fragment in project intellij-community by JetBrains.

the class PyFStringsInjector method getLanguagesToInject.

@Override
public void getLanguagesToInject(@NotNull MultiHostRegistrar registrar, @NotNull PsiElement context) {
    final PyStringLiteralExpression pyString = as(context, PyStringLiteralExpression.class);
    if (pyString == null) {
        return;
    }
    for (ASTNode node : pyString.getStringNodes()) {
        final int relNodeOffset = node.getTextRange().getStartOffset() - pyString.getTextRange().getStartOffset();
        for (Fragment offsets : getInjectionRanges(node)) {
            if (offsets.containsNamedUnicodeEscape())
                continue;
            registrar.startInjecting(PyDocstringLanguageDialect.getInstance());
            registrar.addPlace(null, null, pyString, offsets.getContentRange().shiftRight(relNodeOffset));
            registrar.doneInjecting();
        }
    }
}
Also used : PyStringLiteralExpression(com.jetbrains.python.psi.PyStringLiteralExpression) ASTNode(com.intellij.lang.ASTNode) Fragment(com.jetbrains.python.codeInsight.fstrings.FStringParser.Fragment)

Example 2 with Fragment

use of com.jetbrains.python.codeInsight.fstrings.FStringParser.Fragment in project intellij-community by JetBrains.

the class PyFStringTest method doTestUnicodeEscapeDetection.

private static void doTestUnicodeEscapeDetection(String fStringText, boolean expected) {
    final List<Fragment> fragments = FStringParser.parse(fStringText).getFragments();
    assertSize(1, fragments);
    final Fragment offsets = fragments.get(0);
    assertEquals(expected, offsets.containsNamedUnicodeEscape());
}
Also used : Fragment(com.jetbrains.python.codeInsight.fstrings.FStringParser.Fragment)

Example 3 with Fragment

use of com.jetbrains.python.codeInsight.fstrings.FStringParser.Fragment in project intellij-community by JetBrains.

the class FStringsAnnotator method visitPyStringLiteralExpression.

@Override
public void visitPyStringLiteralExpression(PyStringLiteralExpression pyString) {
    for (ASTNode node : pyString.getStringNodes()) {
        final StringNodeInfo nodeInfo = new StringNodeInfo(node);
        final String nodeText = node.getText();
        if (nodeInfo.isFormatted()) {
            final int nodeContentEnd = nodeInfo.getContentRange().getEndOffset();
            final FStringParser.ParseResult result = FStringParser.parse(nodeText);
            TextRange unclosedBraceRange = null;
            for (Fragment fragment : result.getFragments()) {
                final int fragLeftBrace = fragment.getLeftBraceOffset();
                final int fragContentEnd = fragment.getContentEndOffset();
                final int fragRightBrace = fragment.getRightBraceOffset();
                final TextRange wholeFragmentRange = TextRange.create(fragLeftBrace, fragRightBrace == -1 ? nodeContentEnd : fragRightBrace + 1);
                if (fragment.getDepth() > 2) {
                    // Do not report anything about expression fragments nested deeper that three times
                    if (fragment.getDepth() == 3) {
                        report("Expression fragment inside f-string is nested too deeply", wholeFragmentRange, node);
                    }
                    continue;
                }
                if (CharArrayUtil.isEmptyOrSpaces(nodeText, fragLeftBrace + 1, fragContentEnd) && fragContentEnd < nodeContentEnd) {
                    final TextRange range = TextRange.create(fragLeftBrace, fragContentEnd + 1);
                    report("Empty expression fragments are not allowed inside f-strings", range, node);
                }
                if (fragRightBrace == -1 && unclosedBraceRange == null) {
                    unclosedBraceRange = wholeFragmentRange;
                }
                if (fragment.getFirstHashOffset() != -1) {
                    final TextRange range = TextRange.create(fragment.getFirstHashOffset(), fragment.getContentEndOffset());
                    report("Expression fragments inside f-strings cannot include line comments", range, node);
                }
                for (int i = fragLeftBrace + 1; i < fragment.getContentEndOffset(); i++) {
                    if (nodeText.charAt(i) == '\\') {
                        reportCharacter("Expression fragments inside f-strings cannot include backslashes", i, node);
                    }
                }
                // Do not warn about illegal conversion character if '!' is right before closing quotes 
                if (fragContentEnd < nodeContentEnd && nodeText.charAt(fragContentEnd) == '!' && fragContentEnd + 1 < nodeContentEnd) {
                    final char conversionChar = nodeText.charAt(fragContentEnd + 1);
                    // No conversion character -- highlight only "!"
                    if (fragContentEnd + 1 == fragRightBrace || conversionChar == ':') {
                        reportCharacter("Conversion character is expected: should be one of 's', 'r', 'a'", fragContentEnd, node);
                    } else // Wrong conversion character -- highlight both "!" and the following symbol
                    if ("sra".indexOf(conversionChar) < 0) {
                        final TextRange range = TextRange.from(fragContentEnd, 2);
                        report("Illegal conversion character '" + conversionChar + "': should be one of 's', 'r', 'a'", range, node);
                    }
                }
            }
            for (Integer offset : result.getSingleRightBraces()) {
                reportCharacter("Single '}' is not allowed inside f-strings", offset, node);
            }
            if (unclosedBraceRange != null) {
                report("'}' is expected", unclosedBraceRange, node);
            }
        }
    }
}
Also used : FStringParser(com.jetbrains.python.codeInsight.fstrings.FStringParser) ASTNode(com.intellij.lang.ASTNode) TextRange(com.intellij.openapi.util.TextRange) StringNodeInfo(com.jetbrains.python.psi.PyUtil.StringNodeInfo) Fragment(com.jetbrains.python.codeInsight.fstrings.FStringParser.Fragment)

Aggregations

Fragment (com.jetbrains.python.codeInsight.fstrings.FStringParser.Fragment)3 ASTNode (com.intellij.lang.ASTNode)2 TextRange (com.intellij.openapi.util.TextRange)1 FStringParser (com.jetbrains.python.codeInsight.fstrings.FStringParser)1 PyStringLiteralExpression (com.jetbrains.python.psi.PyStringLiteralExpression)1 StringNodeInfo (com.jetbrains.python.psi.PyUtil.StringNodeInfo)1