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

Commit d99d3bf

Browse files
committed
add lint use_string_in_part_of_directives
1 parent 7d51bf6 commit d99d3bf

File tree

8 files changed

+160
-0
lines changed

8 files changed

+160
-0
lines changed

example/all.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ linter:
203203
- use_rethrow_when_possible
204204
- use_setters_to_change_properties
205205
- use_string_buffers
206+
- use_string_in_part_of_directives
206207
- use_super_parameters
207208
- use_test_throws_matchers
208209
- use_to_and_as_if_applicable

lib/src/rules.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ import 'rules/use_raw_strings.dart';
208208
import 'rules/use_rethrow_when_possible.dart';
209209
import 'rules/use_setters_to_change_properties.dart';
210210
import 'rules/use_string_buffers.dart';
211+
import 'rules/use_string_in_part_of_directives.dart';
211212
import 'rules/use_super_parameters.dart';
212213
import 'rules/use_test_throws_matchers.dart';
213214
import 'rules/use_to_and_as_if_applicable.dart';
@@ -424,6 +425,7 @@ void registerLintRules({bool inTestMode = false}) {
424425
..register(UseRawStrings())
425426
..register(UseSettersToChangeAProperty())
426427
..register(UseStringBuffers())
428+
..register(UseStringInPartOfDirectives())
427429
..register(UseSuperParameters())
428430
..register(UseTestThrowsMatchers())
429431
..register(UseToAndAsIfApplicable())
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright (c) 2022, 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+
import 'package:analyzer/dart/ast/ast.dart';
6+
import 'package:analyzer/dart/ast/visitor.dart';
7+
8+
import '../analyzer.dart';
9+
10+
const _desc = r'Use string in part of directives.';
11+
12+
const _details = r'''
13+
14+
From [effective dart](https://dart.dev/guides/language/effective-dart/usage#do-use-strings-in-part-of-directives):
15+
16+
**DO** use strings in `part of` directives.
17+
18+
**BAD:**
19+
20+
```dart
21+
part of my_library;
22+
```
23+
24+
**GOOD:**
25+
26+
```dart
27+
part of '../../my_library.dart';
28+
```
29+
30+
''';
31+
32+
class UseStringInPartOfDirectives extends LintRule {
33+
UseStringInPartOfDirectives()
34+
: super(
35+
name: 'use_string_in_part_of_directives',
36+
description: _desc,
37+
details: _details,
38+
group: Group.style,
39+
);
40+
41+
@override
42+
void registerNodeProcessors(
43+
NodeLintRegistry registry,
44+
LinterContext context,
45+
) {
46+
var visitor = _Visitor(this);
47+
registry.addPartOfDirective(this, visitor);
48+
}
49+
}
50+
51+
class _Visitor extends SimpleAstVisitor<void> {
52+
_Visitor(this.rule);
53+
54+
final LintRule rule;
55+
56+
@override
57+
void visitPartOfDirective(PartOfDirective node) {
58+
if (node.libraryName != null) {
59+
rule.reportLint(node);
60+
}
61+
}
62+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright (c) 2020, 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+
import 'dart:io';
6+
7+
import 'package:analyzer/src/lint/io.dart';
8+
import 'package:linter/src/analyzer.dart';
9+
import 'package:linter/src/cli.dart' as cli;
10+
import 'package:path/path.dart';
11+
import 'package:test/test.dart';
12+
13+
import '../mocks.dart';
14+
import '../test_constants.dart';
15+
16+
void main() {
17+
group('use_string_in_part_of_directives', () {
18+
var currentOut = outSink;
19+
var collectingOut = CollectingSink();
20+
setUp(() {
21+
exitCode = 0;
22+
outSink = collectingOut;
23+
});
24+
tearDown(() {
25+
collectingOut.buffer.clear();
26+
outSink = currentOut;
27+
exitCode = 0;
28+
});
29+
30+
test(timeout: Timeout.none, 'works correctly', () async {
31+
await cli.runLinter([
32+
'$integrationTestDir/use_string_in_part_of_directives',
33+
'--rules=use_string_in_part_of_directives',
34+
], LinterOptions());
35+
var files =
36+
Directory('$integrationTestDir/use_string_in_part_of_directives')
37+
.listSync()
38+
.whereType<File>()
39+
.toList();
40+
var lintsByFile = <File, List<int>>{
41+
for (var file in files)
42+
file: file
43+
.readAsLinesSync()
44+
.asMap()
45+
.entries
46+
.where((e) => e.value.endsWith('// LINT'))
47+
.map((e) => e.key + 1)
48+
.toList()
49+
};
50+
var output = collectingOut.trim();
51+
for (var entry in lintsByFile.entries) {
52+
for (var line in entry.value) {
53+
expect(output, contains('/${basename(entry.key.path)} $line:'));
54+
}
55+
}
56+
var fileCount = lintsByFile.length;
57+
var issueCount = lintsByFile.values.expand((e) => e).length;
58+
expect(
59+
output,
60+
contains(
61+
'$fileCount file${fileCount <= 1 ? '' : 's'} analyzed, '
62+
'$issueCount issue${issueCount <= 1 ? '' : 's'} found, in',
63+
),
64+
);
65+
expect(exitCode, 1);
66+
});
67+
});
68+
}

test/integration_test.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ import 'integration/unnecessary_string_escapes.dart'
4949
as unnecessary_string_escapes;
5050
import 'integration/use_build_context_synchronously.dart'
5151
as use_build_context_synchronously;
52+
import 'integration/use_string_in_part_of_directives.dart'
53+
as use_string_in_part_of_directives;
5254
import 'mocks.dart';
5355
import 'test_constants.dart';
5456

@@ -201,6 +203,7 @@ void ruleTests() {
201203
prefer_mixin.main();
202204
use_build_context_synchronously.main();
203205
prefer_const_constructors.main();
206+
use_string_in_part_of_directives.main();
204207
});
205208
}
206209

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright (c) 2022, 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+
// test w/ `dart test -N use_string_in_part_of_directives`
6+
7+
part of lib; // LINT
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright (c) 2022, 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+
// test w/ `dart test -N use_string_in_part_of_directives`
6+
7+
part of 'lib.dart'; // OK
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright (c) 2022, 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+
// test w/ `dart test -N use_string_in_part_of_directives`
6+
7+
library lib;
8+
9+
part 'good_part.dart';
10+
part 'bad_part.dart';

0 commit comments

Comments
 (0)