From e1db15d9d7348a20ff6a4fd1687b9ccf0c613c25 Mon Sep 17 00:00:00 2001 From: Dmitry Cheryasov Date: Sun, 6 Jul 2008 02:54:37 +0400 Subject: [PATCH] Closes PY-31 "Unclosed string literals are not highlighted as erorrs". --- .../com/jetbrains/python/PythonLanguage.java | 1 + .../validation/StringConstantAnnotator.java | 53 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 python/src/com/jetbrains/python/validation/StringConstantAnnotator.java diff --git a/python/src/com/jetbrains/python/PythonLanguage.java b/python/src/com/jetbrains/python/PythonLanguage.java index 2f42f244dbba..1fb49da17cd6 100644 --- a/python/src/com/jetbrains/python/PythonLanguage.java +++ b/python/src/com/jetbrains/python/PythonLanguage.java @@ -36,6 +36,7 @@ public class PythonLanguage extends Language { _annotators.add(DocStringAnnotator.class); _annotators.add(ImportAnnotator.class); _annotators.add(UnresolvedReferenceAnnotator.class); + _annotators.add(StringConstantAnnotator.class); } diff --git a/python/src/com/jetbrains/python/validation/StringConstantAnnotator.java b/python/src/com/jetbrains/python/validation/StringConstantAnnotator.java new file mode 100644 index 000000000000..95531c0e4740 --- /dev/null +++ b/python/src/com/jetbrains/python/validation/StringConstantAnnotator.java @@ -0,0 +1,53 @@ +package com.jetbrains.python.validation; + +import com.jetbrains.python.psi.PyStringLiteralExpression; + +/** + * Looks for well-formedness of string constants. + * User: dcheryasov + * Date: Jul 5, 2008 + * Time: 11:58:57 PM + */ +public class StringConstantAnnotator extends PyAnnotator { + public void visitPyStringLiteralExpression(final PyStringLiteralExpression node) { + String s = node.getText(); + String msg = ""; + boolean ok = true; + boolean esc = false; + int index = 0; + // skip 'unicode' and 'raw' modifiers + char first_quote = s.charAt(index); + if ((first_quote == 'u') || (first_quote == 'U')) index += 1; + first_quote = s.charAt(index); + if ((first_quote == 'r') || (first_quote == 'R')) index += 1; + first_quote = s.charAt(index); + // s can't begin with non-quote, else parser would not say it's a string + index += 1; + if (index >= s.length()) { // sole opening quote + msg = "No closing quote [" + first_quote + "]"; + ok = false; + } + else { + while (ok && (index < s.length()-1)) { + char c = s.charAt(index); + if (esc) esc = false; + else { + if (c == first_quote) { + msg = "Premature closing quote [" + first_quote + "]"; + ok = false; + } + else if (c == '\\') esc = true; + } + index += 1; + } + if (ok && (esc || (s.charAt(index) != first_quote))) { + msg = "Missing closing quote [" + first_quote + "]"; + ok = false; + } + } + // + if (! ok) { + getHolder().createErrorAnnotation(node, msg); + } + } +}