mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
WIP Commits separated as follows: - Update lints in analysis_options files - Run `dart fix --apply` - Clean up leftover analysis issues - Run `dart format .` in the right places. Local analysis and testing passes. Checking CI now. Part of https://github.com/flutter/flutter/issues/178827 - Adoption of flutter_lints in examples/api coming in a separate change (cc @loic-sharma) ## Pre-launch Checklist - [ ] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [ ] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [ ] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [ ] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
101 lines
4.0 KiB
Dart
101 lines
4.0 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'dart:io' show Directory;
|
|
|
|
import 'package:analyzer/dart/analysis/analysis_context.dart';
|
|
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
|
|
import 'package:analyzer/dart/analysis/results.dart';
|
|
import 'package:analyzer/dart/analysis/session.dart';
|
|
import 'package:path/path.dart' as path;
|
|
|
|
import '../utils.dart';
|
|
|
|
/// Analyzes the dart source files in the given `flutterRootDirectory` with the
|
|
/// given [AnalyzeRule]s.
|
|
///
|
|
/// The `includePath` parameter takes a collection of paths relative to the given
|
|
/// `flutterRootDirectory`. It specifies the files or directory this function
|
|
/// should analyze. Defaults to null in which case this function analyzes the
|
|
/// all dart source files in `flutterRootDirectory`.
|
|
///
|
|
/// The `excludePath` parameter takes a collection of paths relative to the given
|
|
/// `flutterRootDirectory` that this function should skip analyzing.
|
|
///
|
|
/// If a compilation unit can not be resolved, this function ignores the
|
|
/// corresponding dart source file and logs an error using [foundError].
|
|
Future<void> analyzeWithRules(
|
|
String flutterRootDirectory,
|
|
List<AnalyzeRule> rules, {
|
|
Iterable<String>? includePaths,
|
|
Iterable<String>? excludePaths,
|
|
}) async {
|
|
if (!Directory(flutterRootDirectory).existsSync()) {
|
|
foundError(<String>['Analyzer error: the specified $flutterRootDirectory does not exist.']);
|
|
}
|
|
final Iterable<String> includes =
|
|
includePaths?.map(
|
|
(String relativePath) => path.canonicalize('$flutterRootDirectory/$relativePath'),
|
|
) ??
|
|
<String>[path.canonicalize(flutterRootDirectory)];
|
|
final collection = AnalysisContextCollection(
|
|
includedPaths: includes.toList(),
|
|
excludedPaths: excludePaths
|
|
?.map((String relativePath) => path.canonicalize('$flutterRootDirectory/$relativePath'))
|
|
.toList(),
|
|
);
|
|
|
|
final analyzerErrors = <String>[];
|
|
for (final AnalysisContext context in collection.contexts) {
|
|
final Iterable<String> analyzedFilePaths = context.contextRoot.analyzedFiles();
|
|
final AnalysisSession session = context.currentSession;
|
|
|
|
for (final filePath in analyzedFilePaths) {
|
|
final SomeResolvedUnitResult unit = await session.getResolvedUnit(filePath);
|
|
if (unit is ResolvedUnitResult) {
|
|
for (final rule in rules) {
|
|
rule.applyTo(unit);
|
|
}
|
|
} else {
|
|
analyzerErrors.add(
|
|
'Analyzer error: file $unit could not be resolved. Expected "ResolvedUnitResult", got ${unit.runtimeType}.',
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (analyzerErrors.isNotEmpty) {
|
|
foundError(analyzerErrors);
|
|
}
|
|
for (final verifier in rules) {
|
|
verifier.reportViolations(flutterRootDirectory);
|
|
}
|
|
}
|
|
|
|
/// An interface that defines a set of best practices, and collects information
|
|
/// about code that violates the best practices in a [ResolvedUnitResult].
|
|
///
|
|
/// The [analyzeWithRules] function scans and analyzes the specified
|
|
/// source directory using the dart analyzer package, and applies custom rules
|
|
/// defined in the form of this interface on each resulting [ResolvedUnitResult].
|
|
/// The [reportViolations] method will be called at the end, once all
|
|
/// [ResolvedUnitResult]s are parsed.
|
|
///
|
|
/// Implementers can assume each [ResolvedUnitResult] is valid compilable dart
|
|
/// code, as the caller only applies the custom rules once the code passes
|
|
/// `flutter analyze`.
|
|
abstract class AnalyzeRule {
|
|
/// Applies this rule to the given [ResolvedUnitResult] (typically a file), and
|
|
/// collects information about violations occurred in the compilation unit.
|
|
void applyTo(ResolvedUnitResult unit);
|
|
|
|
/// Reports all violations in the resolved compilation units [applyTo] was
|
|
/// called on, if any.
|
|
///
|
|
/// This method is called once all [ResolvedUnitResult] are parsed.
|
|
///
|
|
/// The implementation typically calls [foundErrors] to report violations.
|
|
void reportViolations(String workingDirectory);
|
|
}
|