[linter] lines_longer_than_80_chars and document_ignores shouldn't read files

* document_ignores read each file once
* lines_longer_than_80_chars read each file for every line > 80 chars (!).

This follows the approach in
https://dart-review.googlesource.com/c/sdk/+/401424 where the same
pattern was identified as bad.

Before this CL, if a file had, say, 1000 lines > 80 chars (and having
the lint enabled), the lint would read the file - from disk - 1000
times. A somewhat saving grace is that for open files - which I guess is
where it's normally run a lot - it normally reads from an overlay file
and thus not from disk.

Except if you are editing a part in which case the open part is an
overlay, but the "parent" (which is for whatever reason also linted) is
read from file. So if you have 1000 lines > 80 chars in the "parent"
file, and is typing in a part file you're in for a really bad time.

This CL should reduce the number of reads in the lint to 0.

Change-Id: Iac6c78f50add1bc7a411c0c244a181f5ca2ea25b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/411300
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
This commit is contained in:
Jens Johansen
2025-02-21 06:40:12 -08:00
committed by Commit Queue
parent f66ceaf292
commit fb3f2633ba
2 changed files with 11 additions and 5 deletions
@@ -5,7 +5,10 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/src/ignore_comments/ignore_info.dart' // ignore: implementation_imports
show CommentTokenExtension, CompilationUnitExtension, IgnoredDiagnosticComment;
show
CommentTokenExtension,
CompilationUnitExtension,
IgnoredDiagnosticComment;
import 'package:analyzer/src/utilities/extensions/string.dart' // ignore: implementation_imports
show IntExtension;
@@ -25,19 +28,21 @@ class DocumentIgnores extends LintRule {
NodeLintRegistry registry,
LinterContext context,
) {
var visitor = _Visitor(this);
var visitor = _Visitor(this, context);
registry.addCompilationUnit(this, visitor);
}
}
class _Visitor extends SimpleAstVisitor<void> {
final LintRule rule;
final LinterContext context;
_Visitor(this.rule);
_Visitor(this.rule, this.context);
@override
void visitCompilationUnit(CompilationUnit node) {
var content = node.declaredFragment?.source.contents.data;
assert(context.currentUnit?.unit == node);
var content = context.currentUnit?.content;
for (var comment in node.ignoreComments) {
var ignoredElements = comment.ignoredElements;
if (ignoredElements.isEmpty) {
@@ -161,6 +161,8 @@ class _Visitor extends SimpleAstVisitor<void> {
var lineInfo = node.lineInfo;
var lineCount = lineInfo.lineCount;
var longLines = <_LineInfo>[];
assert(context.currentUnit?.unit == node);
var content = context.currentUnit?.content;
for (var i = 0; i < lineCount; i++) {
var start = lineInfo.getOffsetOfLine(i);
int end;
@@ -170,7 +172,6 @@ class _Visitor extends SimpleAstVisitor<void> {
end = lineInfo.getOffsetOfLine(i + 1) - 1;
var length = end - start;
if (length > 80) {
var content = node.declaredFragment?.source.contents.data;
if (content != null &&
content[end] == _lf &&
content[end - 1] == _cr) {