findAnalysisOptions method
Implementation
AnalysisOptions? findAnalysisOptions(File? file) {
if (file == null) {
return null;
}
final now = _now();
final searched = <String>[];
for (var dir = file.parent; ; dir = dir.parent) {
final knownEmptyAt = _withoutOptions[dir.path];
if (knownEmptyAt != null &&
now.difference(knownEmptyAt) < _negativeCacheTtl) {
break;
}
searched.add(dir.path);
try {
final optionsFile = dir.getFile('analysis_options.yaml');
if (optionsFile.exists) {
final stamp = optionsFile.modificationStamp;
final cached = _analysisOptions[optionsFile.path];
if (cached != null && cached.$1 == stamp) {
return cached.$2;
}
_logger.finer('parsing ${optionsFile.path}');
final options = AnalysisOptions.loadFromYaml(
dir.path,
optionsFile.readAsStringSync(),
);
_analysisOptions[optionsFile.path] = (stamp, options);
// Reading it worked, so a later break is news again rather than a
// repeat of a complaint already made.
_warnedAbout.remove(dir.path);
return options;
}
// No file here. A complaint about one that has since been deleted is
// stale too, and keeping it would silence the next breakage of a
// recreated one. Deliberately not `continue`: the loop's exit test is
// at the bottom, and skipping it spins forever at the filesystem root.
_warnedAbout.remove(dir.path);
} catch (e, stackTrace) {
// Failing here silently disables every exclude_glob, so say so -- but
// only once per file, since this runs for every reported literal.
if (_warnedAbout.add(dir.path)) {
_logger.warning(
'Unable to read analysis options near ${dir.path}',
e,
stackTrace,
);
}
// Return rather than break: caching this as "no options above here"
// would turn a malformed or briefly unreadable file into a permanent
// one, surviving the fix that repairs it.
return null;
}
// Checked after reading, so an options file at the root is still found.
if (dir.isRoot) {
break;
}
}
for (final path in searched) {
_withoutOptions[path] = now;
}
return null;
}