void visitLexeme()

in lib/src/rules/unnecessary_string_escapes.dart [79:126]


  void visitLexeme(
    Token token, {
    required bool isSingleQuoted,
    required bool isMultiline,
    required int contentsOffset,
    required int contentsEnd,
  }) {
    // For multiline string we keep the list on pending quotes.
    // Starting from 3 consecutive quotes, we allow escaping.
    // index -> escaped
    var pendingQuotes = <int, bool>{};
    void checkPendingQuotes() {
      if (isMultiline && pendingQuotes.length < 3) {
        var escapeIndexes =
            pendingQuotes.entries.where((e) => e.value).map((e) => e.key);
        for (var index in escapeIndexes) {
          // case for '''___\'''' : without last backslash it leads a parsing error
          if (contentsEnd != token.end && index + 2 == contentsEnd) continue;
          rule.reporter.reportErrorForOffset(rule.lintCode, index, 1);
        }
      }
    }

    var lexeme = token.lexeme
        .substring(contentsOffset - token.offset, contentsEnd - token.offset);
    for (var i = 0; i < lexeme.length; i++) {
      var current = lexeme[i];
      var escaped = false;
      if (current == r'\' && i < lexeme.length - 1) {
        escaped = true;
        i += 1;
        current = lexeme[i];
        if (isSingleQuoted && current == '"' ||
            !isSingleQuoted && current == "'" ||
            !allowedEscapedChars.contains(current)) {
          rule.reporter
              .reportErrorForOffset(rule.lintCode, contentsOffset + i - 1, 1);
        }
      }
      if (isSingleQuoted ? current == "'" : current == '"') {
        pendingQuotes[contentsOffset + i - (escaped ? 1 : 0)] = escaped;
      } else {
        checkPendingQuotes();
        pendingQuotes.clear();
      }
    }
    checkPendingQuotes();
  }