Skip to content

Commit 4511eb2

Browse files
committed
Version 2.13.0-211.14.beta
* Cherry-pick 37a91c0 to beta
2 parents 5cae07b + 47579b7 commit 4511eb2

File tree

11 files changed

+87
-30
lines changed

11 files changed

+87
-30
lines changed

pkg/analyzer/lib/src/source/path_filter.dart

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,35 @@
55
import 'package:analyzer/src/util/glob.dart';
66
import 'package:path/path.dart' as path;
77

8-
/// Filter paths against a set of [_ignorePatterns] relative to a [root]
9-
/// directory. Paths outside of [root] are also ignored.
8+
/// Filter paths against a set of [_ignorePatterns] relative to a
9+
/// [ignorePatternsRoot] directory. Paths outside of [includedRoot] are also
10+
/// ignored.
1011
class PathFilter {
1112
/// The path context to use when manipulating paths.
1213
final path.Context pathContext;
1314

15+
/// The path in which files are considered to be included.
16+
final String includedRoot;
17+
1418
/// Path that all ignore patterns are relative to.
15-
final String root;
19+
final String ignorePatternsRoot;
1620

1721
/// List of ignore patterns that paths are tested against.
1822
final List<Glob> _ignorePatterns = <Glob>[];
1923

20-
/// Construct a new path filter rooted at [root] with [ignorePatterns].
24+
/// Construct a new path filter rooted at [includedRoot],
25+
/// with [ignorePatterns] that are relative to [ignorePatternsRoot].
2126
/// If [pathContext] is not specified, then the system path context is used.
22-
PathFilter(this.root, List<String> ignorePatterns,
27+
PathFilter(
28+
this.includedRoot, this.ignorePatternsRoot, List<String> ignorePatterns,
2329
[path.Context? pathContext])
2430
: pathContext = pathContext ?? path.context {
2531
setIgnorePatterns(ignorePatterns);
2632
}
2733

2834
/// Returns true if [path] should be ignored. A path is ignored if it is not
29-
/// contained in [root] or matches one of the ignore patterns.
30-
/// [path] is absolute or relative to [root].
35+
/// contained in [includedRoot] or matches one of the ignore patterns.
36+
/// [path] is absolute or relative to [includedRoot].
3137
bool ignored(String path) {
3238
path = _canonicalize(path);
3339
return !_contained(path) || _match(path);
@@ -53,24 +59,21 @@ class PathFilter {
5359
return sb.toString();
5460
}
5561

56-
/// Returns the absolute path of [path], relative to [root].
62+
/// Returns the absolute path of [path], relative to [includedRoot].
5763
String _canonicalize(String path) =>
58-
pathContext.normalize(pathContext.join(root, path));
64+
pathContext.normalize(pathContext.join(includedRoot, path));
5965

60-
/// Returns true when [path] is contained inside [root].
61-
bool _contained(String path) => path.startsWith(root);
66+
/// Returns true when [path] is contained inside [includedRoot].
67+
bool _contained(String path) => path.startsWith(includedRoot);
6268

6369
/// Returns true if [path] matches any ignore patterns.
6470
bool _match(String path) {
65-
path = _relative(path);
71+
var relative = pathContext.relative(path, from: ignorePatternsRoot);
6672
for (Glob glob in _ignorePatterns) {
67-
if (glob.matches(path)) {
73+
if (glob.matches(relative)) {
6874
return true;
6975
}
7076
}
7177
return false;
7278
}
73-
74-
/// Returns the relative portion of [path] from [root].
75-
String _relative(String path) => pathContext.relative(path, from: root);
7679
}

pkg/analyzer/test/source/path_filter_test.dart

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,53 +8,68 @@ import 'package:test/test.dart';
88

99
main() {
1010
String root(String path) => context.absolute(context.normalize(path));
11+
12+
PathFilter withSingleRoot(String root, List<String> ignorePatterns) {
13+
return PathFilter(root, root, ignorePatterns, context);
14+
}
15+
1116
group('PathFilterTest', () {
12-
setUp(() {});
13-
tearDown(() {});
1417
test('test_ignoreEverything', () {
15-
var filter = PathFilter(root('/'), ['*'], context);
18+
var filter = withSingleRoot(root('/'), ['*']);
1619
expect(filter.ignored('a'), isTrue);
1720
});
21+
1822
test('test_ignoreFile', () {
19-
var filter = PathFilter(root('/'), ['apple'], context);
23+
var filter = withSingleRoot(root('/'), ['apple']);
2024
expect(filter.ignored('apple'), isTrue);
2125
expect(filter.ignored('banana'), isFalse);
2226
});
27+
2328
test('test_ignoreMultipleFiles', () {
24-
var filter = PathFilter(root('/'), ['apple', 'banana'], context);
29+
var filter = withSingleRoot(root('/'), ['apple', 'banana']);
2530
expect(filter.ignored('apple'), isTrue);
2631
expect(filter.ignored('banana'), isTrue);
2732
});
33+
2834
test('test_ignoreSubDir', () {
29-
var filter = PathFilter(root('/'), ['apple/*'], context);
35+
var filter = withSingleRoot(root('/'), ['apple/*']);
3036
expect(filter.ignored('apple/banana'), isTrue);
3137
expect(filter.ignored('apple/banana/cantaloupe'), isFalse);
3238
});
39+
3340
test('test_ignoreTree', () {
34-
var filter = PathFilter(root('/'), ['apple/**'], context);
41+
var filter = withSingleRoot(root('/'), ['apple/**']);
3542
expect(filter.ignored('apple/banana'), isTrue);
3643
expect(filter.ignored('apple/banana/cantaloupe'), isTrue);
3744
});
45+
3846
test('test_ignoreSdkExt', () {
39-
var filter = PathFilter(root('/'), ['sdk_ext/**'], context);
47+
var filter = withSingleRoot(root('/'), ['sdk_ext/**']);
4048
expect(filter.ignored('sdk_ext/entry.dart'), isTrue);
4149
expect(filter.ignored('sdk_ext/lib/src/part.dart'), isTrue);
4250
});
51+
4352
test('test_outsideRoot', () {
44-
var filter =
45-
PathFilter(root('/workspace/dart/sdk'), ['sdk_ext/**'], context);
53+
var filter = withSingleRoot(root('/workspace/dart/sdk'), ['sdk_ext/**']);
4654
expect(filter.ignored('/'), isTrue);
4755
expect(filter.ignored('/workspace'), isTrue);
4856
expect(filter.ignored('/workspace/dart'), isTrue);
4957
expect(filter.ignored('/workspace/dart/sdk'), isFalse);
5058
expect(filter.ignored('/workspace/dart/../dart/sdk'), isFalse);
5159
});
60+
5261
test('test_relativePaths', () {
53-
var filter =
54-
PathFilter(root('/workspace/dart/sdk'), ['sdk_ext/**'], context);
62+
var filter = withSingleRoot(root('/workspace/dart/sdk'), ['sdk_ext/**']);
5563
expect(filter.ignored('../apple'), isTrue);
5664
expect(filter.ignored('../sdk/main.dart'), isFalse);
5765
expect(filter.ignored('../sdk/sdk_ext/entry.dart'), isTrue);
5866
});
67+
68+
test('different ignore patterns root', () {
69+
var filter = PathFilter(
70+
root('/home/my'), root('/home'), ['my/test/ignored/*.dart'], context);
71+
expect(filter.ignored(root('/home/my/lib/a.dart')), isFalse);
72+
expect(filter.ignored(root('/home/my/test/ignored/b.dart')), isTrue);
73+
});
5974
});
6075
}

pkg/analyzer_cli/lib/src/driver.dart

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,16 @@ class _AnalysisContextProvider {
505505

506506
/// TODO(scheglov) Use analyzedFiles()
507507
PathFilter get pathFilter {
508-
return PathFilter(analysisContext.contextRoot.root.path,
508+
var contextRoot = analysisContext.contextRoot;
509+
var optionsFile = contextRoot.optionsFile;
510+
511+
// If there is no options file, there can be no excludes.
512+
if (optionsFile == null) {
513+
return PathFilter(contextRoot.root.path, contextRoot.root.path, []);
514+
}
515+
516+
// Exclude patterns are relative to the directory with the options file.
517+
return PathFilter(contextRoot.root.path, optionsFile.parent2.path,
509518
analysisContext.analysisOptions.excludePatterns);
510519
}
511520

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
analyzer:
2+
exclude:
3+
- inner/lib/excluded_error.dart
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"configVersion": 2,
3+
"packages": [
4+
{
5+
"name": "inner",
6+
"rootUri": "../",
7+
"packageUri": "lib",
8+
"languageVersion": "2.9"
9+
}
10+
]
11+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ExcludedUndefinedClassInInner x = null;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
IncludedUndefinedClassInInner f = null;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Note `.dart_tool/package_config.json` - it, not this file, makes a new analysis context.
2+
name: inner
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/// Should not be reported, we analyze only `inner`.
2+
IncludedUndefinedClassInOuter f = null;

pkg/analyzer_cli/test/driver_test.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,16 @@ class OptionsTest extends BaseTest {
396396
_expectUndefinedClassErrorsWithoutExclusions();
397397
}
398398

399+
Future<void> test_analysisOptions_excludes_inner() async {
400+
await drive('data/exclude_portion_of_inner_context/inner',
401+
options: 'data/exclude_portion_of_inner_context/$analysisOptionsYaml');
402+
expect(
403+
bulletToDash(outSink),
404+
contains("error - Undefined class 'IncludedUndefinedClassInInner'"),
405+
);
406+
expect(outSink.toString(), contains('1 error found.'));
407+
}
408+
399409
Future<void>
400410
test_analysisOptions_excludesRelativeToAnalysisOptions_explicit() async {
401411
// The exclude is relative to the project, not/ the analyzed path, and it

0 commit comments

Comments
 (0)