mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 15:29:45 +00:00
[analyzer] Add a valueOrThrow extension similar to our oft-used typeOrThrow
This really helps in complying with strict-casts. YamlNode.value returns a `dynamic`, which is then often passed somewhere which accepts Object (and then does some type tests). To avoid the implicit cast from `dynamic`, we can use `.valueOrThrow` (or basically just `.value as Object`). The extension getter improves readability and avoids a lot of as-expressions inside conditional expressions etc. Change-Id: I50d2eebd51d6fc3eccf1c930652dd5ce70dd9eb1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/277582 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
parent
c3a1bfdfa5
commit
105efd85b6
|
@ -6,6 +6,7 @@ import 'package:analyzer/error/error.dart';
|
|||
import 'package:analyzer/src/generated/engine.dart';
|
||||
import 'package:analyzer/src/generated/utilities_general.dart';
|
||||
import 'package:analyzer/src/task/options.dart';
|
||||
import 'package:analyzer/src/util/yaml.dart';
|
||||
import 'package:yaml/yaml.dart';
|
||||
|
||||
/// String identifiers mapped to associated severities.
|
||||
|
@ -46,7 +47,7 @@ class ErrorConfig {
|
|||
if (codes is YamlMap) {
|
||||
codes.nodes.forEach((k, v) {
|
||||
if (k is YamlScalar && v is YamlScalar) {
|
||||
_process(k.value, v.value);
|
||||
_process(k.value as String?, v.valueOrThrow);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:analyzer/src/util/yaml.dart';
|
||||
import 'package:yaml/yaml.dart';
|
||||
|
||||
/// Test if the given [value] is `false` or the string "false"
|
||||
|
@ -19,7 +20,7 @@ bool isTrue(Object value) =>
|
|||
/// value could not be converted.
|
||||
bool? toBool(Object value) {
|
||||
if (value is YamlScalar) {
|
||||
value = value.value;
|
||||
value = value.valueOrThrow;
|
||||
}
|
||||
if (value is bool) {
|
||||
return value;
|
||||
|
|
|
@ -66,7 +66,7 @@ class _LintConfig implements LintConfig {
|
|||
void addAsListOrString(Object? value, List<String> list) {
|
||||
if (value is List) {
|
||||
for (var entry in value) {
|
||||
list.add(entry);
|
||||
list.add(entry as String);
|
||||
}
|
||||
} else if (value is String) {
|
||||
list.add(value);
|
||||
|
@ -74,7 +74,7 @@ class _LintConfig implements LintConfig {
|
|||
}
|
||||
|
||||
bool? asBool(Object scalar) {
|
||||
Object value = scalar is YamlScalar ? scalar.value : scalar;
|
||||
var value = scalar is YamlScalar ? scalar.valueOrThrow : scalar;
|
||||
if (value is bool) {
|
||||
return value;
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ class _LintConfig implements LintConfig {
|
|||
}
|
||||
|
||||
String? asString(Object scalar) {
|
||||
Object value = scalar is YamlScalar ? scalar.value : scalar;
|
||||
var value = scalar is YamlScalar ? scalar.valueOrThrow : scalar;
|
||||
if (value is String) {
|
||||
return value;
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ class _LintConfig implements LintConfig {
|
|||
|
||||
// style_guide: {unnecessary_getters: false, camel_case_types: true}
|
||||
if (v is YamlMap) {
|
||||
v.nodes.forEach((key, value) {
|
||||
v.nodes.cast<Object, YamlNode>().forEach((key, value) {
|
||||
//{unnecessary_getters: false}
|
||||
if (asBool(value) != null) {
|
||||
var config = _RuleConfig();
|
||||
|
@ -153,7 +153,7 @@ class _LintConfig implements LintConfig {
|
|||
|
||||
// style_guide: {unnecessary_getters: false, camel_case_types: true}
|
||||
if (value is YamlMap) {
|
||||
value.nodes.forEach((rule, args) {
|
||||
value.nodes.cast<Object, YamlNode>().forEach((rule, args) {
|
||||
// TODO: verify format
|
||||
// unnecessary_getters: false
|
||||
var config = _RuleConfig();
|
||||
|
|
|
@ -36,8 +36,11 @@ class DependencyValidator extends BasePubspecValidator {
|
|||
for (var dependency in declaredDevDependencies.entries) {
|
||||
var packageName = dependency.key as YamlNode;
|
||||
if (declaredDependencies.containsKey(packageName)) {
|
||||
reportErrorForNode(reporter, packageName,
|
||||
PubspecWarningCode.UNNECESSARY_DEV_DEPENDENCY, [packageName.value]);
|
||||
reportErrorForNode(
|
||||
reporter,
|
||||
packageName,
|
||||
PubspecWarningCode.UNNECESSARY_DEV_DEPENDENCY,
|
||||
[packageName.valueOrThrow]);
|
||||
}
|
||||
_validatePathEntries(reporter, dependency.value, false);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:analyzer/error/listener.dart';
|
|||
import 'package:analyzer/file_system/file_system.dart';
|
||||
import 'package:analyzer/src/pubspec/pubspec_validator.dart';
|
||||
import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
|
||||
import 'package:analyzer/src/util/yaml.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:yaml/yaml.dart';
|
||||
|
||||
|
@ -23,7 +24,7 @@ class FlutterValidator extends BasePubspecValidator {
|
|||
String packageRoot = context.dirname(source.fullName);
|
||||
for (YamlNode entryValue in assetsField.nodes) {
|
||||
if (entryValue is YamlScalar) {
|
||||
Object entry = entryValue.value;
|
||||
var entry = entryValue.valueOrThrow;
|
||||
if (entry is String) {
|
||||
if (entry.startsWith('packages/')) {
|
||||
// TODO(brianwilkerson) Add validation of package references.
|
||||
|
@ -36,8 +37,8 @@ class FlutterValidator extends BasePubspecValidator {
|
|||
ErrorCode errorCode = isDirectoryEntry
|
||||
? PubspecWarningCode.ASSET_DIRECTORY_DOES_NOT_EXIST
|
||||
: PubspecWarningCode.ASSET_DOES_NOT_EXIST;
|
||||
reportErrorForNode(
|
||||
reporter, entryValue, errorCode, [entryValue.value]);
|
||||
reportErrorForNode(reporter, entryValue, errorCode,
|
||||
[entryValue.valueOrThrow]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -23,7 +23,7 @@ class ScreenshotsValidator extends BasePubspecValidator {
|
|||
var path = entryValue.value;
|
||||
if (path is String && !_fileExistsAtPath(path)) {
|
||||
reportErrorForNode(reporter, entryValue,
|
||||
PubspecWarningCode.PATH_DOES_NOT_EXIST, [entryValue.value]);
|
||||
PubspecWarningCode.PATH_DOES_NOT_EXIST, [entryValue.valueOrThrow]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -311,12 +311,12 @@ class CodeStyleOptionsValidator extends OptionsValidator {
|
|||
format.span,
|
||||
[AnalyzerOptions.format]);
|
||||
} else if (format is YamlScalar) {
|
||||
var formatValue = toBool(format.value);
|
||||
var formatValue = toBool(format.valueOrThrow);
|
||||
if (formatValue == null) {
|
||||
reporter.reportErrorForSpan(
|
||||
AnalysisOptionsWarningCode.UNSUPPORTED_VALUE, format.span, [
|
||||
AnalyzerOptions.format,
|
||||
format.value,
|
||||
format.valueOrThrow,
|
||||
AnalyzerOptions.trueOrFalseProposal
|
||||
]);
|
||||
}
|
||||
|
@ -414,9 +414,10 @@ class ErrorBuilder {
|
|||
void reportError(ErrorReporter reporter, String scopeName, YamlNode node) {
|
||||
if (proposal.isNotEmpty) {
|
||||
reporter.reportErrorForSpan(
|
||||
code, node.span, [scopeName, node.value, proposal]);
|
||||
code, node.span, [scopeName, node.valueOrThrow, proposal]);
|
||||
} else {
|
||||
reporter.reportErrorForSpan(code, node.span, [scopeName, node.value]);
|
||||
reporter
|
||||
.reportErrorForSpan(code, node.span, [scopeName, node.valueOrThrow]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -519,7 +520,7 @@ class LanguageOptionValidator extends OptionsValidator {
|
|||
reporter.reportErrorForSpan(
|
||||
AnalysisOptionsWarningCode.UNSUPPORTED_VALUE,
|
||||
v.span,
|
||||
[key!, v.value, AnalyzerOptions.trueOrFalseProposal]);
|
||||
[key!, v.valueOrThrow, AnalyzerOptions.trueOrFalseProposal]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -572,9 +573,11 @@ class OptionalChecksValueValidator extends OptionsValidator {
|
|||
value = toLowerCase(v.value);
|
||||
if (!AnalyzerOptions.trueOrFalse.contains(value)) {
|
||||
reporter.reportErrorForSpan(
|
||||
AnalysisOptionsWarningCode.UNSUPPORTED_VALUE,
|
||||
v.span,
|
||||
[key!, v.value, AnalyzerOptions.trueOrFalseProposal]);
|
||||
AnalysisOptionsWarningCode.UNSUPPORTED_VALUE, v.span, [
|
||||
key!,
|
||||
v.valueOrThrow,
|
||||
AnalyzerOptions.trueOrFalseProposal
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -671,7 +674,7 @@ class StrongModeOptionValueValidator extends OptionsValidator {
|
|||
reporter.reportErrorForSpan(
|
||||
AnalysisOptionsWarningCode.UNSUPPORTED_VALUE,
|
||||
v.span,
|
||||
[key!, v.value, AnalyzerOptions.trueOrFalseProposal]);
|
||||
[key!, v.valueOrThrow, AnalyzerOptions.trueOrFalseProposal]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -729,8 +732,8 @@ class TopLevelOptionValidator extends OptionsValidator {
|
|||
node.nodes.forEach((k, v) {
|
||||
if (k is YamlScalar) {
|
||||
if (!supportedOptions.contains(k.value)) {
|
||||
reporter.reportErrorForSpan(
|
||||
_warningCode, k.span, [pluginName, k.value, _valueProposal]);
|
||||
reporter.reportErrorForSpan(_warningCode, k.span,
|
||||
[pluginName, k.valueOrThrow, _valueProposal]);
|
||||
}
|
||||
}
|
||||
//TODO(pq): consider an error if the node is not a Scalar.
|
||||
|
@ -803,7 +806,7 @@ class _OptionsProcessor {
|
|||
}
|
||||
}
|
||||
} else if (names is YamlMap) {
|
||||
for (var key in names.nodes.keys) {
|
||||
for (var key in names.nodes.keys.cast<YamlNode?>()) {
|
||||
var pluginName = _toString(key);
|
||||
if (pluginName != null) {
|
||||
pluginNames.add(pluginName);
|
||||
|
@ -857,7 +860,7 @@ class _OptionsProcessor {
|
|||
configs.nodes.forEach((key, value) {
|
||||
if (key is YamlScalar && value is YamlScalar) {
|
||||
var feature = key.value?.toString();
|
||||
_applyLanguageOption(options, feature, value.value);
|
||||
_applyLanguageOption(options, feature, value.valueOrThrow);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -867,7 +870,8 @@ class _OptionsProcessor {
|
|||
if (config is YamlMap) {
|
||||
config.nodes.forEach((k, v) {
|
||||
if (k is YamlScalar && v is YamlScalar) {
|
||||
_applyOptionalChecksOption(options, k.value?.toString(), v.value);
|
||||
_applyOptionalChecksOption(
|
||||
options, k.value?.toString(), v.valueOrThrow);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -913,7 +917,7 @@ class _OptionsProcessor {
|
|||
if (config is YamlMap) {
|
||||
config.nodes.forEach((k, v) {
|
||||
if (k is YamlScalar && v is YamlScalar) {
|
||||
_applyStrongModeOption(options, k.value?.toString(), v.value);
|
||||
_applyStrongModeOption(options, k.value?.toString(), v.valueOrThrow);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ extension YamlMapExtensions on YamlMap {
|
|||
/// Return the [YamlNode] associated with the given [key], or `null` if there
|
||||
/// is no matching key.
|
||||
YamlNode? getKey(String key) {
|
||||
for (YamlNode k in nodes.keys) {
|
||||
for (var k in nodes.keys.cast<YamlNode>()) {
|
||||
if (k is YamlScalar && k.value == key) {
|
||||
return k;
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ extension YamlMapExtensions on YamlMap {
|
|||
YamlNode? keyAtValue(YamlNode value) {
|
||||
for (var entry in nodes.entries) {
|
||||
if (entry.value == value) {
|
||||
return entry.key;
|
||||
return entry.key as YamlNode?;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -142,3 +142,7 @@ extension YamlMapExtensions on YamlMap {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
extension YamlNodeExtension on YamlNode {
|
||||
Object get valueOrThrow => value as Object;
|
||||
}
|
||||
|
|
|
@ -100,9 +100,10 @@ main() {
|
|||
|
||||
final Merger merger = Merger();
|
||||
|
||||
Object merge(Object o1, Object o2) => merger.merge(wrap(o1), wrap(o2)).value;
|
||||
Object merge(Object o1, Object o2) =>
|
||||
merger.merge(wrap(o1), wrap(o2)).valueOrThrow;
|
||||
|
||||
YamlNode wrap(Object value) {
|
||||
YamlNode wrap(Object? value) {
|
||||
if (value is List) {
|
||||
var wrappedElements = value.map((e) => wrap(e)).toList();
|
||||
return YamlList.internal(
|
||||
|
|
Loading…
Reference in a new issue