blob: dbd281b6a84e77c84646b2148e42f7c0dd437b33 [file] [log] [blame]
// Copyright (c) 2022, 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.
/// This data structure assigns a unique integer identifier to everything that
/// might undergo promotion in the user's code (local variables and properties).
/// An integer identifier is also assigned to `this` (even though `this` is not
/// promotable), because promotable properties can be reached using `this` as a
/// starting point.
class PromotionKeyStore<Variable extends Object> {
/// Special promotion key to represent `this`.
late final int thisPromotionKey = _makeNewKey();
final Map<Variable, int> _variableKeys = new Map<Variable, int>.identity();
/// List whose `i`th entry is the [Variable] corresponding to promotion key
/// `i`, or `null`, if promotion key `i` does not correspond to a specific
/// [Variable].
final List<Variable?> _keyToVariable = [];
int keyForVariable(Variable variable) =>
_variableKeys[variable] ??= _makeNewKey(variable: variable);
/// Creates a fresh promotion key that hasn't been used before (and won't be
/// reused again). This is used by flow analysis to model the synthetic
/// variables used during pattern matching to cache the values that the
/// pattern, and its subpatterns, are being matched against. It is also used
/// to track the values returned by property gets.
int makeTemporaryKey() => _makeNewKey();
/// Gets the [Variable] corresponding to [variableKey], or `null` if
/// [variableKey] does not correspond to a specific [Variable].
Variable? variableForKey(int variableKey) => _keyToVariable[variableKey];
/// Creates a fresh promotion key. If a [variable] is provided, it is stored
/// for later retrieval by [variableForKey].
int _makeNewKey({Variable? variable}) {
int key = _keyToVariable.length;
_keyToVariable.add(variable);
return key;
}
}