Skip to content

Commit

Permalink
Merge pull request #94 from dart-lang/plugin
Browse files Browse the repository at this point in the history
Plugin babysteps.
  • Loading branch information
pq committed May 12, 2015
2 parents af49276 + b9c31b7 commit 304e35b
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 0 deletions.
16 changes: 16 additions & 0 deletions lib/plugin/linter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// 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.

/// Support for client code that extends the analysis engine by adding new
/// lint rules.
library analyzer.plugin.linter;

import 'package:linter/src/linter.dart';
import 'package:linter/src/plugin/linter_plugin.dart';
import 'package:plugin/plugin.dart';

/// The identifier of the extension point that allows plugins to register new
/// lints. The object used as an extension must implement [LintRule].
final String LINT_RULE_EXTENSION_POINT_ID = Plugin.join(
LinterPlugin.UNIQUE_IDENTIFIER, LinterPlugin.LINT_RULE_EXTENSION_POINT);
76 changes: 76 additions & 0 deletions lib/src/plugin/linter_plugin.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// 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.

library linter.src.plugin.linter_plugin;

import 'package:linter/plugin/linter.dart';
import 'package:linter/src/linter.dart';
import 'package:linter/src/rules/camel_case_types.dart';
import 'package:linter/src/rules/constant_identifier_names.dart';
import 'package:linter/src/rules/empty_constructor_bodies.dart';
import 'package:linter/src/rules/library_names.dart';
import 'package:linter/src/rules/library_prefixes.dart';
import 'package:linter/src/rules/non_constant_identifier_names.dart';
import 'package:linter/src/rules/one_member_abstracts.dart';
import 'package:linter/src/rules/slash_for_doc_comments.dart';
import 'package:linter/src/rules/super_goes_last.dart';
import 'package:linter/src/rules/type_init_formals.dart';
import 'package:linter/src/rules/unnecessary_brace_in_string_interp.dart';
import 'package:plugin/plugin.dart';

/// The shared linter plugin instance.
final LinterPlugin linterPlugin = new LinterPlugin();

/// A plugin that defines the extension points and extensions that are
/// inherently defined by the linter.
class LinterPlugin implements Plugin {

/// The unique identifier of this plugin.
static const String UNIQUE_IDENTIFIER = 'linter.core';

/// The simple identifier of the extension point that allows plugins to
/// register new lint rules.
static const String LINT_RULE_EXTENSION_POINT = 'rule';

/// The extension point that allows plugins to register new lint rules.
ExtensionPoint lintRuleExtensionPoint;

/// Return a list containing all contributed lint rules.
List<LintRule> get lintRules => lintRuleExtensionPoint.extensions;

@override
String get uniqueIdentifier => UNIQUE_IDENTIFIER;

@override
void registerExtensionPoints(RegisterExtensionPoint registerExtensionPoint) {
lintRuleExtensionPoint = registerExtensionPoint(
LINT_RULE_EXTENSION_POINT, _validateTaskExtension);
}

@override
void registerExtensions(RegisterExtension registerExtension) {
/// A subset of rules that we are considering enabled by "default".
[
new CamelCaseTypes(),
new ConstantIdentifierNames(),
new EmptyConstructorBodies(),
new LibraryNames(),
new LibraryPrefixes(),
new NonConstantIdentifierNames(),
new OneMemberAbstracts(),
new SlashForDocComments(),
new SuperGoesLast(),
new TypeInitFormals(),
new UnnecessaryBraceInStringInterp()
].forEach((LintRule rule) =>
registerExtension(LINT_RULE_EXTENSION_POINT_ID, rule));
}

void _validateTaskExtension(Object extension) {
if (extension is! LintRule) {
String id = lintRuleExtensionPoint.uniqueIdentifier;
throw new ExtensionError('Extensions to $id must implement LintRule');
}
}
}
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ dependencies:
args: '>=0.12.1 <0.14.0'
cli_util: '>=0.0.1 <0.1.0'
glob: '>=1.0.3 <2.0.0'
plugin: '<0.2.0'
source_span: '>=1.0.2 <2.0.0'
yaml: '>=2.1.2 <3.0.0'
dev_dependencies:
Expand Down
31 changes: 31 additions & 0 deletions test/linter_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ import 'package:linter/src/analysis.dart';
import 'package:linter/src/ast.dart';
import 'package:linter/src/io.dart';
import 'package:linter/src/linter.dart';
import 'package:linter/src/plugin/linter_plugin.dart';
import 'package:linter/src/pub.dart';
import 'package:linter/src/rules.dart';
import 'package:linter/src/rules/camel_case_types.dart';
import 'package:linter/src/rules/package_prefixed_library_names.dart';
import 'package:linter/src/util.dart';
import 'package:mockito/mockito.dart';
import 'package:path/path.dart' as p;
import 'package:plugin/manager.dart';
import 'package:unittest/unittest.dart';

import '../bin/linter.dart' as dartlint;
Expand All @@ -33,6 +35,7 @@ main() {

defineSanityTests();
defineLinterEngineTests();
definePluginTests();
defineRuleTests();
defineRuleUnitTests();
}
Expand Down Expand Up @@ -255,6 +258,34 @@ void defineLinterEngineTests() {
});
}

/// Default contributed lint rules.
var builtinRules = [
'camel_case_types',
'constant_identifier_names',
'empty_constructor_bodies',
'library_names',
'library_prefixes',
'non_constant_identifier_names',
'one_member_abstracts',
'slash_for_doc_comments',
'super_goes_last',
'type_init_formals',
'unnecessary_brace_in_string_interp'
];

/// Plugin tests
definePluginTests() {
group('plugin', () {
test('contributed rules', () {
LinterPlugin linterPlugin = new LinterPlugin();
ExtensionManager manager = new ExtensionManager();
manager.processPlugins([linterPlugin]);
var contributedRules = linterPlugin.lintRules.map((rule) => rule.name);
expect(contributedRules, unorderedEquals(builtinRules));
});
});
}

/// Rule tests
defineRuleTests() {

Expand Down

0 comments on commit 304e35b

Please sign in to comment.