Skip to content
This repository was archived by the owner on Nov 20, 2024. It is now read-only.

Commit aa783b3

Browse files
committed
Plugin babysteps.
1 parent 81840c4 commit aa783b3

File tree

4 files changed

+126
-0
lines changed

4 files changed

+126
-0
lines changed

lib/plugin/linter.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// Support for client code that extends the analysis engine by adding new
6+
/// lint rules.
7+
library analyzer.plugin.linter;
8+
9+
import 'package:linter/src/linter.dart';
10+
import 'package:linter/src/plugin/linter_plugin.dart';
11+
import 'package:plugin/plugin.dart';
12+
13+
/// The identifier of the extension point that allows plugins to register new
14+
/// lints. The object used as an extension must implement [LintRule].
15+
final String LINT_RULE_EXTENSION_POINT_ID = Plugin.join(
16+
LinterPlugin.UNIQUE_IDENTIFIER, LinterPlugin.LINT_RULE_EXTENSION_POINT);

lib/src/plugin/linter_plugin.dart

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
library linter.src.plugin.linter_plugin;
6+
7+
import 'package:linter/plugin/linter.dart';
8+
import 'package:linter/src/linter.dart';
9+
import 'package:linter/src/rules/camel_case_types.dart';
10+
import 'package:linter/src/rules/constant_identifier_names.dart';
11+
import 'package:linter/src/rules/empty_constructor_bodies.dart';
12+
import 'package:linter/src/rules/library_names.dart';
13+
import 'package:linter/src/rules/library_prefixes.dart';
14+
import 'package:linter/src/rules/non_constant_identifier_names.dart';
15+
import 'package:linter/src/rules/one_member_abstracts.dart';
16+
import 'package:linter/src/rules/slash_for_doc_comments.dart';
17+
import 'package:linter/src/rules/super_goes_last.dart';
18+
import 'package:linter/src/rules/type_init_formals.dart';
19+
import 'package:linter/src/rules/unnecessary_brace_in_string_interp.dart';
20+
import 'package:plugin/plugin.dart';
21+
22+
/// The shared linter plugin instance.
23+
final LinterPlugin linterPlugin = new LinterPlugin();
24+
25+
/// A plugin that defines the extension points and extensions that are
26+
/// inherently defined by the linter.
27+
class LinterPlugin implements Plugin {
28+
29+
/// A subset of rules that we are considering enabled by "default".
30+
static final List<LintRule> _rules = [
31+
new CamelCaseTypes(),
32+
new ConstantIdentifierNames(),
33+
new EmptyConstructorBodies(),
34+
new LibraryNames(),
35+
new LibraryPrefixes(),
36+
new NonConstantIdentifierNames(),
37+
new OneMemberAbstracts(),
38+
new SlashForDocComments(),
39+
new SuperGoesLast(),
40+
new TypeInitFormals(),
41+
new UnnecessaryBraceInStringInterp()
42+
];
43+
44+
/// The unique identifier of this plugin.
45+
static const String UNIQUE_IDENTIFIER = 'linter.core';
46+
47+
/// The simple identifier of the extension point that allows plugins to
48+
/// register new lint rules.
49+
static const String LINT_RULE_EXTENSION_POINT = 'rule';
50+
51+
/// The extension point that allows plugins to register new lint rules.
52+
ExtensionPoint lintRuleExtensionPoint;
53+
54+
/// Return a list containing all contributed lint rules.
55+
List<LintRule> get lintRules => lintRuleExtensionPoint.extensions;
56+
57+
@override
58+
String get uniqueIdentifier => UNIQUE_IDENTIFIER;
59+
60+
@override
61+
void registerExtensionPoints(RegisterExtensionPoint registerExtensionPoint) {
62+
lintRuleExtensionPoint = registerExtensionPoint(
63+
LINT_RULE_EXTENSION_POINT, _validateTaskExtension);
64+
}
65+
66+
@override
67+
void registerExtensions(RegisterExtension registerExtension) {
68+
_rules.forEach((LintRule rule) =>
69+
registerExtension(LINT_RULE_EXTENSION_POINT_ID, rule));
70+
}
71+
72+
void _validateTaskExtension(Object extension) {
73+
if (extension is! LintRule) {
74+
String id = lintRuleExtensionPoint.uniqueIdentifier;
75+
throw new ExtensionError('Extensions to $id must implement LintRule');
76+
}
77+
}
78+
}

pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ dependencies:
88
args: '>=0.12.1 <0.14.0'
99
cli_util: '>=0.0.1 <0.1.0'
1010
glob: '>=1.0.3 <2.0.0'
11+
plugin: '<0.2.0'
1112
source_span: '>=1.0.2 <2.0.0'
1213
yaml: '>=2.1.2 <3.0.0'
1314
dev_dependencies:

test/linter_test.dart

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ import 'package:linter/src/analysis.dart';
1616
import 'package:linter/src/ast.dart';
1717
import 'package:linter/src/io.dart';
1818
import 'package:linter/src/linter.dart';
19+
import 'package:linter/src/plugin/linter_plugin.dart';
1920
import 'package:linter/src/pub.dart';
2021
import 'package:linter/src/rules.dart';
2122
import 'package:linter/src/rules/camel_case_types.dart';
2223
import 'package:linter/src/rules/package_prefixed_library_names.dart';
2324
import 'package:linter/src/util.dart';
2425
import 'package:mockito/mockito.dart';
2526
import 'package:path/path.dart' as p;
27+
import 'package:plugin/manager.dart';
2628
import 'package:unittest/unittest.dart';
2729

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

3436
defineSanityTests();
3537
defineLinterEngineTests();
38+
definePluginTests();
3639
defineRuleTests();
3740
defineRuleUnitTests();
3841
}
@@ -255,6 +258,34 @@ void defineLinterEngineTests() {
255258
});
256259
}
257260

261+
/// Default contributed lint rules.
262+
var builtinRules = [
263+
'camel_case_types',
264+
'constant_identifier_names',
265+
'empty_constructor_bodies',
266+
'library_names',
267+
'library_prefixes',
268+
'non_constant_identifier_names',
269+
'one_member_abstracts',
270+
'slash_for_doc_comments',
271+
'super_goes_last',
272+
'type_init_formals',
273+
'unnecessary_brace_in_string_interp'
274+
];
275+
276+
/// Plugin tests
277+
definePluginTests() {
278+
group('plugin', () {
279+
test('contributed rules', () {
280+
LinterPlugin linterPlugin = new LinterPlugin();
281+
ExtensionManager manager = new ExtensionManager();
282+
manager.processPlugins([linterPlugin]);
283+
var contributedRules = linterPlugin.lintRules.map((rule) => rule.name);
284+
expect(contributedRules, unorderedEquals(builtinRules));
285+
});
286+
});
287+
}
288+
258289
/// Rule tests
259290
defineRuleTests() {
260291

0 commit comments

Comments
 (0)