Index: pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart |
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart b/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart |
index 4f90dbd818da0ec2687d5ee83d66fe5a81ad4442..8fccb03919a03e76bedd8ed55fa4b8692c2a33cb 100644 |
--- a/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart |
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart |
@@ -25,7 +25,7 @@ import 'package:kernel/ast.dart'; |
/// This class abstracts away the representation of the underlying AST using |
/// generic parameters. Derived classes should set E and V to the class they |
/// use to represent expressions and variable declarations, respectively. |
-abstract class TypePromoter<E, V> { |
+abstract class TypePromoter { |
/// Returns the current type promotion scope. |
TypePromotionScope get currentScope; |
@@ -34,8 +34,8 @@ abstract class TypePromoter<E, V> { |
/// |
/// [mutatedInClosure] indicates whether the variable was mutated in a closure |
/// somewhere in the method. |
- DartType computePromotedType(TypePromotionFact<V> fact, |
- TypePromotionScope scope, bool mutatedInClosure); |
+ DartType computePromotedType( |
+ TypePromotionFact fact, TypePromotionScope scope, bool mutatedInClosure); |
/// Updates the state to reflect the fact that we are entering an "else" |
/// branch. |
@@ -44,7 +44,7 @@ abstract class TypePromoter<E, V> { |
/// Updates the state to reflect the fact that the "condition" part of an "if" |
/// statement or conditional expression has just been parsed, and we are |
/// entering the "then" branch. |
- void enterThen(E condition); |
+ void enterThen(Expression condition); |
/// Updates the state to reflect the fact that we have exited the "else" |
/// branch of an "if" statement or conditional expression. |
@@ -59,55 +59,56 @@ abstract class TypePromoter<E, V> { |
/// |
/// [functionNestingLevel] should be the current nesting level of closures. |
/// This is used to determine if the variable was accessed in a closure. |
- TypePromotionFact<V> getFactForAccess(V variable, int functionNestingLevel); |
+ TypePromotionFact getFactForAccess( |
+ VariableDeclaration variable, int functionNestingLevel); |
/// Updates the state to reflect the fact that an "is" check of a local |
/// variable was just parsed. |
- void handleIsCheck(E isExpression, bool isInverted, V variable, DartType type, |
- int functionNestingLevel); |
+ void handleIsCheck(Expression isExpression, bool isInverted, |
+ VariableDeclaration variable, DartType type, int functionNestingLevel); |
/// Updates the state to reflect the fact that the given [variable] was |
/// mutated. |
- void mutateVariable(V variable, int functionNestingLevel); |
+ void mutateVariable(VariableDeclaration variable, int functionNestingLevel); |
} |
/// Derived class containing generic implementations of [TypePromoter]. |
/// |
/// This class contains as much of the implementation of type promotion as |
-/// possible without knowing the identity of the type parameters. It defers to |
-/// abstract methods for everything else. |
-abstract class TypePromoterImpl<E, V> extends TypePromoter<E, V> { |
+/// possible without needing access to private members of shadow objects. It |
+/// defers to abstract methods for everything else. |
+abstract class TypePromoterImpl extends TypePromoter { |
/// [TypePromotionFact] representing the initial state (no facts have been |
/// determined yet). |
/// |
/// All linked lists of facts terminate in this object. |
- final _NullFact<V> _nullFacts; |
+ final _NullFact _nullFacts; |
/// Map from variable declaration to the most recent [TypePromotionFact] |
/// associated with the variable. |
/// |
/// [TypePromotionFact]s that are not associated with any variable show up in |
/// this map under the key `null`. |
- final _factCache = <V, TypePromotionFact<V>>{}; |
+ final _factCache = <VariableDeclaration, TypePromotionFact>{}; |
/// Linked list of [TypePromotionFact]s that was current at the time the |
/// [_factCache] was last updated. |
- TypePromotionFact<V> _factCacheState; |
+ TypePromotionFact _factCacheState; |
/// Linked list of [TypePromotionFact]s describing what is known to be true |
/// after execution of the expression or statement that was most recently |
/// parsed. |
- TypePromotionFact<V> _currentFacts; |
+ TypePromotionFact _currentFacts; |
/// The most recently parsed expression whose outcome potentially affects what |
/// is known to be true (e.g. an "is" check or a logical expression). May be |
/// `null` if no such expression has been encountered yet. |
- E _promotionExpression; |
+ Expression _promotionExpression; |
/// Linked list of [TypePromotionFact]s describing what is known to be true |
/// after execution of [_promotionExpression], assuming that |
/// [_promotionExpression] evaluates to `true`. |
- TypePromotionFact<V> _trueFactsForPromotionExpression; |
+ TypePromotionFact _trueFactsForPromotionExpression; |
/// Linked list of [TypePromotionScope]s describing the nesting structure that |
/// contains the expressoin or statement that was most recently parsed. |
@@ -117,9 +118,9 @@ abstract class TypePromoterImpl<E, V> extends TypePromoter<E, V> { |
/// created. |
int _lastFactSequenceNumber = 0; |
- TypePromoterImpl() : this._(new _NullFact<V>()); |
+ TypePromoterImpl() : this._(new _NullFact()); |
- TypePromoterImpl._(_NullFact<V> this._nullFacts) |
+ TypePromoterImpl._(_NullFact this._nullFacts) |
: _factCacheState = _nullFacts, |
_currentFacts = _nullFacts { |
_factCache[null] = _nullFacts; |
@@ -129,8 +130,8 @@ abstract class TypePromoterImpl<E, V> extends TypePromoter<E, V> { |
TypePromotionScope get currentScope => _currentScope; |
@override |
- DartType computePromotedType(TypePromotionFact<V> fact, |
- TypePromotionScope scope, bool mutatedInClosure) { |
+ DartType computePromotedType( |
+ TypePromotionFact fact, TypePromotionScope scope, bool mutatedInClosure) { |
if (mutatedInClosure) return null; |
return fact?._computePromotedType(this, scope); |
} |
@@ -154,7 +155,7 @@ abstract class TypePromoterImpl<E, V> extends TypePromoter<E, V> { |
} |
@override |
- void enterThen(E condition) { |
+ void enterThen(Expression condition) { |
debugEvent('enterThen'); |
// Figure out what the facts are based on possible condition outcomes. |
var trueFacts = _factsWhenTrue(condition); |
@@ -183,7 +184,8 @@ abstract class TypePromoterImpl<E, V> extends TypePromoter<E, V> { |
} |
@override |
- TypePromotionFact<V> getFactForAccess(V variable, int functionNestingLevel) { |
+ TypePromotionFact getFactForAccess( |
+ VariableDeclaration variable, int functionNestingLevel) { |
debugEvent('getFactForAccess'); |
var fact = _computeCurrentFactMap()[variable]; |
TypePromotionFact._recordAccessedInScope( |
@@ -192,14 +194,14 @@ abstract class TypePromoterImpl<E, V> extends TypePromoter<E, V> { |
} |
/// Returns the nesting level that was in effect when [variable] was declared. |
- int getVariableFunctionNestingLevel(V variable); |
+ int getVariableFunctionNestingLevel(VariableDeclaration variable); |
@override |
- void handleIsCheck(E isExpression, bool isInverted, V variable, DartType type, |
- int functionNestingLevel) { |
+ void handleIsCheck(Expression isExpression, bool isInverted, |
+ VariableDeclaration variable, DartType type, int functionNestingLevel) { |
debugEvent('handleIsCheck'); |
if (!isPromotionCandidate(variable)) return; |
- var isCheck = new _IsCheck<V>( |
+ var isCheck = new _IsCheck( |
++_lastFactSequenceNumber, |
variable, |
_currentFacts, |
@@ -217,11 +219,11 @@ abstract class TypePromoterImpl<E, V> extends TypePromoter<E, V> { |
/// This is needed because in kernel, [VariableDeclaration] objects are |
/// sometimes used to represent local functions, which are not subject to |
/// promotion. |
- bool isPromotionCandidate(V variable); |
+ bool isPromotionCandidate(VariableDeclaration variable); |
/// Updates the state to reflect the fact that the given [variable] was |
/// mutated. |
- void mutateVariable(V variable, int functionNestingLevel) { |
+ void mutateVariable(VariableDeclaration variable, int functionNestingLevel) { |
debugEvent('mutateVariable'); |
var fact = _computeCurrentFactMap()[variable]; |
TypePromotionFact._recordMutatedInScope(fact, _currentScope); |
@@ -233,28 +235,28 @@ abstract class TypePromoterImpl<E, V> extends TypePromoter<E, V> { |
/// Determines whether [a] and [b] represent the same expression, after |
/// dropping redundant enclosing parentheses. |
- bool sameExpressions(E a, E b); |
+ bool sameExpressions(Expression a, Expression b); |
/// Records that the given variable was mutated somewhere inside the method. |
- void setVariableMutatedAnywhere(V variable); |
+ void setVariableMutatedAnywhere(VariableDeclaration variable); |
/// Records that the given variable was mutated inside a closure. |
- void setVariableMutatedInClosure(V variable); |
+ void setVariableMutatedInClosure(VariableDeclaration variable); |
/// Indicates whether [setVariableMutatedAnywhere] has been called for the |
/// given [variable]. |
- bool wasVariableMutatedAnywhere(V variable); |
+ bool wasVariableMutatedAnywhere(VariableDeclaration variable); |
/// Returns a map from variable declaration to the most recent |
/// [TypePromotionFact] associated with the variable. |
- Map<V, TypePromotionFact<V>> _computeCurrentFactMap() { |
+ Map<VariableDeclaration, TypePromotionFact> _computeCurrentFactMap() { |
// Roll back any map entries associated with facts that are no longer in |
// effect, and set [commonAncestor] to the fact that is an ancestor of |
// the current state and the previously cached state. To do this, we set a |
// variable pointing to [_currentFacts], and then walk both it and |
// [_factCacheState] back to their common ancestor, updating [_factCache] as |
// we go. |
- TypePromotionFact<V> commonAncestor = _currentFacts; |
+ TypePromotionFact commonAncestor = _currentFacts; |
while (commonAncestor.sequenceNumber != _factCacheState.sequenceNumber) { |
if (commonAncestor.sequenceNumber > _factCacheState.sequenceNumber) { |
// The currently cached state is older than the common ancestor guess, |
@@ -273,7 +275,7 @@ abstract class TypePromoterImpl<E, V> extends TypePromoter<E, V> { |
// Roll forward any map entries associated with facts that are newly in |
// effect. Since newer facts link to older ones, it is easiest to do roll |
// forward the most recent facts first. |
- for (TypePromotionFact<V> newState = _currentFacts; |
+ for (TypePromotionFact newState = _currentFacts; |
!identical(newState, commonAncestor); |
newState = newState.previous) { |
var currentlyCached = _factCache[newState.variable]; |
@@ -292,7 +294,7 @@ abstract class TypePromoterImpl<E, V> extends TypePromoter<E, V> { |
/// assuming it evaluates to `false`. |
/// |
/// [e] must be the most resently parsed expression or statement. |
- TypePromotionFact<V> _factsWhenFalse(E e) { |
+ TypePromotionFact _factsWhenFalse(Expression e) { |
// Type promotion currently only occurs when an "is" or logical expression |
// evaluates to `true`, so no special logic is required; we just use |
// [_currentFacts]. |
@@ -306,15 +308,14 @@ abstract class TypePromoterImpl<E, V> extends TypePromoter<E, V> { |
/// assuming it evaluates to `true`. |
/// |
/// [e] must be the most resently parsed expression or statement. |
- TypePromotionFact<V> _factsWhenTrue(E e) => |
+ TypePromotionFact _factsWhenTrue(Expression e) => |
sameExpressions(_promotionExpression, e) |
? _trueFactsForPromotionExpression |
: _currentFacts; |
/// Returns the set of facts known to be true after two branches of execution |
/// rejoin. |
- TypePromotionFact<V> _mergeFacts( |
- TypePromotionFact<V> a, TypePromotionFact<V> b) { |
+ TypePromotionFact _mergeFacts(TypePromotionFact a, TypePromotionFact b) { |
// Type promotion currently doesn't support any mechanism for facts to |
// accumulate along a straight-line execution path (they can only accumulate |
// when entering a scope), so we can simply find the common ancestor fact. |
@@ -340,7 +341,7 @@ abstract class TypePromoterImpl<E, V> extends TypePromoter<E, V> { |
/// For internal debugging use, prints the current state followed by the event |
/// name. |
void _printEvent(String name) { |
- Iterable<TypePromotionFact<V>> factChain(TypePromotionFact<V> fact) sync* { |
+ Iterable<TypePromotionFact> factChain(TypePromotionFact fact) sync* { |
while (fact != null) { |
yield fact; |
fact = fact.previousForVariable; |
@@ -363,8 +364,8 @@ abstract class TypePromoterImpl<E, V> extends TypePromoter<E, V> { |
/// need to split [ifFalse] into two cases, one for when the expression |
/// evaluated to `false`, and one where the truth value of the expression |
/// doesn't matter. |
- void _recordPromotionExpression( |
- E expression, TypePromotionFact<V> ifTrue, TypePromotionFact<V> ifFalse) { |
+ void _recordPromotionExpression(Expression expression, |
+ TypePromotionFact ifTrue, TypePromotionFact ifFalse) { |
_promotionExpression = expression; |
_trueFactsForPromotionExpression = ifTrue; |
_currentFacts = ifFalse; |
@@ -392,14 +393,14 @@ abstract class TypePromoterImpl<E, V> extends TypePromoter<E, V> { |
/// It's possible that the fact will be overshadowed by a later fact, or its |
/// effect will be cancelled by a later assignment. The final detemination of |
/// whether promotion occurs is left to [_computePromotedType]. |
-abstract class TypePromotionFact<V> { |
+abstract class TypePromotionFact { |
/// The variable this fact records information about, or `null` if this fact |
/// records information about general flow control. |
- final V variable; |
+ final VariableDeclaration variable; |
/// The fact chain that was in effect prior to execution of the statement or |
/// expression that caused this fact to be true. |
- final TypePromotionFact<V> previous; |
+ final TypePromotionFact previous; |
/// Integer associated with this fact. Each time a fact is created it is |
/// given a sequence number one greater than the previously generated fact. |
@@ -410,7 +411,7 @@ abstract class TypePromotionFact<V> { |
/// The most recent fact appearing in the fact chain [previous] whose |
/// [variable] matches this one, or `null` if there is no such fact. |
- final TypePromotionFact<V> previousForVariable; |
+ final TypePromotionFact previousForVariable; |
/// The function nesting level of the expression that led to this fact. |
final int functionNestingLevel; |
@@ -437,7 +438,7 @@ abstract class TypePromotionFact<V> { |
/// |
/// Should not be called until after parsing of the entire method is complete. |
DartType _computePromotedType( |
- TypePromoterImpl<dynamic, V> promoter, TypePromotionScope scope); |
+ TypePromoterImpl promoter, TypePromotionScope scope); |
/// Records the fact that the variable referenced by [fact] was accessed |
/// within the given scope, at the given function nesting level. |
@@ -507,27 +508,27 @@ class TypePromotionScope { |
/// [TypePromotionScope] representing the "then" and "else" bodies of an "if" |
/// statement or conditional expression. |
-class _ConditionalScope<V> extends TypePromotionScope { |
+class _ConditionalScope extends TypePromotionScope { |
/// The fact state in effect at the top of the "else" block. |
- final TypePromotionFact<V> beforeElse; |
+ final TypePromotionFact beforeElse; |
/// The fact state which was in effect at the bottom of the "then" block. |
- TypePromotionFact<V> afterTrue; |
+ TypePromotionFact afterTrue; |
_ConditionalScope(TypePromotionScope enclosing, this.beforeElse) |
: super(enclosing); |
} |
/// [TypePromotionFact] representing an "is" check which succeeded. |
-class _IsCheck<V> extends TypePromotionFact<V> { |
+class _IsCheck extends TypePromotionFact { |
/// The type appearing on the right hand side of "is". |
final DartType checkedType; |
_IsCheck( |
int sequenceNumber, |
- V variable, |
- TypePromotionFact<V> previous, |
- TypePromotionFact<V> previousForVariable, |
+ VariableDeclaration variable, |
+ TypePromotionFact previous, |
+ TypePromotionFact previousForVariable, |
int functionNestingLevel, |
this.checkedType) |
: super(sequenceNumber, variable, previous, previousForVariable, |
@@ -538,7 +539,7 @@ class _IsCheck<V> extends TypePromotionFact<V> { |
@override |
DartType _computePromotedType( |
- TypePromoterImpl<dynamic, V> promoter, TypePromotionScope scope) { |
+ TypePromoterImpl promoter, TypePromotionScope scope) { |
// TODO(paulberry): add a subtype check. For example: |
// f(Object x) { |
// if (x is int) { // promotes x to int |
@@ -575,7 +576,7 @@ class _IsCheck<V> extends TypePromotionFact<V> { |
/// Instance of [TypePromotionFact] representing the facts which are known on |
/// entry to the method (i.e. nothing). |
-class _NullFact<V> extends TypePromotionFact<V> { |
+class _NullFact extends TypePromotionFact { |
_NullFact() : super(0, null, null, null, 0); |
@override |
@@ -583,7 +584,7 @@ class _NullFact<V> extends TypePromotionFact<V> { |
@override |
DartType _computePromotedType( |
- TypePromoter<dynamic, V> promoter, TypePromotionScope scope) { |
+ TypePromoter promoter, TypePromotionScope scope) { |
throw new StateError('Tried to create promoted type for no variable'); |
} |
} |