Skip to content

Commit 6d2e6f9

Browse files
johnniwintherCommit Queue
authored and
Commit Queue
committed
[cfe] Improve switch encoding
Addresses #51554 (comment) Closes #51391 TEST=existing Change-Id: Idec105dcfde4a91d0a21a1907777d6c07e5f01b2 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/289224 Commit-Queue: Johnni Winther <[email protected]> Reviewed-by: Chloe Stefantsova <[email protected]> Reviewed-by: Alexander Markov <[email protected]>
1 parent b2f4cf3 commit 6d2e6f9

File tree

1,092 files changed

+22150
-13705
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,092 files changed

+22150
-13705
lines changed

pkg/front_end/lib/src/api_prototype/lowering_predicates.dart

Lines changed: 79 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -502,9 +502,6 @@ Field? getLateFieldTarget(Member node) {
502502
///
503503
/// The default value of this variable is `null`.
504504
bool isLateLoweredLocal(VariableDeclaration node) {
505-
assert(node.isLowered ||
506-
node.name == null ||
507-
!isLateLoweredLocalName(node.name!));
508505
return node.isLowered && isLateLoweredLocalName(node.name!);
509506
}
510507

@@ -515,7 +512,8 @@ bool isLateLoweredLocalName(String name) {
515512
name.startsWith(lateLocalPrefix) &&
516513
!name.endsWith(lateIsSetSuffix) &&
517514
!name.endsWith(lateLocalGetterSuffix) &&
518-
!name.endsWith(lateLocalSetterSuffix);
515+
!name.endsWith(lateLocalSetterSuffix) &&
516+
!name.contains(joinedIntermediateInfix);
519517
}
520518

521519
/// Returns the name of the original late local variable from the [name] of the
@@ -547,9 +545,6 @@ String extractLocalNameFromLateLoweredLocal(String name) {
547545
///
548546
/// The default value of this variable is `false`.
549547
bool isLateLoweredIsSetLocal(VariableDeclaration node) {
550-
assert(node.isLowered ||
551-
node.name == null ||
552-
!isLateLoweredIsSetLocalName(node.name!));
553548
return node.isLowered && isLateLoweredIsSetLocalName(node.name!);
554549
}
555550

@@ -586,9 +581,6 @@ String extractLocalNameFromLateLoweredIsSet(String name) {
586581
///
587582
/// where '#local#get' is the local function for reading the variable.
588583
bool isLateLoweredLocalGetter(VariableDeclaration node) {
589-
assert(node.isLowered ||
590-
node.name == null ||
591-
!isLateLoweredLocalGetterName(node.name!));
592584
return node.isLowered && isLateLoweredLocalGetterName(node.name!);
593585
}
594586

@@ -627,9 +619,6 @@ String extractLocalNameFromLateLoweredGetter(String name) {
627619
/// where '#local#set' is the local function for setting the value of the
628620
/// variable.
629621
bool isLateLoweredLocalSetter(VariableDeclaration node) {
630-
assert(node.isLowered ||
631-
node.name == null ||
632-
!isLateLoweredLocalSetterName(node.name!));
633622
return node.isLowered && isLateLoweredLocalSetterName(node.name!);
634623
}
635624

@@ -737,6 +726,83 @@ String? _extractLocalName(String name) {
737726
return extractLocalNameFromLateLoweredSetter(name);
738727
} else if (isLateLoweredIsSetLocalName(name)) {
739728
return extractLocalNameFromLateLoweredIsSet(name);
729+
} else if (isJoinedIntermediateName(name)) {
730+
return extractJoinedIntermediateName(name);
740731
}
741732
return null;
742733
}
734+
735+
/// Infix used for the name of a joined intermediate variable.
736+
///
737+
/// See [isJoinedIntermediateName] for details.
738+
const String joinedIntermediateInfix = "#case#";
739+
740+
/// Returns `true` if [node] is a joined intermediate variable.
741+
///
742+
/// See [isJoinedIntermediateName] for details.
743+
bool isJoinedIntermediateVariable(VariableDeclaration node) {
744+
return node.isLowered &&
745+
node.name != null &&
746+
isJoinedIntermediateName(node.name!);
747+
}
748+
749+
/// Returns `true` if [name] is the name of the "joined intermediate" variable
750+
/// for a "joined local variable".
751+
///
752+
/// A joined local variable occurs when variables of the same name are declared
753+
/// in multiple switch cases for the same body. For instance
754+
///
755+
/// switch (o) {
756+
/// case [var a, _] when a > 5:
757+
/// case [_, var a] when a < 5:
758+
/// print(a);
759+
/// }
760+
///
761+
/// In this cases the 'a' in `print(a)` is a joined variable but the 'a'
762+
/// variables used in the guards of the case are joined intermediate variables:
763+
///
764+
/// {
765+
/// var a#case#0; // intermediate variable for the joined variable 'a'.
766+
/// var a#case#1; // intermediate variable for the joined variable 'a'.
767+
/// var #t1; // temporary variable for the joined variable 'a'.
768+
/// if (o is List<dynamic> &&
769+
/// o.length == 2 &&
770+
/// let #1 in #t1 = a#case#0 = o[0] in true &&
771+
/// a#case#0 > 5 ||
772+
/// o is List<dynamic> &&
773+
/// o.length == 2 &&
774+
/// let #1 in #t1 = a#case#1 = o[1] in true &&
775+
/// a#case#1 < 5) {
776+
/// var a = #t1;
777+
/// {
778+
/// print(a);
779+
/// }
780+
/// }
781+
/// }
782+
///
783+
bool isJoinedIntermediateName(String name) {
784+
int index = name.indexOf(joinedIntermediateInfix);
785+
if (index == -1) {
786+
return false;
787+
}
788+
return int.tryParse(name.substring(index + joinedIntermediateInfix.length)) !=
789+
null;
790+
}
791+
792+
/// Returns the original name for a joined intermediate variable from the [name]
793+
/// of the lowered variable.
794+
///
795+
/// This method assumes that `isJoinedIntermediateName(name)` is `true`.
796+
///
797+
/// See [isJoinedIntermediateName] for details.
798+
String extractJoinedIntermediateName(String name) {
799+
int index = name.indexOf(joinedIntermediateInfix);
800+
return name.substring(0, index);
801+
}
802+
803+
/// Infix used for the name of a joined intermediate variable.
804+
///
805+
/// See [isJoinedIntermediateName] for details.
806+
String createJoinedIntermediateName(String variableName, int index) {
807+
return '$variableName$joinedIntermediateInfix$index';
808+
}

0 commit comments

Comments
 (0)