mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 12:58:05 +00:00
[dart2js] Fix #51558 - skip abstract getters
Improve 'enum switch' optimization to not be confused by abstract getters. Bug: 51558 Change-Id: Iac4e5238c1884df6afd1611aecc9f158b1a8b167 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/286102 Reviewed-by: Nate Biggs <natebiggs@google.com> Commit-Queue: Stephen Adams <sra@google.com>
This commit is contained in:
parent
ed277908ae
commit
cfa6d0f735
|
@ -1209,10 +1209,21 @@ class SsaInstructionSimplifier extends HBaseVisitor<HInstruction>
|
|||
}
|
||||
|
||||
FieldEntity _indexFieldOfEnumClass(ClassEntity enumClass) {
|
||||
final member = _closedWorld.elementEnvironment
|
||||
.lookupClassMember(enumClass, const PublicName('index'));
|
||||
if (member is FieldEntity) return member;
|
||||
throw StateError('$enumClass should have index field, found $member');
|
||||
// We expect the enum class to extend `_Enum`, which has an `index` field,
|
||||
// but that might be shadowed by an abstract getter from the class or a
|
||||
// mixin.
|
||||
ClassEntity? cls = enumClass;
|
||||
MemberEntity? foundMember;
|
||||
while (cls != null) {
|
||||
final member = _closedWorld.elementEnvironment
|
||||
.lookupClassMember(cls, const PublicName('index'));
|
||||
if (member == null) break; // should never happen.
|
||||
foundMember = member;
|
||||
if (member is FieldEntity) return member;
|
||||
if (!member.isAbstract) break;
|
||||
cls = _closedWorld.elementEnvironment.getSuperClass(cls);
|
||||
}
|
||||
throw StateError('$enumClass should have index field, found $foundMember');
|
||||
}
|
||||
|
||||
IntConstantValue _indexValueOfEnumConstant(
|
||||
|
|
36
tests/web/regress/issue/51558_test.dart
Normal file
36
tests/web/regress/issue/51558_test.dart
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
// Regression test for http://dartbug.com/51558
|
||||
//
|
||||
// Enum classes may have abstract getters in the inheritance chain that, as
|
||||
// declarations, shadow the `index` of the base class.
|
||||
|
||||
abstract class EnumFlag extends Object {
|
||||
int get index;
|
||||
|
||||
int get value => 1 << index;
|
||||
}
|
||||
|
||||
enum EnumXY with EnumFlag { x, y }
|
||||
|
||||
extension EnumXTExtensions on EnumXY {
|
||||
String display() {
|
||||
switch (this) {
|
||||
case EnumXY.x:
|
||||
return 'X';
|
||||
case EnumXY.y:
|
||||
return 'Y';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
Expect.equals('X', EnumXY.x.display());
|
||||
|
||||
// This second line is needed so that the abstract getter is resolved.
|
||||
Expect.equals(0, EnumXY.x.index);
|
||||
}
|
Loading…
Reference in a new issue