mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 21:30:17 +00:00
[analyzer] Fix resolving target kinds
As the analyzer is shipped with the SDK, it may have to analyze sources using a newer version of package:meta than the one it was compiled with. If that new version adds a new TargetKind, attempting to resolve that constant with `TargetKind.values[index]` may cause a range error. Further, if a new TargetKind is not added at the end of that enum, the analyzer will misinterpret the constant values. This CL fixes both issues by comparing target kinds by their name. Unknown target kinds from a newer meta version are ignored since the analyzer would not be capable of analyzing them either way. Bug: 46183 Change-Id: Ibbb7063ae9939e95f846076d7fe462e222a8a5bb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/201760 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
parent
10b83a4882
commit
8eba520115
|
@ -41,6 +41,10 @@ import 'package:meta/meta_meta.dart';
|
|||
class BestPracticesVerifier extends RecursiveAstVisitor<void> {
|
||||
static const String _TO_INT_METHOD_NAME = "toInt";
|
||||
|
||||
static final Map<String, TargetKind> _targetKindsByName = {
|
||||
for (final kind in TargetKind.values) kind.toString(): kind,
|
||||
};
|
||||
|
||||
/// The class containing the AST nodes being visited, or `null` if we are not
|
||||
/// in the scope of a class.
|
||||
ClassElementImpl? _enclosingClass;
|
||||
|
@ -1623,9 +1627,23 @@ class BestPracticesVerifier extends RecursiveAstVisitor<void> {
|
|||
if (annotation.isTarget) {
|
||||
var value = annotation.computeConstantValue()!;
|
||||
var kinds = <TargetKind>{};
|
||||
|
||||
for (var kindObject in value.getField('kinds')!.toSetValue()!) {
|
||||
// We can't directly translate the index from the analyzed TargetKind
|
||||
// constant to TargetKinds.values because the analyzer from the SDK
|
||||
// may have been compiled with a different version of pkg:meta.
|
||||
var index = kindObject.getField('index')!.toIntValue()!;
|
||||
kinds.add(TargetKind.values[index]);
|
||||
var targetKindClass =
|
||||
(kindObject.type as InterfaceType).element as EnumElementImpl;
|
||||
// Instead, map constants to their TargetKind by comparing getter
|
||||
// names.
|
||||
var getter = targetKindClass.constants[index];
|
||||
var name = 'TargetKind.${getter.name}';
|
||||
|
||||
var foundTargetKind = _targetKindsByName[name];
|
||||
if (foundTargetKind != null) {
|
||||
kinds.add(foundTargetKind);
|
||||
}
|
||||
}
|
||||
return kinds;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue