mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 15:09:04 +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) {
|
FieldEntity _indexFieldOfEnumClass(ClassEntity enumClass) {
|
||||||
final member = _closedWorld.elementEnvironment
|
// We expect the enum class to extend `_Enum`, which has an `index` field,
|
||||||
.lookupClassMember(enumClass, const PublicName('index'));
|
// but that might be shadowed by an abstract getter from the class or a
|
||||||
if (member is FieldEntity) return member;
|
// mixin.
|
||||||
throw StateError('$enumClass should have index field, found $member');
|
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(
|
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