From fb3f2633badbd50cd09d68abe682ae552bb093f6 Mon Sep 17 00:00:00 2001 From: Jens Johansen Date: Fri, 21 Feb 2025 06:40:12 -0800 Subject: [PATCH] [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 Commit-Queue: Jens Johansen --- pkg/linter/lib/src/rules/document_ignores.dart | 13 +++++++++---- .../lib/src/rules/lines_longer_than_80_chars.dart | 3 ++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/pkg/linter/lib/src/rules/document_ignores.dart b/pkg/linter/lib/src/rules/document_ignores.dart index 51c1cbfb0a8..b3022d30f9d 100644 --- a/pkg/linter/lib/src/rules/document_ignores.dart +++ b/pkg/linter/lib/src/rules/document_ignores.dart @@ -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 { 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) { diff --git a/pkg/linter/lib/src/rules/lines_longer_than_80_chars.dart b/pkg/linter/lib/src/rules/lines_longer_than_80_chars.dart index 7bd8e96d753..49d6728769b 100644 --- a/pkg/linter/lib/src/rules/lines_longer_than_80_chars.dart +++ b/pkg/linter/lib/src/rules/lines_longer_than_80_chars.dart @@ -161,6 +161,8 @@ class _Visitor extends SimpleAstVisitor { 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 { 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) {