Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Unified Diff: pkg/analyzer/lib/src/lint/linter.dart

Issue 2561573003: Revert "Move the linter core to the analyzer package" (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analyzer/lib/src/lint/io.dart ('k') | pkg/analyzer/lib/src/lint/project.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/lint/linter.dart
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
deleted file mode 100644
index 5706f35ea8d26f8d5198b2c6bea474b33e6a6250..0000000000000000000000000000000000000000
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ /dev/null
@@ -1,429 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. 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';
-
-import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/generated/engine.dart'
- show AnalysisErrorInfo, AnalysisErrorInfoImpl, Logger;
-import 'package:analyzer/src/generated/java_engine.dart' show CaughtException;
-import 'package:analyzer/src/generated/source.dart' show LineInfo;
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/lint/analysis.dart';
-import 'package:analyzer/src/lint/config.dart';
-import 'package:analyzer/src/lint/io.dart';
-import 'package:analyzer/src/lint/project.dart';
-import 'package:analyzer/src/lint/pub.dart';
-import 'package:analyzer/src/lint/registry.dart';
-import 'package:analyzer/src/services/lint.dart' show Linter;
-import 'package:glob/glob.dart';
-import 'package:path/path.dart' as p;
-
-typedef Printer(String msg);
-
-/// Describes a String in valid camel case format.
-class CamelCaseString {
- static final _camelCaseMatcher = new RegExp(r'[A-Z][a-z]*');
- static final _camelCaseTester = new RegExp(r'^([_$]*)([A-Z?$]+[a-z0-9]*)+$');
-
- final String value;
- CamelCaseString(this.value) {
- if (!isCamelCase(value)) {
- throw new ArgumentError('$value is not CamelCase');
- }
- }
-
- String get humanized => _humanize(value);
-
- @override
- String toString() => value;
-
- static bool isCamelCase(String name) => _camelCaseTester.hasMatch(name);
-
- static String _humanize(String camelCase) =>
- _camelCaseMatcher.allMatches(camelCase).map((m) => m.group(0)).join(' ');
-}
-
-/// Dart source linter.
-class DartLinter implements AnalysisErrorListener {
- final errors = <AnalysisError>[];
-
- final LinterOptions options;
- final Reporter reporter;
-
- /// The total number of sources that were analyzed. Only valid after
- /// [lintFiles] has been called.
- int numSourcesAnalyzed;
-
- /// Creates a new linter.
- DartLinter(this.options, {this.reporter: const PrintingReporter()});
-
- Iterable<AnalysisErrorInfo> lintFiles(List<File> files) {
- List<AnalysisErrorInfo> errors = [];
- var analysisDriver = new AnalysisDriver(options);
- errors.addAll(analysisDriver.analyze(files.where((f) => isDartFile(f))));
- numSourcesAnalyzed = analysisDriver.numSourcesAnalyzed;
- files.where((f) => isPubspecFile(f)).forEach((p) {
- numSourcesAnalyzed++;
- return errors.addAll(_lintPubspecFile(p));
- });
- return errors;
- }
-
- Iterable<AnalysisErrorInfo> lintPubspecSource(
- {String contents, String sourcePath}) {
- var results = <AnalysisErrorInfo>[];
-
- Uri sourceUrl = sourcePath == null ? null : p.toUri(sourcePath);
-
- var spec = new Pubspec.parse(contents, sourceUrl: sourceUrl);
-
- for (Linter lint in options.enabledLints) {
- if (lint is LintRule) {
- LintRule rule = lint;
- var visitor = rule.getPubspecVisitor();
- if (visitor != null) {
- // Analyzer sets reporters; if this file is not being analyzed,
- // we need to set one ourselves. (Needless to say, when pubspec
- // processing gets pushed down, this hack can go away.)
- if (rule.reporter == null && sourceUrl != null) {
- var source = createSource(sourceUrl);
- rule.reporter = new ErrorReporter(this, source);
- }
- try {
- spec.accept(visitor);
- } on Exception catch (e) {
- reporter.exception(new LinterException(e.toString()));
- }
- if (rule._locationInfo != null && rule._locationInfo.isNotEmpty) {
- results.addAll(rule._locationInfo);
- rule._locationInfo.clear();
- }
- }
- }
- }
-
- return results;
- }
-
- @override
- onError(AnalysisError error) => errors.add(error);
-
- Iterable<AnalysisErrorInfo> _lintPubspecFile(File sourceFile) =>
- lintPubspecSource(
- contents: sourceFile.readAsStringSync(), sourcePath: sourceFile.path);
-}
-
-class FileGlobFilter extends LintFilter {
- Iterable<Glob> includes;
- Iterable<Glob> excludes;
-
- FileGlobFilter([Iterable<String> includeGlobs, Iterable<String> excludeGlobs])
- : includes = includeGlobs.map((glob) => new Glob(glob)),
- excludes = excludeGlobs.map((glob) => new Glob(glob));
-
- @override
- bool filter(AnalysisError lint) {
- // TODO specify order
- return excludes.any((glob) => glob.matches(lint.source.fullName)) &&
- !includes.any((glob) => glob.matches(lint.source.fullName));
- }
-}
-
-class Group implements Comparable<Group> {
- /// Defined rule groups.
- static const Group errors =
- const Group._('errors', description: 'Possible coding errors.');
- static const Group pub = const Group._('pub',
- description: 'Pub-related rules.',
- link: const Hyperlink('See the <strong>Pubspec Format</strong>',
- 'https://www.dartlang.org/tools/pub/pubspec.html'));
- static const Group style = const Group._('style',
- description:
- 'Matters of style, largely derived from the official Dart Style Guide.',
- link: const Hyperlink('See the <strong>Style Guide</strong>',
- 'https://www.dartlang.org/articles/style-guide/'));
-
- /// List of builtin groups in presentation order.
- static const Iterable<Group> builtin = const [errors, style, pub];
-
- final String name;
- final bool custom;
- final String description;
- final Hyperlink link;
-
- factory Group(String name, {String description: '', Hyperlink link}) {
- var n = name.toLowerCase();
- return builtin.firstWhere((g) => g.name == n,
- orElse: () => new Group._(name,
- custom: true, description: description, link: link));
- }
-
- const Group._(this.name, {this.custom: false, this.description, this.link});
-
- @override
- int compareTo(Group other) => name.compareTo(other.name);
-}
-
-class Hyperlink {
- final String label;
- final String href;
- final bool bold;
- const Hyperlink(this.label, this.href, {this.bold: false});
- String get html => '<a href="$href">${_emph(label)}</a>';
- String _emph(msg) => bold ? '<strong>$msg</strong>' : msg;
-}
-
-/// Thrown when an error occurs in linting.
-class LinterException implements Exception {
- /// A message describing the error.
- final String message;
-
- /// Creates a new LinterException with an optional error [message].
- const LinterException([this.message]);
-
- @override
- String toString() =>
- message == null ? "LinterException" : "LinterException: $message";
-}
-
-/// Linter options.
-class LinterOptions extends DriverOptions {
- Iterable<LintRule> enabledLints;
- LintFilter filter;
- LinterOptions([this.enabledLints]) {
- enabledLints ??= Registry.ruleRegistry;
- }
- void configure(LintConfig config) {
- // TODO(pquitslund): revisit these default-to-on semantics.
- enabledLints = Registry.ruleRegistry.where((LintRule rule) =>
- !config.ruleConfigs.any((rc) => rc.disables(rule.name)));
- filter = new FileGlobFilter(config.fileIncludes, config.fileExcludes);
- }
-}
-
-/// Filtered lints are ommitted from linter output.
-abstract class LintFilter {
- bool filter(AnalysisError lint);
-}
-
-/// Describes a lint rule.
-abstract class LintRule extends Linter implements Comparable<LintRule> {
- /// Description (in markdown format) suitable for display in a detailed lint
- /// description.
- final String details;
-
- /// Short description suitable for display in console output.
- final String description;
-
- /// Lint group (for example, 'style').
- final Group group;
-
- /// Lint maturity (stable|experimental).
- final Maturity maturity;
-
- /// Lint name.
- @override
- final String name;
-
- /// Until pubspec analysis is pushed into the analyzer proper, we need to
- /// do some extra book-keeping to keep track of details that will help us
- /// constitute AnalysisErrorInfos.
- final List<AnalysisErrorInfo> _locationInfo = <AnalysisErrorInfo>[];
-
- LintRule(
- {this.name,
- this.group,
- this.description,
- this.details,
- this.maturity: Maturity.stable});
-
- LintCode get lintCode => new _LintCode(name, description);
-
- @override
- int compareTo(LintRule other) {
- var g = group.compareTo(other.group);
- if (g != 0) {
- return g;
- }
- return name.compareTo(other.name);
- }
-
- /// Return a visitor to be passed to provide access to Dart project context
- /// and to perform project-level analyses.
- ProjectVisitor getProjectVisitor() => null;
-
- /// Return a visitor to be passed to pubspecs to perform lint
- /// analysis.
- /// Lint errors are reported via this [Linter]'s error [reporter].
- PubspecVisitor getPubspecVisitor() => null;
-
- @override
- AstVisitor getVisitor() => null;
-
- void reportLint(AstNode node, {bool ignoreSyntheticNodes: true}) {
- if (node != null && (!node.isSynthetic || !ignoreSyntheticNodes)) {
- reporter.reportErrorForNode(lintCode, node, []);
- }
- }
-
- void reportLintForToken(Token token, {bool ignoreSyntheticTokens: true}) {
- if (token != null && (!token.isSynthetic || !ignoreSyntheticTokens)) {
- reporter.reportErrorForToken(lintCode, token, []);
- }
- }
-
- void reportPubLint(PSNode node) {
- Source source = createSource(node.span.sourceUrl);
-
- // Cache error and location info for creating AnalysisErrorInfos
- // Note that error columns are 1-based
- AnalysisError error = new AnalysisError(
- source, node.span.start.column + 1, node.span.length, lintCode);
- LineInfo lineInfo = new LineInfo.fromContent(source.contents.data);
-
- _locationInfo.add(new AnalysisErrorInfoImpl([error], lineInfo));
-
- // Then do the reporting
- reporter?.reportError(error);
- }
-}
-
-class Maturity implements Comparable<Maturity> {
- static const Maturity stable = const Maturity._('stable', ordinal: 0);
- static const Maturity experimental = const Maturity._('stable', ordinal: 1);
-
- final String name;
- final int ordinal;
-
- factory Maturity(String name, {int ordinal}) {
- switch (name.toLowerCase()) {
- case 'stable':
- return stable;
- case 'experimental':
- return experimental;
- default:
- return new Maturity._(name, ordinal: ordinal);
- }
- }
-
- const Maturity._(this.name, {this.ordinal});
-
- @override
- int compareTo(Maturity other) => this.ordinal - other.ordinal;
-}
-
-class PrintingReporter implements Reporter, Logger {
- final Printer _print;
-
- const PrintingReporter([this._print = print]);
-
- @override
- void exception(LinterException exception) {
- _print('EXCEPTION: $exception');
- }
-
- @override
- void logError(String message, [CaughtException exception]) {
- _print('ERROR: $message');
- }
-
- @override
- void logInformation(String message, [CaughtException exception]) {
- _print('INFO: $message');
- }
-
- @override
- void warn(String message) {
- _print('WARN: $message');
- }
-}
-
-abstract class Reporter {
- void exception(LinterException exception);
- void warn(String message);
-}
-
-/// Linter implementation.
-class SourceLinter implements DartLinter, AnalysisErrorListener {
- @override
- final errors = <AnalysisError>[];
- @override
- final LinterOptions options;
- @override
- final Reporter reporter;
-
- @override
- int numSourcesAnalyzed;
-
- SourceLinter(this.options, {this.reporter: const PrintingReporter()});
-
- @override
- Iterable<AnalysisErrorInfo> lintFiles(List<File> files) {
- List<AnalysisErrorInfo> errors = [];
- var analysisDriver = new AnalysisDriver(options);
- errors.addAll(analysisDriver.analyze(files.where((f) => isDartFile(f))));
- numSourcesAnalyzed = analysisDriver.numSourcesAnalyzed;
- files.where((f) => isPubspecFile(f)).forEach((p) {
- numSourcesAnalyzed++;
- return errors.addAll(_lintPubspecFile(p));
- });
- return errors;
- }
-
- @override
- Iterable<AnalysisErrorInfo> lintPubspecSource(
- {String contents, String sourcePath}) {
- var results = <AnalysisErrorInfo>[];
-
- Uri sourceUrl = sourcePath == null ? null : p.toUri(sourcePath);
-
- var spec = new Pubspec.parse(contents, sourceUrl: sourceUrl);
-
- for (Linter lint in options.enabledLints) {
- if (lint is LintRule) {
- LintRule rule = lint;
- var visitor = rule.getPubspecVisitor();
- if (visitor != null) {
- // Analyzer sets reporters; if this file is not being analyzed,
- // we need to set one ourselves. (Needless to say, when pubspec
- // processing gets pushed down, this hack can go away.)
- if (rule.reporter == null && sourceUrl != null) {
- var source = createSource(sourceUrl);
- rule.reporter = new ErrorReporter(this, source);
- }
- try {
- spec.accept(visitor);
- } on Exception catch (e) {
- reporter.exception(new LinterException(e.toString()));
- }
- if (rule._locationInfo != null && rule._locationInfo.isNotEmpty) {
- results.addAll(rule._locationInfo);
- rule._locationInfo.clear();
- }
- }
- }
- }
-
- return results;
- }
-
- @override
- onError(AnalysisError error) => errors.add(error);
-
- @override
- Iterable<AnalysisErrorInfo> _lintPubspecFile(File sourceFile) =>
- lintPubspecSource(
- contents: sourceFile.readAsStringSync(), sourcePath: sourceFile.path);
-}
-
-class _LintCode extends LintCode {
- static final registry = <String, LintCode>{};
-
- factory _LintCode(String name, String message) => registry.putIfAbsent(
- name + message, () => new _LintCode._(name, message));
-
- _LintCode._(String name, String message) : super(name, message);
-}
« no previous file with comments | « pkg/analyzer/lib/src/lint/io.dart ('k') | pkg/analyzer/lib/src/lint/project.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698