diff --git a/DEPS b/DEPS index a91a88f63fdf..affb687df48f 100644 --- a/DEPS +++ b/DEPS @@ -73,7 +73,7 @@ vars = { "isolate_tag": "@0.2.3", "jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1", "json_rpc_2_tag": "@2.0.2", - "linter_rev": "@17870d56361a95831e1ab32c82a0851ffe34c82b", + "linter_rev": "@b2d95da1287e27d4dbb9bd199dd2d23d650bd274", "logging_tag": "@0.11.3+1", "markdown_tag": "@0.11.0", "matcher_tag": "@0.12.0+2", diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart index 21a7fccaba43..4333b45473bf 100644 --- a/pkg/analysis_server/lib/src/context_manager.dart +++ b/pkg/analysis_server/lib/src/context_manager.dart @@ -30,13 +30,13 @@ import 'package:analyzer/src/generated/java_io.dart'; import 'package:analyzer/src/generated/sdk.dart'; import 'package:analyzer/src/generated/source.dart'; import 'package:analyzer/src/generated/source_io.dart'; -import 'package:analyzer/src/lint/config.dart'; -import 'package:analyzer/src/lint/linter.dart'; -import 'package:analyzer/src/lint/registry.dart'; import 'package:analyzer/src/task/options.dart'; import 'package:analyzer/src/util/absolute_path.dart'; import 'package:analyzer/src/util/glob.dart'; import 'package:analyzer/src/util/yaml.dart'; +import 'package:linter/src/config.dart'; +import 'package:linter/src/linter.dart'; +import 'package:linter/src/rules.dart'; import 'package:package_config/packages.dart'; import 'package:package_config/packages_file.dart' as pkgfile show parse; import 'package:package_config/src/packages_impl.dart' show MapPackages; @@ -714,7 +714,7 @@ class ContextManagerImpl implements ContextManager { var lintOptions = options['linter']; if (lintOptions != null) { LintConfig config = new LintConfig.parseMap(lintOptions); - Iterable lintRules = Registry.ruleRegistry.enabled(config); + Iterable lintRules = ruleRegistry.enabled(config); if (lintRules.isNotEmpty) { analysisOptions.lint = true; analysisOptions.lintRules = lintRules.toList(); diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart index f0bf43879e50..2f180ee61aee 100644 --- a/pkg/analysis_server/lib/src/server/driver.dart +++ b/pkg/analysis_server/lib/src/server/driver.dart @@ -26,7 +26,6 @@ import 'package:analyzer/src/generated/incremental_logger.dart'; import 'package:analyzer/src/generated/sdk.dart'; import 'package:args/args.dart'; import 'package:linter/src/plugin/linter_plugin.dart'; -import 'package:linter/src/rules.dart' as linter; import 'package:plugin/manager.dart'; import 'package:plugin/plugin.dart'; @@ -425,7 +424,6 @@ class Driver implements ServerStarter { plugins.addAll(_userDefinedPlugins); ExtensionManager manager = new ExtensionManager(); manager.processPlugins(plugins); - linter.registerLintRules(); String defaultSdkPath; if (results[SDK_OPTION] != null) { diff --git a/pkg/analysis_server/lib/src/services/linter/linter.dart b/pkg/analysis_server/lib/src/services/linter/linter.dart index 89dd0c849da9..964c238d0487 100644 --- a/pkg/analysis_server/lib/src/services/linter/linter.dart +++ b/pkg/analysis_server/lib/src/services/linter/linter.dart @@ -6,7 +6,7 @@ library services.src.linter; import 'package:analyzer/analyzer.dart'; import 'package:analyzer/plugin/options.dart'; -import 'package:analyzer/src/lint/registry.dart'; +import 'package:linter/src/rules.dart'; import 'package:yaml/yaml.dart'; /** @@ -38,8 +38,7 @@ class LinterRuleOptionsValidator extends OptionsValidator { validateRules(dynamic rules, ErrorReporter reporter) { if (rules is YamlList) { //TODO(pq): migrate this to a proper API once there is one. - Iterable registeredLints = - Registry.ruleRegistry.map((r) => r.name); + Iterable registeredLints = ruleRegistry.map((r) => r.name); rules.nodes.forEach((YamlNode ruleNode) { Object value = ruleNode.value; if (value != null && !registeredLints.contains(value)) { diff --git a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart index 89f720363632..7d08f0f868b5 100644 --- a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart +++ b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart @@ -9,7 +9,6 @@ import 'package:analysis_server/src/constants.dart'; import 'package:analysis_server/src/domain_analysis.dart'; import 'package:analyzer/src/generated/engine.dart'; import 'package:analyzer/src/services/lint.dart'; -import 'package:linter/src/rules.dart'; import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; @@ -75,7 +74,6 @@ analyzer: @override void setUp() { - registerLintRules(); super.setUp(); server.handlers = [new AnalysisDomainHandler(server)]; } diff --git a/pkg/analysis_server/test/analysis/notification_errors_test.dart b/pkg/analysis_server/test/analysis/notification_errors_test.dart index 96d165e33fa4..6dfc5013461c 100644 --- a/pkg/analysis_server/test/analysis/notification_errors_test.dart +++ b/pkg/analysis_server/test/analysis/notification_errors_test.dart @@ -10,8 +10,8 @@ import 'package:analysis_server/src/context_manager.dart'; import 'package:analysis_server/src/domain_analysis.dart'; import 'package:analyzer/src/dart/analysis/driver.dart'; import 'package:analyzer/src/generated/engine.dart'; -import 'package:analyzer/src/lint/linter.dart'; import 'package:analyzer/src/services/lint.dart'; +import 'package:linter/src/linter.dart'; import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart index 16170378c964..c95252b21a13 100644 --- a/pkg/analysis_server/test/context_manager_test.dart +++ b/pkg/analysis_server/test/context_manager_test.dart @@ -22,7 +22,6 @@ import 'package:analyzer/src/generated/source_io.dart'; import 'package:analyzer/src/services/lint.dart'; import 'package:analyzer/src/util/glob.dart'; import 'package:linter/src/plugin/linter_plugin.dart'; -import 'package:linter/src/rules.dart'; import 'package:linter/src/rules/avoid_as.dart'; import 'package:path/path.dart' as path; import 'package:plugin/manager.dart'; @@ -1783,8 +1782,6 @@ abstract class ContextManagerTest { plugins.add(linterPlugin); ExtensionManager manager = new ExtensionManager(); manager.processPlugins(plugins); - - registerLintRules(); } UriResolver providePackageResolver(Folder folder) => packageResolver; diff --git a/pkg/analysis_server/test/services/linter/linter_test.dart b/pkg/analysis_server/test/services/linter/linter_test.dart index bbe930472151..5ac1339213bb 100644 --- a/pkg/analysis_server/test/services/linter/linter_test.dart +++ b/pkg/analysis_server/test/services/linter/linter_test.dart @@ -9,7 +9,6 @@ import 'package:analyzer/analyzer.dart'; import 'package:analyzer/source/analysis_options_provider.dart'; import 'package:analyzer/src/generated/engine.dart'; import 'package:analyzer/src/generated/source.dart'; -import 'package:linter/src/rules.dart'; import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; @@ -30,7 +29,6 @@ class LinterRuleOptionsValidatorTest { List get errors => recorder.errors; setUp() { - registerLintRules(); recorder = new RecordingErrorListener(); reporter = new ErrorReporter(recorder, new _TestSource()); } diff --git a/pkg/analyzer/lib/src/lint/analysis.dart b/pkg/analyzer/lib/src/lint/analysis.dart deleted file mode 100644 index f779e5451bfc..000000000000 --- a/pkg/analyzer/lib/src/lint/analysis.dart +++ /dev/null @@ -1,262 +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:collection'; -import 'dart:io' as io; - -import 'package:analyzer/dart/element/element.dart'; -import 'package:analyzer/file_system/file_system.dart' - show File, Folder, ResourceProvider, ResourceUriResolver; -import 'package:analyzer/file_system/physical_file_system.dart'; -import 'package:analyzer/source/package_map_resolver.dart'; -import 'package:analyzer/src/context/builder.dart'; -import 'package:analyzer/src/dart/sdk/sdk.dart'; -import 'package:analyzer/src/generated/engine.dart'; -import 'package:analyzer/src/generated/sdk.dart'; -import 'package:analyzer/src/generated/source.dart'; -import 'package:analyzer/src/generated/source_io.dart'; -import 'package:analyzer/src/lint/io.dart'; -import 'package:analyzer/src/lint/linter.dart'; -import 'package:analyzer/src/lint/project.dart'; -import 'package:analyzer/src/lint/registry.dart'; -import 'package:analyzer/src/services/lint.dart'; -import 'package:cli_util/cli_util.dart' as cli_util; -import 'package:package_config/packages.dart' show Packages; -import 'package:package_config/packages_file.dart' as pkgfile show parse; -import 'package:package_config/src/packages_impl.dart' show MapPackages; -import 'package:path/path.dart' as p; -import 'package:plugin/manager.dart'; -import 'package:plugin/plugin.dart'; - -Source createSource(Uri sourceUri) { - return PhysicalResourceProvider.INSTANCE - .getFile(sourceUri.toFilePath()) - .createSource(sourceUri); -} - -/// Print the given message and exit with the given [exitCode] -void printAndFail(String message, {int exitCode: 15}) { - print(message); - io.exit(exitCode); -} - -AnalysisOptions _buildAnalyzerOptions(DriverOptions options) { - AnalysisOptionsImpl analysisOptions = new AnalysisOptionsImpl(); - analysisOptions.strongMode = options.strongMode; - analysisOptions.hint = false; - analysisOptions.lint = options.enableLints; - analysisOptions.generateSdkErrors = options.showSdkWarnings; - analysisOptions.enableTiming = options.enableTiming; - return analysisOptions; -} - -class AnalysisDriver { - /// The sources which have been analyzed so far. This is used to avoid - /// analyzing a source more than once, and to compute the total number of - /// sources analyzed for statistics. - Set _sourcesAnalyzed = new HashSet(); - - final LinterOptions options; - - AnalysisDriver(this.options) { - _processPlugins(); - } - - /// Return the number of sources that have been analyzed so far. - int get numSourcesAnalyzed => _sourcesAnalyzed.length; - - List get resolvers { - // TODO(brianwilkerson) Use the context builder to compute all of the resolvers. - ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE; - ContextBuilder builder = new ContextBuilder(resourceProvider, null, null); - - DartSdk sdk = options.mockSdk ?? - new FolderBasedDartSdk( - resourceProvider, resourceProvider.getFolder(sdkDir)); - - List resolvers = [new DartUriResolver(sdk)]; - - if (options.packageRootPath != null) { - // TODO(brianwilkerson) After 0.30.0 is published, clean up the following. - try { - // Try to use the post 0.30.0 API. - (builder as dynamic).builderOptions.defaultPackagesDirectoryPath = - options.packageRootPath; - } catch (_) { - // If that fails, fall back to the pre 0.30.0 API. - (builder as dynamic).defaultPackagesDirectoryPath = - options.packageRootPath; - } - Map> packageMap = - builder.convertPackagesToMap(builder.createPackageMap(null)); - resolvers.add(new PackageMapUriResolver(resourceProvider, packageMap)); - } - - // File URI resolver must come last so that files inside "/lib" are - // are analyzed via "package:" URI's. - resolvers.add(new ResourceUriResolver(resourceProvider)); - return resolvers; - } - - String get sdkDir { - if (options.dartSdkPath != null) { - return options.dartSdkPath; - } - // In case no SDK has been specified, fall back to inferring it - // TODO: pass args to cli_util - return cli_util.getSdkDir().path; - } - - List analyze(Iterable files) { - AnalysisContext context = AnalysisEngine.instance.createAnalysisContext(); - context.analysisOptions = _buildAnalyzerOptions(options); - registerLinters(context); - - Packages packages = _getPackageConfig(); - - context.sourceFactory = new SourceFactory(resolvers, packages); - AnalysisEngine.instance.logger = new StdLogger(); - - List sources = []; - ChangeSet changeSet = new ChangeSet(); - for (io.File file in files) { - File sourceFile = PhysicalResourceProvider.INSTANCE - .getFile(p.normalize(file.absolute.path)); - Source source = sourceFile.createSource(); - Uri uri = context.sourceFactory.restoreUri(source); - if (uri != null) { - // Ensure that we analyze the file using its canonical URI (e.g. if - // it's in "/lib", analyze it using a "package:" URI). - source = sourceFile.createSource(uri); - } - sources.add(source); - changeSet.addedSource(source); - } - context.applyChanges(changeSet); - - // Temporary location - var project = new DartProject(context, sources); - // This will get pushed into the generator (or somewhere comparable) when - // we have a proper plugin. - Registry.ruleRegistry.forEach((lint) { - if (lint is ProjectVisitor) { - (lint as ProjectVisitor).visit(project); - } - }); - - List errors = []; - - for (Source source in sources) { - context.computeErrors(source); - errors.add(context.getErrors(source)); - _sourcesAnalyzed.add(source); - } - - if (options.visitTransitiveClosure) { - // In the process of computing errors for all the sources in [sources], - // the analyzer has visited the transitive closure of all libraries - // referenced by those sources. So now we simply need to visit all - // library sources known to the analysis context, and all parts they - // refer to. - for (Source librarySource in context.librarySources) { - for (Source source in _getAllUnitSources(context, librarySource)) { - if (!_sourcesAnalyzed.contains(source)) { - context.computeErrors(source); - errors.add(context.getErrors(source)); - _sourcesAnalyzed.add(source); - } - } - } - } - - return errors; - } - - void registerLinters(AnalysisContext context) { - if (options.enableLints) { - setLints(context, options.enabledLints?.toList(growable: false)); - } - } - - /// Yield the sources for all the compilation units constituting - /// [librarySource] (including the defining compilation unit). - Iterable _getAllUnitSources( - AnalysisContext context, Source librarySource) { - List result = [librarySource]; - result.addAll(context - .getLibraryElement(librarySource) - .parts - .map((CompilationUnitElement e) => e.source)); - return result; - } - - Packages _getPackageConfig() { - if (options.packageConfigPath != null) { - String packageConfigPath = options.packageConfigPath; - Uri fileUri = new Uri.file(packageConfigPath); - try { - io.File configFile = new io.File.fromUri(fileUri).absolute; - List bytes = configFile.readAsBytesSync(); - Map map = pkgfile.parse(bytes, configFile.uri); - return new MapPackages(map); - } catch (e) { - printAndFail( - 'Unable to read package config data from $packageConfigPath: $e'); - } - } - return null; - } - - void _processPlugins() { - List plugins = []; - plugins.addAll(AnalysisEngine.instance.requiredPlugins); - plugins.add(AnalysisEngine.instance.commandLinePlugin); - plugins.add(AnalysisEngine.instance.optionsPlugin); - ExtensionManager manager = new ExtensionManager(); - manager.processPlugins(plugins); - } -} - -class DriverOptions { - /// The maximum number of sources for which AST structures should be kept - /// in the cache. The default is 512. - int cacheSize = 512; - - /// The path to the dart SDK. - String dartSdkPath; - - /// Whether to show lint warnings. - bool enableLints = true; - - /// Whether to gather timing data during analysis. - bool enableTiming = false; - - /// The path to a `.packages` configuration file - String packageConfigPath; - - /// The path to the package root. - String packageRootPath; - - /// Whether to show SDK warnings. - bool showSdkWarnings = false; - - /// Whether to use Dart's Strong Mode analyzer. - bool strongMode = true; - - /// The mock SDK (to speed up testing) or `null` to use the actual SDK. - DartSdk mockSdk; - - /// Whether to show lints for the transitive closure of imported and exported - /// libraries. - bool visitTransitiveClosure = false; -} - -/// Prints logging information comments to the [outSink] and error messages to -/// [errorSink]. -class StdLogger extends Logger { - @override - void logError(String message, [exception]) => errorSink.writeln(message); - @override - void logInformation(String message, [exception]) => outSink.writeln(message); -} diff --git a/pkg/analyzer/lib/src/lint/config.dart b/pkg/analyzer/lib/src/lint/config.dart deleted file mode 100644 index f33b3f3392b7..000000000000 --- a/pkg/analyzer/lib/src/lint/config.dart +++ /dev/null @@ -1,243 +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 'package:yaml/yaml.dart'; - -/** - * Parse the given map into a lint config. - */ -LintConfig parseConfig(Map optionsMap) { - if (optionsMap != null) { - var options = optionsMap['linter']; - // Quick check of basic contract. - if (options is Map) { - return new LintConfig.parseMap(options); - } - } - return null; -} - -/** - * Process the given option [fileContents] and produce a corresponding - * [LintConfig]. - */ -LintConfig processAnalysisOptionsFile(String fileContents, {String fileUrl}) { - var yaml = loadYamlNode(fileContents, sourceUrl: fileUrl); - if (yaml is YamlMap) { - return parseConfig(yaml); - } - return null; -} - -/** - * The configuration of lint rules within an analysis options file. - */ -abstract class LintConfig { - factory LintConfig.parse(String source, {String sourceUrl}) => - new _LintConfig().._parse(source, sourceUrl: sourceUrl); - - factory LintConfig.parseMap(Map map) => new _LintConfig().._parseMap(map); - - List get fileExcludes; - List get fileIncludes; - List get ruleConfigs; -} - -/** - * The configuration of a single lint rule within an analysis options file. - */ -abstract class RuleConfig { - Map args = {}; - String get group; - String get name; - - // Provisional - bool disables(String ruleName) => - ruleName == name && args['enabled'] == false; - - bool enables(String ruleName) => ruleName == name && args['enabled'] == true; -} - -class _LintConfig implements LintConfig { - @override - final fileIncludes = []; - @override - final fileExcludes = []; - @override - final ruleConfigs = []; - - void addAsListOrString(value, List list) { - if (value is List) { - value.forEach((v) => list.add(v)); - } else if (value is String) { - list.add(value); - } - } - - bool asBool(scalar) { - if (scalar is bool) { - return scalar; - } - if (scalar is String) { - if (scalar == 'true') { - return true; - } - if (scalar == 'false') { - return false; - } - } - return null; - } - - String asString(scalar) { - if (scalar is String) { - return scalar; - } - return null; - } - - Map parseArgs(args) { - bool enabled = asBool(args); - if (enabled != null) { - return {'enabled': enabled}; - } - return null; - } - - void _parse(String src, {String sourceUrl}) { - var yaml = loadYamlNode(src, sourceUrl: sourceUrl); - if (yaml is YamlMap) { - _parseYaml(yaml); - } - } - - void _parseMap(Map options) { - //TODO(pq): unify map parsing. - if (options is YamlMap) { - _parseYaml(options); - } else { - _parseRawMap(options); - } - } - - void _parseRawMap(Map options) { - options.forEach((k, v) { - if (k is! String) { - return; - } - String key = k; - switch (key) { - case 'files': - if (v is Map) { - addAsListOrString(v['include'], fileIncludes); - addAsListOrString(v['exclude'], fileExcludes); - } - break; - - case 'rules': - // - unnecessary_getters - // - camel_case_types - if (v is List) { - v.forEach((rule) { - var config = new _RuleConfig(); - config.name = asString(rule); - config.args = {'enabled': true}; - ruleConfigs.add(config); - }); - } - - // {unnecessary_getters: false, camel_case_types: true} - if (v is Map) { - v.forEach((key, value) { - // style_guide: {unnecessary_getters: false, camel_case_types: true} - if (value is Map) { - value.forEach((rule, args) { - // unnecessary_getters: false - var config = new _RuleConfig(); - config.group = key; - config.name = asString(rule); - config.args = parseArgs(args); - ruleConfigs.add(config); - }); - } else { - //{unnecessary_getters: false} - value = asBool(value); - if (value != null) { - var config = new _RuleConfig(); - config.name = asString(key); - config.args = {'enabled': value}; - ruleConfigs.add(config); - } - } - }); - } - break; - } - }); - } - - void _parseYaml(YamlMap yaml) { - yaml.nodes.forEach((k, v) { - if (k is! YamlScalar) { - return; - } - YamlScalar key = k; - switch (key.toString()) { - case 'files': - if (v is YamlMap) { - addAsListOrString(v['include'], fileIncludes); - addAsListOrString(v['exclude'], fileExcludes); - } - break; - - case 'rules': - - // - unnecessary_getters - // - camel_case_types - if (v is List) { - (v as List).forEach((rule) { - var config = new _RuleConfig(); - config.name = asString(rule); - config.args = {'enabled': true}; - ruleConfigs.add(config); - }); - } - - // style_guide: {unnecessary_getters: false, camel_case_types: true} - if (v is YamlMap) { - v.forEach((key, value) { - //{unnecessary_getters: false} - if (value is bool) { - var config = new _RuleConfig(); - config.name = asString(key); - config.args = {'enabled': value}; - ruleConfigs.add(config); - } - - // style_guide: {unnecessary_getters: false, camel_case_types: true} - if (value is YamlMap) { - value.forEach((rule, args) { - // TODO: verify format - // unnecessary_getters: false - var config = new _RuleConfig(); - config.group = key; - config.name = asString(rule); - config.args = parseArgs(args); - ruleConfigs.add(config); - }); - } - }); - } - break; - } - }); - } -} - -class _RuleConfig extends RuleConfig { - @override - String group; - @override - String name; -} diff --git a/pkg/analyzer/lib/src/lint/io.dart b/pkg/analyzer/lib/src/lint/io.dart deleted file mode 100644 index 762ee93d0b38..000000000000 --- a/pkg/analyzer/lib/src/lint/io.dart +++ /dev/null @@ -1,68 +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/src/lint/util.dart'; -import 'package:glob/glob.dart'; -import 'package:path/path.dart' as p; - -final dartMatcher = new Glob('**.dart'); - -/// Shared IO sink for standard error reporting. -/// Visible for testing -IOSink errorSink = stderr; - -/// Shared IO sink for standard out reporting. -/// Visible for testing -IOSink outSink = stdout; - -/// Cached project package. -String _projectPackageName; - -/// Cached project root. -String _projectRoot; - -/// Collect all lintable files, recursively, under this [path] root, ignoring -/// links. -Iterable collectFiles(String path) { - List files = []; - - var file = new File(path); - if (file.existsSync()) { - files.add(file); - } else { - var directory = new Directory(path); - if (directory.existsSync()) { - for (var entry - in directory.listSync(recursive: true, followLinks: false)) { - var relative = p.relative(entry.path, from: directory.path); - - if (isLintable(entry) && !isInHiddenDir(relative)) { - files.add(entry); - } - } - } - } - - return files; -} - -/// Returns `true` if this [entry] is a Dart file. -bool isDartFile(FileSystemEntity entry) => isDartFileName(entry.path); - -/// Returns `true` if this relative path is a hidden directory. -bool isInHiddenDir(String relative) => - p.split(relative).any((part) => part.startsWith(".")); - -/// Returns `true` if this relative path is a hidden directory. -bool isLintable(FileSystemEntity file) => - file is File && (isDartFile(file) || isPubspecFile(file)); - -/// Returns `true` if this [entry] is a pubspec file. -bool isPubspecFile(FileSystemEntity entry) => - isPubspecFileName(p.basename(entry.path)); - -/// Synchronously read the contents of the file at the given [path] as a string. -String readFile(String path) => new File(path).readAsStringSync(); diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart deleted file mode 100644 index 5706f35ea8d2..000000000000 --- 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 = []; - - 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 lintFiles(List files) { - List 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 lintPubspecSource( - {String contents, String sourcePath}) { - var results = []; - - 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 _lintPubspecFile(File sourceFile) => - lintPubspecSource( - contents: sourceFile.readAsStringSync(), sourcePath: sourceFile.path); -} - -class FileGlobFilter extends LintFilter { - Iterable includes; - Iterable excludes; - - FileGlobFilter([Iterable includeGlobs, Iterable 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 { - /// 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 Pubspec Format', - '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 Style Guide', - 'https://www.dartlang.org/articles/style-guide/')); - - /// List of builtin groups in presentation order. - static const Iterable 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 => '${_emph(label)}'; - String _emph(msg) => bold ? '$msg' : 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 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 { - /// 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 _locationInfo = []; - - 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 { - 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 = []; - @override - final LinterOptions options; - @override - final Reporter reporter; - - @override - int numSourcesAnalyzed; - - SourceLinter(this.options, {this.reporter: const PrintingReporter()}); - - @override - Iterable lintFiles(List files) { - List 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 lintPubspecSource( - {String contents, String sourcePath}) { - var results = []; - - 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 _lintPubspecFile(File sourceFile) => - lintPubspecSource( - contents: sourceFile.readAsStringSync(), sourcePath: sourceFile.path); -} - -class _LintCode extends LintCode { - static final registry = {}; - - factory _LintCode(String name, String message) => registry.putIfAbsent( - name + message, () => new _LintCode._(name, message)); - - _LintCode._(String name, String message) : super(name, message); -} diff --git a/pkg/analyzer/lib/src/lint/project.dart b/pkg/analyzer/lib/src/lint/project.dart deleted file mode 100644 index 9b22294e15c0..000000000000 --- a/pkg/analyzer/lib/src/lint/project.dart +++ /dev/null @@ -1,129 +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/dart/element/element.dart'; -import 'package:analyzer/src/generated/engine.dart'; -import 'package:analyzer/src/generated/resolver.dart'; -import 'package:analyzer/src/generated/source.dart'; -import 'package:analyzer/src/lint/io.dart'; -import 'package:analyzer/src/lint/pub.dart'; -import 'package:path/path.dart' as p; - -Pubspec _findAndParsePubspec(Directory root) { - if (root.existsSync()) { - File pubspec = root - .listSync(followLinks: false) - .firstWhere((f) => isPubspecFile(f), orElse: () => null); - if (pubspec != null) { - return new Pubspec.parse(pubspec.readAsStringSync(), - sourceUrl: p.toUri(pubspec.path)); - } - } - return null; -} - -/// A semantic representation of a Dart project. -/// -/// Projects provide a semantic model of a Dart project based on the -/// [pub package layout conventions](https://www.dartlang.org/tools/pub/package-layout.html). -/// This model allows clients to traverse project contents in a convenient and -/// standardized way, access global information (such as whether elements are -/// in the "public API") and resources that have special meanings in the -/// context of pub package layout conventions. -class DartProject { - _ApiModel _apiModel; - String _name; - Pubspec _pubspec; - - /// Project root. - final Directory root; - - /// Create a Dart project for the corresponding [context] and [sources]. - /// If a [dir] is unspecified the current working directory will be - /// used. - DartProject(AnalysisContext context, List sources, {Directory dir}) - : root = dir ?? Directory.current { - _pubspec = _findAndParsePubspec(root); - _apiModel = new _ApiModel(context, sources, root); - } - - /// The project's name. - /// - /// Project names correspond to the package name as specified in the project's - /// [pubspec]. The pubspec is found relative to the project [root]. If no - /// pubspec can be found, the name defaults to the project root basename. - String get name => _name ??= _calculateName(); - - /// The project's pubspec. - Pubspec get pubspec => _pubspec; - - /// Returns `true` if the given element is part of this project's public API. - /// - /// Public API elements are defined as all elements that are in the packages's - /// `lib` directory, *less* those in `lib/src` (which are treated as private - /// *implementation files*), plus elements having been explicitly exported - /// via an `export` directive. - bool isApi(Element element) => _apiModel.contains(element); - - String _calculateName() { - if (pubspec != null) { - var nameEntry = pubspec.name; - if (nameEntry != null) { - return nameEntry.value.text; - } - } - return p.basename(root.path); - } -} - -/// An object that can be used to visit Dart project structure. -abstract class ProjectVisitor { - T visit(DartProject project) => null; -} - -/// Captures the project's API as defined by pub package layout standards. -class _ApiModel { - final AnalysisContext context; - final List sources; - final Directory root; - final Set elements = new Set(); - - _ApiModel(this.context, this.sources, this.root) { - _calculate(); - } - - /// Return `true` if this element is part of the public API for this package. - bool contains(Element element) { - while (element != null) { - if (!element.isPrivate && elements.contains(element)) { - return true; - } - element = element.enclosingElement; - } - return false; - } - - _calculate() { - if (sources == null || sources.isEmpty) { - return; - } - - var libDir = root.path + '/lib'; - var libSrcDir = libDir + '/src'; - - for (Source source in sources) { - var path = source.uri.path; - if (path.startsWith(libDir) && !path.startsWith(libSrcDir)) { - var library = context.computeLibraryElement(source); - var namespaceBuilder = new NamespaceBuilder(); - var exports = namespaceBuilder.createExportNamespaceForLibrary(library); - var public = namespaceBuilder.createPublicNamespaceForLibrary(library); - elements.addAll(exports.definedNames.values); - elements.addAll(public.definedNames.values); - } - } - } -} diff --git a/pkg/analyzer/lib/src/lint/pub.dart b/pkg/analyzer/lib/src/lint/pub.dart deleted file mode 100644 index 8d12e134bb54..000000000000 --- a/pkg/analyzer/lib/src/lint/pub.dart +++ /dev/null @@ -1,430 +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:collection'; - -import 'package:source_span/source_span.dart'; -import 'package:yaml/yaml.dart'; - -PSEntry _findEntry(YamlMap map, String key) { - PSEntry entry; - map.nodes.forEach((k, v) { - if (k is YamlScalar && key == k.toString()) { - entry = _processScalar(k, v); - } - }); - return entry; -} - -PSDependencyList _processDependencies(YamlScalar key, YamlNode v) { - if (v is! YamlMap) { - return null; - } - YamlMap depsMap = v; - - _PSDependencyList deps = new _PSDependencyList(new _PSNode(key)); - depsMap.nodes.forEach((k, v) => deps.add(new _PSDependency(k, v))); - return deps; -} - -PSGitRepo _processGitRepo(YamlScalar key, YamlNode v) { - if (v is! YamlMap) { - return null; - } - YamlMap hostMap = v; - // url: git://github.com/munificent/kittens.git - // ref: some-branch - _PSGitRepo repo = new _PSGitRepo(); - repo.token = new _PSNode(key); - repo.ref = _findEntry(hostMap, 'ref'); - repo.url = _findEntry(hostMap, 'url'); - return repo; -} - -PSHost _processHost(YamlScalar key, YamlNode v) { - if (v is! YamlMap) { - return null; - } - YamlMap hostMap = v; - // name: transmogrify - // url: http://your-package-server.com - _PSHost host = new _PSHost(); - host.token = new _PSNode(key); - host.name = _findEntry(hostMap, 'name'); - host.url = _findEntry(hostMap, 'url'); - return host; -} - -PSNodeList _processList(YamlScalar key, YamlNode v) { - if (v is! YamlList) { - return null; - } - YamlList nodeList = v; - - return new _PSNodeList( - new _PSNode(key), nodeList.nodes.map((n) => new _PSNode(n))); -} - -PSEntry _processScalar(YamlScalar key, YamlNode value) { - if (value is! YamlScalar) { - return null; - //WARN? - } - return new PSEntry(new _PSNode(key), new _PSNode(value)); -} - -abstract class PSDependency { - PSGitRepo get git; - PSHost get host; - PSNode get name; - PSEntry get version; -} - -abstract class PSDependencyList extends Object - with IterableMixin {} - -class PSEntry { - final PSNode key; - final PSNode value; - PSEntry(this.key, this.value); - - @override - String toString() => '${key != null ? (key.toString() + ': ') : ''}$value'; -} - -abstract class PSGitRepo { - PSEntry get ref; - PSNode get token; - PSEntry get url; -} - -abstract class PSHost { - PSEntry get name; - PSNode get token; - PSEntry get url; -} - -abstract class PSNode { - SourceSpan get span; - String get text; -} - -abstract class PSNodeList extends Object with IterableMixin { - @override - Iterator get iterator; - PSNode get token; -} - -abstract class Pubspec { - factory Pubspec.parse(String source, {Uri sourceUrl}) => - new _Pubspec(source, sourceUrl: sourceUrl); - PSEntry get author; - PSNodeList get authors; - PSDependencyList get dependencies; - PSEntry get description; - PSDependencyList get devDependencies; - PSEntry get documentation; - PSEntry get homepage; - PSEntry get name; - PSEntry get version; - accept(PubspecVisitor visitor); -} - -abstract class PubspecVisitor { - T visitPackageAuthor(PSEntry author) => null; - T visitPackageAuthors(PSNodeList authors) => null; - T visitPackageDependencies(PSDependencyList dependencies) => null; - T visitPackageDependency(PSDependency dependency) => null; - T visitPackageDescription(PSEntry description) => null; - T visitPackageDevDependencies(PSDependencyList dependencies) => null; - T visitPackageDevDependency(PSDependency dependency) => null; - T visitPackageDocumentation(PSEntry documentation) => null; - T visitPackageHomepage(PSEntry homepage) => null; - T visitPackageName(PSEntry name) => null; - T visitPackageVersion(PSEntry version) => null; -} - -class _PSDependency extends PSDependency { - @override - PSNode name; - @override - PSEntry version; - @override - PSHost host; - @override - PSGitRepo git; - - factory _PSDependency(dynamic k, YamlNode v) { - if (k is! YamlScalar) { - return null; - } - YamlScalar key = k; - - _PSDependency dep = new _PSDependency._(); - - dep.name = new _PSNode(key); - - if (v is YamlScalar) { - // Simple version - dep.version = new PSEntry(null, new _PSNode(v)); - } else if (v is YamlMap) { - // hosted: - // name: transmogrify - // url: http://your-package-server.com - // version: '>=0.4.0 <1.0.0' - YamlMap details = v; - details.nodes.forEach((k, v) { - if (k is! YamlScalar) { - return; - } - YamlScalar key = k; - switch (key.toString()) { - case 'version': - dep.version = _processScalar(key, v); - break; - case 'hosted': - dep.host = _processHost(key, v); - break; - case 'git': - dep.git = _processGitRepo(key, v); - break; - } - }); - } - return dep; - } - - _PSDependency._(); - - @override - String toString() { - var sb = new StringBuffer(); - if (name != null) { - sb.write('$name:'); - } - var versionInfo = ''; - if (version != null) { - if (version.key == null) { - versionInfo = ' $version'; - } else { - versionInfo = '\n $version'; - } - } - sb.writeln(versionInfo); - if (host != null) { - sb.writeln(host); - } - if (git != null) { - sb.writeln(git); - } - return sb.toString(); - } -} - -class _PSDependencyList extends PSDependencyList { - final dependencies = []; - final PSNode token; - - _PSDependencyList(this.token); - - @override - Iterator get iterator => dependencies.iterator; - - add(PSDependency dependency) { - if (dependency != null) { - dependencies.add(dependency); - } - } - - @override - String toString() => '$token\n${dependencies.join(' ')}'; -} - -class _PSGitRepo implements PSGitRepo { - @override - PSNode token; - @override - PSEntry ref; - @override - PSEntry url; - @override - String toString() => ''' - $token: - $url - $ref'''; -} - -class _PSHost implements PSHost { - @override - PSNode token; - @override - PSEntry name; - @override - PSEntry url; - @override - String toString() => ''' - $token: - $name - $url'''; -} - -class _PSNode implements PSNode { - @override - final String text; - @override - final SourceSpan span; - - _PSNode(YamlNode node) - : text = node.value?.toString(), - span = node.span; - - @override - String toString() => '$text'; -} - -class _PSNodeList extends PSNodeList { - @override - final PSNode token; - final Iterable nodes; - - _PSNodeList(this.token, this.nodes); - - @override - Iterator get iterator => nodes.iterator; - - @override - String toString() => ''' -$token: - - ${nodes.join('\n - ')}'''; -} - -class _Pubspec implements Pubspec { - @override - PSEntry author; - @override - PSNodeList authors; - @override - PSEntry description; - @override - PSEntry documentation; - @override - PSEntry homepage; - @override - PSEntry name; - @override - PSEntry version; - @override - PSDependencyList dependencies; - @override - PSDependencyList devDependencies; - - _Pubspec(String src, {Uri sourceUrl}) { - try { - _parse(src, sourceUrl: sourceUrl); - } on Exception { - // ignore - } - } - - @override - void accept(PubspecVisitor visitor) { - if (author != null) { - visitor.visitPackageAuthor(author); - } - if (authors != null) { - visitor.visitPackageAuthors(authors); - } - if (description != null) { - visitor.visitPackageDescription(description); - } - if (documentation != null) { - visitor.visitPackageDocumentation(documentation); - } - if (homepage != null) { - visitor.visitPackageHomepage(homepage); - } - if (name != null) { - visitor.visitPackageName(name); - } - if (version != null) { - visitor.visitPackageVersion(version); - } - if (dependencies != null) { - visitor.visitPackageDependencies(dependencies); - dependencies.forEach((d) => visitor.visitPackageDependency(d)); - } - if (devDependencies != null) { - visitor.visitPackageDevDependencies(devDependencies); - devDependencies.forEach((d) => visitor.visitPackageDevDependency(d)); - } - } - - @override - String toString() { - var sb = new _StringBuilder(); - sb.writelin(name); - sb.writelin(version); - sb.writelin(author); - sb.writelin(authors); - sb.writelin(description); - sb.writelin(homepage); - sb.writelin(dependencies); - sb.writelin(devDependencies); - return sb.toString(); - } - - _parse(String src, {Uri sourceUrl}) { - var yaml = loadYamlNode(src, sourceUrl: sourceUrl); - if (yaml is! YamlMap) { - return; - } - YamlMap yamlMap = yaml; - yamlMap.nodes.forEach((k, v) { - if (k is! YamlScalar) { - return; - } - YamlScalar key = k; - switch (key.toString()) { - case 'author': - author = _processScalar(key, v); - break; - case 'authors': - authors = _processList(key, v); - break; - case 'homepage': - homepage = _processScalar(key, v); - break; - case 'name': - name = _processScalar(key, v); - break; - case 'description': - description = _processScalar(key, v); - break; - case 'documentation': - documentation = _processScalar(key, v); - break; - case 'dependencies': - dependencies = _processDependencies(key, v); - break; - case 'dev_dependencies': - devDependencies = _processDependencies(key, v); - break; - case 'version': - version = _processScalar(key, v); - break; - } - }); - } -} - -class _StringBuilder { - StringBuffer buffer = new StringBuffer(); - @override - String toString() => buffer.toString(); - writelin(Object value) { - if (value != null) { - buffer.writeln(value); - } - } -} diff --git a/pkg/analyzer/lib/src/lint/registry.dart b/pkg/analyzer/lib/src/lint/registry.dart deleted file mode 100644 index 20ce0367efcd..000000000000 --- a/pkg/analyzer/lib/src/lint/registry.dart +++ /dev/null @@ -1,42 +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:collection'; - -import 'package:analyzer/src/lint/config.dart'; -import 'package:analyzer/src/lint/linter.dart'; - -/** - * Registry of contributed lint rules. - */ -class Registry extends Object with IterableMixin { - /** - * The default registry to be used by clients. - */ - static final Registry ruleRegistry = new Registry(); - - Map _ruleMap = {}; - - @override - Iterator get iterator => _ruleMap.values.iterator; - - Iterable get rules => _ruleMap.values; - - LintRule operator [](String key) => _ruleMap[key]; - - /// All lint rules explicitly enabled by the given [config]. - /// - /// For example: - /// my_rule: true - /// - /// enables `my_rule`. - /// - /// Unspecified rules are treated as disabled by default. - Iterable enabled(LintConfig config) => rules - .where((rule) => config.ruleConfigs.any((rc) => rc.enables(rule.name))); - - void register(LintRule rule) { - _ruleMap[rule.name] = rule; - } -} diff --git a/pkg/analyzer/lib/src/lint/util.dart b/pkg/analyzer/lib/src/lint/util.dart deleted file mode 100644 index e1c63af6a62e..000000000000 --- a/pkg/analyzer/lib/src/lint/util.dart +++ /dev/null @@ -1,172 +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/dart/ast/token.dart'; -import 'package:analyzer/src/dart/scanner/reader.dart'; -import 'package:analyzer/src/dart/scanner/scanner.dart'; -import 'package:analyzer/src/generated/parser.dart' show Parser; -import 'package:analyzer/src/string_source.dart' show StringSource; -import 'package:path/path.dart' as p; - -final _identifier = new RegExp(r'^([(_|$)a-zA-Z]+([_a-zA-Z0-9])*)$'); - -final _lowerCamelCase = - new RegExp(r'^(_)*[?$a-z][a-z0-9?$]*([A-Z][a-z0-9?$]*)*$'); - -final _lowerCaseUnderScore = new RegExp(r'^([a-z]+([_]?[a-z0-9]+)*)+$'); - -final _lowerCaseUnderScoreWithDots = - new RegExp(r'^[a-z][_a-z0-9]*(\.[a-z][_a-z0-9]*)*$'); - -final _pubspec = new RegExp(r'^[_]?pubspec\.yaml$'); - -final _underscores = new RegExp(r'^[_]+$'); - -/// Create a library name prefix based on [libraryPath], [projectRoot] and -/// current [packageName]. -String createLibraryNamePrefix( - {String libraryPath, String projectRoot, String packageName}) { - // Use the posix context to canonicalize separators (`\`). - var libraryDirectory = p.posix.dirname(libraryPath); - var path = p.posix.relative(libraryDirectory, from: projectRoot); - // Drop 'lib/'. - var segments = p.split(path); - if (segments[0] == 'lib') { - path = p.posix.joinAll(segments.sublist(1)); - } - // Replace separators. - path = path.replaceAll('/', '.'); - // Add separator if needed. - if (path.isNotEmpty) { - path = '.$path'; - } - - return '$packageName$path'; -} - -/// Returns `true` if this [fileName] is a Dart file. -bool isDartFileName(String fileName) => fileName.endsWith('.dart'); - -/// Returns `true` if this [name] is a legal Dart identifier. -bool isIdentifier(String name) => _identifier.hasMatch(name); - -/// Returns `true` of the given [name] is composed only of `_`s. -bool isJustUnderscores(String name) => _underscores.hasMatch(name); - -/// Returns `true` if this [id] is `lowerCamelCase`. -bool isLowerCamelCase(String id) => - id.length == 1 && isUpperCase(id.codeUnitAt(0)) || - id == '_' || - _lowerCamelCase.hasMatch(id); - -/// Returns `true` if this [id] is `lower_camel_case_with_underscores`. -bool isLowerCaseUnderScore(String id) => _lowerCaseUnderScore.hasMatch(id); - -/// Returns `true` if this [id] is `lower_camel_case_with_underscores_or.dots`. -bool isLowerCaseUnderScoreWithDots(String id) => - _lowerCaseUnderScoreWithDots.hasMatch(id); - -/// Returns `true` if this [fileName] is a Pubspec file. -bool isPubspecFileName(String fileName) => _pubspec.hasMatch(fileName); - -/// Returns `true` if the given code unit [c] is upper case. -bool isUpperCase(int c) => c >= 0x40 && c <= 0x5A; - -class Spelunker { - final String path; - final IOSink sink; - Spelunker(this.path, {IOSink sink}) : this.sink = sink ?? stdout; - - void spelunk() { - var contents = new File(path).readAsStringSync(); - - var errorListener = new _ErrorListener(); - - var reader = new CharSequenceReader(contents); - var stringSource = new StringSource(contents, path); - var scanner = new Scanner(stringSource, reader, errorListener); - var startToken = scanner.tokenize(); - - errorListener.throwIfErrors(); - - var parser = new Parser(stringSource, errorListener); - var node = parser.parseCompilationUnit(startToken); - - errorListener.throwIfErrors(); - - var visitor = new _SourceVisitor(sink); - node.accept(visitor); - } -} - -class _ErrorListener implements AnalysisErrorListener { - final errors = []; - - @override - void onError(AnalysisError error) { - errors.add(error); - } - - void throwIfErrors() { - if (errors.isNotEmpty) { - throw new Exception(errors); - } - } -} - -class _SourceVisitor extends GeneralizingAstVisitor { - int indent = 0; - - final IOSink sink; - _SourceVisitor(this.sink); - - String asString(AstNode node) => - typeInfo(node.runtimeType) + ' [${node.toString()}]'; - - List getPrecedingComments(Token token) { - var comments = []; - var comment = token.precedingComments; - while (comment is CommentToken) { - comments.add(comment); - comment = comment.next; - } - return comments; - } - - String getTrailingComment(AstNode node) { - var successor = node.endToken.next; - if (successor != null) { - var precedingComments = successor.precedingComments; - if (precedingComments != null) { - return precedingComments.toString(); - } - } - return ''; - } - - String typeInfo(Type type) => type.toString(); - - @override - visitNode(AstNode node) { - write(node); - - ++indent; - node.visitChildren(this); - --indent; - return null; - } - - write(AstNode node) { - //EOL comments - var comments = getPrecedingComments(node.beginToken); - comments.forEach((c) => sink.writeln('${" " * indent}$c')); - - sink.writeln( - '${" " * indent}${asString(node)} ${getTrailingComment(node)}'); - } -} diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart index b29e3abd9bc3..35caf046d234 100644 --- a/pkg/analyzer_cli/lib/src/driver.dart +++ b/pkg/analyzer_cli/lib/src/driver.dart @@ -42,7 +42,6 @@ import 'package:analyzer_cli/src/options.dart'; import 'package:analyzer_cli/src/perf_report.dart'; import 'package:analyzer_cli/starter.dart'; import 'package:linter/src/plugin/linter_plugin.dart'; -import 'package:linter/src/rules.dart' as linter; import 'package:package_config/discovery.dart' as pkg_discovery; import 'package:package_config/packages.dart' show Packages; import 'package:package_config/packages_file.dart' as pkgfile show parse; @@ -624,8 +623,6 @@ class Driver implements CommandLineStarter { ExtensionManager manager = new ExtensionManager(); manager.processPlugins(plugins); - - linter.registerLintRules(); } /// Analyze a single source.