dartCodeWithoutComments function

String dartCodeWithoutComments(
  1. String source
)

source with its comments removed and everything else — string literals included — kept, newlines and all.

stripDartComments reads a string as running to the next quote of its kind, which is right for the prose scans it serves and wrong for a structural one: '"${v.replaceAll('"', '""')}"' ends early there, and every comment after it is read as code. This one follows an interpolation's braces, so a quote inside ${…} does not end the string.

Implementation

String dartCodeWithoutComments(String source) {
  final s = source;
  final out = StringBuffer();
  late final int Function(int, bool) code;

  int string(int i) {
    final raw = i > 0 && (s[i - 1] == 'r' || s[i - 1] == 'R');
    final quote = s[i];
    final terminator = s.startsWith(quote * 3, i) ? quote * 3 : quote;
    out.write(terminator);
    i += terminator.length;
    while (i < s.length && !s.startsWith(terminator, i)) {
      if (!raw && s[i] == r'\' && i + 1 < s.length) {
        out.write(s.substring(i, i + 2));
        i += 2;
        continue;
      }
      if (!raw && s.startsWith(r'${', i)) {
        out.write(r'${');
        i = code(i + 2, true);
        continue;
      }
      out.write(s[i]);
      i++;
    }
    if (i < s.length) out.write(terminator);
    return i + terminator.length;
  }

  code = (int i, bool untilBrace) {
    var depth = 0;
    while (i < s.length) {
      final c = s[i];
      if (s.startsWith('//', i)) {
        while (i < s.length && s[i] != '\n') {
          i++;
        }
        continue;
      }
      if (s.startsWith('/*', i)) {
        var nesting = 0;
        while (i < s.length) {
          if (s.startsWith('/*', i)) {
            nesting++;
            i += 2;
          } else if (s.startsWith('*/', i)) {
            i += 2;
            if (--nesting == 0) break;
          } else {
            if (s[i] == '\n') out.write('\n');
            i++;
          }
        }
        continue;
      }
      if (c == "'" || c == '"') {
        i = string(i);
        continue;
      }
      if (untilBrace) {
        if (c == '{') depth++;
        if (c == '}') {
          if (depth == 0) {
            out.write('}');
            return i + 1;
          }
          depth--;
        }
      }
      out.write(c);
      i++;
    }
    return i;
  };

  code(0, false);
  return out.toString();
}