From bf83cc30edde61b1ccc15cf97c9e6a5bbfa480cf Mon Sep 17 00:00:00 2001 From: Mayank Patke Date: Thu, 13 Jun 2024 23:01:34 +0000 Subject: [PATCH] [dart2js] Convert VariableUse to a sealed class hierarchy. Change-Id: I28d71d81031e3e6eefc2b4f6decfe375099a1c32 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371185 Reviewed-by: Stephen Adams Commit-Queue: Mayank Patke --- pkg/compiler/lib/src/ir/closure.dart | 294 ++++++++++++--------- pkg/compiler/lib/src/ir/scope_visitor.dart | 82 +++--- pkg/compiler/lib/src/js_model/closure.dart | 66 +++-- 3 files changed, 247 insertions(+), 195 deletions(-) diff --git a/pkg/compiler/lib/src/ir/closure.dart b/pkg/compiler/lib/src/ir/closure.dart index 44cd931355d1..54ba76964ad8 100644 --- a/pkg/compiler/lib/src/ir/closure.dart +++ b/pkg/compiler/lib/src/ir/closure.dart @@ -164,7 +164,9 @@ class NodeBox { NodeBox(this.name, this.executableContext); } -enum VariableUseKind { +sealed class VariableUse {} + +enum SimpleVariableUse implements VariableUse { /// An explicit variable use. /// /// For type variable this is an explicit as-cast, an is-test or a type @@ -186,147 +188,197 @@ enum VariableUseKind { /// A type variable passed as the type argument of a map literal. mapLiteral, - /// A type variable passed as a type argument to a constructor. - constructorTypeArgument, + /// A type variable in a field type. + fieldType, +} - /// A type variable passed as a type argument to a static method. - staticTypeArgument, +/// A type variable in a parameter type of a member. +class MemberParameterVariableUse implements VariableUse { + final ir.Member member; - /// A type variable passed as a type argument to an instance method. - instanceTypeArgument, + MemberParameterVariableUse(this.member); - /// A type variable passed as a type argument to a local function. - localTypeArgument, + @override + int get hashCode => Object.hash(MemberParameterVariableUse, member); - /// A type variable in a parameter type of a member. - memberParameter, + @override + bool operator ==(other) { + if (identical(this, other)) return true; + if (other is! MemberParameterVariableUse) return false; + return member == other.member; + } - /// A type variable in a parameter type of a local function. - localParameter, + @override + String toString() => 'MemberParameterVariableUse(member=$member)'; +} - /// A type variable used in a return type of a member. - memberReturnType, +/// A type variable in a parameter type of a local function. +class LocalParameterVariableUse implements VariableUse { + final ir.LocalFunction localFunction; - /// A type variable used in a return type of a local function. - localReturnType, + LocalParameterVariableUse(this.localFunction); - /// A type variable in a field type. - fieldType, + @override + int get hashCode => Object.hash(LocalParameterVariableUse, localFunction); + + @override + bool operator ==(other) { + if (identical(this, other)) return true; + if (other is! LocalParameterVariableUse) return false; + return localFunction == other.localFunction; + } + + @override + String toString() => + 'LocalParameterVariableUse(localFunction=$localFunction)'; +} + +/// A type variable used in a return type of a member. +class MemberReturnTypeVariableUse implements VariableUse { + final ir.Member member; + + MemberReturnTypeVariableUse(this.member); + + @override + int get hashCode => Object.hash(MemberReturnTypeVariableUse, member); + + @override + bool operator ==(other) { + if (identical(this, other)) return true; + if (other is! MemberReturnTypeVariableUse) return false; + return member == other.member; + } + + @override + String toString() => 'MemberReturnTypeVariableUse(member=$member)'; +} + +/// A type variable used in a return type of a local function. +class LocalReturnTypeVariableUse implements VariableUse { + final ir.LocalFunction localFunction; + + LocalReturnTypeVariableUse(this.localFunction); + + @override + int get hashCode => Object.hash(LocalReturnTypeVariableUse, localFunction); + + @override + bool operator ==(other) { + if (identical(this, other)) return true; + if (other is! LocalReturnTypeVariableUse) return false; + return localFunction == other.localFunction; + } + + @override + String toString() => + 'LocalReturnTypeVariableUse(localFunction=$localFunction)'; +} + +/// A type variable passed as a type argument to a constructor. +class ConstructorTypeArgumentVariableUse implements VariableUse { + final ir.Member member; - /// A type argument of an generic instantiation. - instantiationTypeArgument, + ConstructorTypeArgumentVariableUse(this.member); + + @override + int get hashCode => Object.hash(ConstructorTypeArgumentVariableUse, member); + + @override + bool operator ==(other) { + if (identical(this, other)) return true; + if (other is! ConstructorTypeArgumentVariableUse) return false; + return member == other.member; + } + + @override + String toString() => 'ConstructorTypeArgumentVariableUse(member=$member)'; +} + +/// A type variable passed as a type argument to a static method. +class StaticTypeArgumentVariableUse implements VariableUse { + final ir.Procedure procedure; + + StaticTypeArgumentVariableUse(this.procedure); + + @override + int get hashCode => Object.hash(StaticTypeArgumentVariableUse, procedure); + + @override + bool operator ==(other) { + if (identical(this, other)) return true; + if (other is! StaticTypeArgumentVariableUse) return false; + return procedure == other.procedure; + } + + @override + String toString() => 'StaticTypeArgumentVariableUse(procedure=$procedure)'; } -class VariableUse { - final VariableUseKind kind; - final ir.Member? member; - final ir.LocalFunction? localFunction; - final ir.Expression? invocation; - final ir.Instantiation? instantiation; - - const VariableUse._simple(this.kind) - : this.member = null, - this.localFunction = null, - this.invocation = null, - this.instantiation = null; - - VariableUse.memberParameter(this.member) - : this.kind = VariableUseKind.memberParameter, - this.localFunction = null, - this.invocation = null, - this.instantiation = null; - - VariableUse.localParameter(this.localFunction) - : this.kind = VariableUseKind.localParameter, - this.member = null, - this.invocation = null, - this.instantiation = null; - - VariableUse.memberReturnType(this.member) - : this.kind = VariableUseKind.memberReturnType, - this.localFunction = null, - this.invocation = null, - this.instantiation = null; - - VariableUse.localReturnType(this.localFunction) - : this.kind = VariableUseKind.localReturnType, - this.member = null, - this.invocation = null, - this.instantiation = null; - - VariableUse.constructorTypeArgument(this.member) - : this.kind = VariableUseKind.constructorTypeArgument, - this.localFunction = null, - this.invocation = null, - this.instantiation = null; - - VariableUse.staticTypeArgument(this.member) - : this.kind = VariableUseKind.staticTypeArgument, - this.localFunction = null, - this.invocation = null, - this.instantiation = null; - - VariableUse.instanceTypeArgument(this.invocation) - : this.kind = VariableUseKind.instanceTypeArgument, - this.member = null, - this.localFunction = null, - this.instantiation = null; - - VariableUse.localTypeArgument(this.localFunction, this.invocation) - : this.kind = VariableUseKind.localTypeArgument, - this.member = null, - this.instantiation = null; - - VariableUse.instantiationTypeArgument(this.instantiation) - : this.kind = VariableUseKind.instantiationTypeArgument, - this.member = null, - this.localFunction = null, - this.invocation = null; - - static const VariableUse explicit = - VariableUse._simple(VariableUseKind.explicit); - - static const VariableUse localType = - VariableUse._simple(VariableUseKind.localType); - - static const VariableUse implicitCast = - VariableUse._simple(VariableUseKind.implicitCast); - - static const VariableUse listLiteral = - VariableUse._simple(VariableUseKind.listLiteral); - - static const VariableUse setLiteral = - VariableUse._simple(VariableUseKind.setLiteral); - - static const VariableUse mapLiteral = - VariableUse._simple(VariableUseKind.mapLiteral); - - static const VariableUse fieldType = - VariableUse._simple(VariableUseKind.fieldType); +/// A type variable passed as a type argument to an instance method. +class InstanceTypeArgumentVariableUse implements VariableUse { + final ir.Expression invocation; + + InstanceTypeArgumentVariableUse(this.invocation); + + @override + int get hashCode => Object.hash(InstanceTypeArgumentVariableUse, invocation); + + @override + bool operator ==(other) { + if (identical(this, other)) return true; + if (other is! InstanceTypeArgumentVariableUse) return false; + return invocation == other.invocation; + } + + @override + String toString() => + 'InstanceTypeArgumentVariableUse(invocation=$invocation)'; +} + +/// A type variable passed as a type argument to a local function. +class LocalTypeArgumentVariableUse implements VariableUse { + final ir.LocalFunction localFunction; + final ir.Expression invocation; + + LocalTypeArgumentVariableUse(this.localFunction, this.invocation); + + @override + int get hashCode => + Object.hash(LocalTypeArgumentVariableUse, localFunction, invocation); + + @override + bool operator ==(other) { + if (identical(this, other)) return true; + if (other is! LocalTypeArgumentVariableUse) return false; + return localFunction == other.localFunction && + invocation == other.invocation; + } + + @override + String toString() => + 'LocalTypeArgumentVariableUse(localFunction=$localFunction,invocation=$invocation)'; +} + +/// A type argument of an generic instantiation. +class InstantiationTypeArgumentVariableUse implements VariableUse { + final ir.Instantiation instantiation; + + InstantiationTypeArgumentVariableUse(this.instantiation); @override int get hashCode => - kind.hashCode * 11 + - member.hashCode * 13 + - localFunction.hashCode * 17 + - invocation.hashCode * 19 + - instantiation.hashCode * 23; + Object.hash(InstantiationTypeArgumentVariableUse, instantiation); @override bool operator ==(other) { if (identical(this, other)) return true; - if (other is! VariableUse) return false; - return kind == other.kind && - member == other.member && - localFunction == other.localFunction && - invocation == other.invocation && - instantiation == other.instantiation; + if (other is! InstantiationTypeArgumentVariableUse) return false; + return instantiation == other.instantiation; } @override - String toString() => 'VariableUse(kind=$kind,member=$member,' - 'localFunction=$localFunction,invocation=$invocation,' - 'instantiation=$instantiation)'; + String toString() => + 'InstantiationTypeArgumentVariableUse(instantiation=$instantiation)'; } enum TypeVariableKind { cls, method, local } diff --git a/pkg/compiler/lib/src/ir/scope_visitor.dart b/pkg/compiler/lib/src/ir/scope_visitor.dart index 782dafc23139..41c9b78a16e2 100644 --- a/pkg/compiler/lib/src/ir/scope_visitor.dart +++ b/pkg/compiler/lib/src/ir/scope_visitor.dart @@ -288,7 +288,7 @@ class ScopeModelBuilder extends ir.VisitorDefault @override EvaluationComplexity visitVariableGet(ir.VariableGet node) { - _markVariableAsUsed(node.variable, VariableUse.explicit); + _markVariableAsUsed(node.variable, SimpleVariableUse.explicit); // Don't visit `node.promotedType`. return const EvaluationComplexity.lazy(); } @@ -296,8 +296,8 @@ class ScopeModelBuilder extends ir.VisitorDefault @override EvaluationComplexity visitVariableSet(ir.VariableSet node) { _mutatedVariables.add(node.variable); - _markVariableAsUsed(node.variable, VariableUse.explicit); - visitInContext(node.variable.type, VariableUse.localType); + _markVariableAsUsed(node.variable, SimpleVariableUse.explicit); + visitInContext(node.variable.type, SimpleVariableUse.localType); visitNode(node.value); registerAssignedVariable(node.variable); return const EvaluationComplexity.lazy(); @@ -317,7 +317,7 @@ class ScopeModelBuilder extends ir.VisitorDefault @override EvaluationComplexity visitVariableDeclaration(ir.VariableDeclaration node) { - _handleVariableDeclaration(node, VariableUse.localType); + _handleVariableDeclaration(node, SimpleVariableUse.localType); return const EvaluationComplexity.lazy(); } @@ -338,7 +338,7 @@ class ScopeModelBuilder extends ir.VisitorDefault // optimization: factories have type parameters as function // parameters, and type parameters are declared in the class, not // the factory. - if (usage == VariableUse.explicit) { + if (usage == SimpleVariableUse.explicit) { _currentScopeInfo.freeVariables.add(variable); } else { _currentScopeInfo.freeVariablesForRti @@ -355,7 +355,7 @@ class ScopeModelBuilder extends ir.VisitorDefault @override EvaluationComplexity visitThisExpression(ir.ThisExpression thisExpression) { if (_hasThisLocal) { - _registerNeedsThis(VariableUse.explicit); + _registerNeedsThis(SimpleVariableUse.explicit); } return const EvaluationComplexity.lazy(); } @@ -416,7 +416,7 @@ class ScopeModelBuilder extends ir.VisitorDefault /// type information is checked. void _registerNeedsThis(VariableUse usage) { if (_isInsideClosure) { - if (usage == VariableUse.explicit) { + if (usage == SimpleVariableUse.explicit) { _currentScopeInfo.thisUsedAsFreeVariable = true; } else { _currentScopeInfo.thisUsedAsFreeVariableIfNeedsRti.add(usage); @@ -439,7 +439,7 @@ class ScopeModelBuilder extends ir.VisitorDefault // the underlying StreamIterator. visitInContext( node.variable.type, - VariableUse.constructorTypeArgument( + ConstructorTypeArgumentVariableUse( _coreTypes.streamIteratorDefaultConstructor)); } visitInVariableScope(node, () { @@ -535,11 +535,11 @@ class ScopeModelBuilder extends ir.VisitorDefault EvaluationComplexity visitSuperMethodInvocation( ir.SuperMethodInvocation node) { if (_hasThisLocal) { - _registerNeedsThis(VariableUse.explicit); + _registerNeedsThis(SimpleVariableUse.explicit); } if (node.arguments.types.isNotEmpty) { visitNodesInContext(node.arguments.types, - VariableUse.staticTypeArgument(node.interfaceTarget)); + StaticTypeArgumentVariableUse(node.interfaceTarget)); } visitArguments(node.arguments); return const EvaluationComplexity.lazy(); @@ -548,7 +548,7 @@ class ScopeModelBuilder extends ir.VisitorDefault @override EvaluationComplexity visitSuperPropertySet(ir.SuperPropertySet node) { if (_hasThisLocal) { - _registerNeedsThis(VariableUse.explicit); + _registerNeedsThis(SimpleVariableUse.explicit); } visitNode(node.value); return const EvaluationComplexity.lazy(); @@ -557,7 +557,7 @@ class ScopeModelBuilder extends ir.VisitorDefault @override EvaluationComplexity visitSuperPropertyGet(ir.SuperPropertyGet node) { if (_hasThisLocal) { - _registerNeedsThis(VariableUse.explicit); + _registerNeedsThis(SimpleVariableUse.explicit); } return const EvaluationComplexity.lazy(); } @@ -598,7 +598,7 @@ class ScopeModelBuilder extends ir.VisitorDefault assert(freeVariables.isEmpty || savedIsInsideClosure); for (ir.Node freeVariable in freeVariables) { _capturedVariables.add(freeVariable); - _markVariableAsUsed(freeVariable, VariableUse.explicit); + _markVariableAsUsed(freeVariable, SimpleVariableUse.explicit); } savedScopeInfo.freeVariablesForRti.forEach( (TypeVariableTypeWithContext freeVariableForRti, @@ -633,7 +633,7 @@ class ScopeModelBuilder extends ir.VisitorDefault @override EvaluationComplexity visitField(ir.Field node) { - _currentTypeUsage = VariableUse.fieldType; + _currentTypeUsage = SimpleVariableUse.fieldType; late final EvaluationComplexity complexity; visitInvokable(node, () { assert(node.initializer != null); @@ -776,14 +776,14 @@ class ScopeModelBuilder extends ir.VisitorDefault @override EvaluationComplexity visitTypeLiteral(ir.TypeLiteral node) { - visitInContext(node.type, VariableUse.explicit); + visitInContext(node.type, SimpleVariableUse.explicit); return _evaluateImplicitConstant(node); } @override EvaluationComplexity visitIsExpression(ir.IsExpression node) { EvaluationComplexity complexity = visitNode(node.operand); - visitInContext(node.type, VariableUse.explicit); + visitInContext(node.type, SimpleVariableUse.explicit); if (complexity.isConstant) { return _evaluateImplicitConstant(node); } @@ -793,8 +793,11 @@ class ScopeModelBuilder extends ir.VisitorDefault @override EvaluationComplexity visitAsExpression(ir.AsExpression node) { EvaluationComplexity complexity = visitNode(node.operand); - visitInContext(node.type, - node.isTypeError ? VariableUse.implicitCast : VariableUse.explicit); + visitInContext( + node.type, + node.isTypeError + ? SimpleVariableUse.implicitCast + : SimpleVariableUse.explicit); if (complexity.isConstant) { return _evaluateImplicitConstant(node); } @@ -836,8 +839,8 @@ class ScopeModelBuilder extends ir.VisitorDefault EvaluationComplexity visitFunctionNode(ir.FunctionNode node) { final parent = node.parent; VariableUse parameterUsage = parent is ir.Member - ? VariableUse.memberParameter(parent) - : VariableUse.localParameter(parent as ir.LocalFunction?); + ? MemberParameterVariableUse(parent) + : LocalParameterVariableUse(parent as ir.LocalFunction); visitNodesInContext(node.typeParameters, parameterUsage); for (ir.VariableDeclaration declaration in node.positionalParameters) { _handleVariableDeclaration(declaration, parameterUsage); @@ -848,8 +851,8 @@ class ScopeModelBuilder extends ir.VisitorDefault visitInContext( node.returnType, parent is ir.Member - ? VariableUse.memberReturnType(parent) - : VariableUse.localReturnType(parent as ir.LocalFunction)); + ? MemberReturnTypeVariableUse(parent) + : LocalReturnTypeVariableUse(parent as ir.LocalFunction)); if (node.body != null) { visitNode(node.body!); } @@ -859,7 +862,7 @@ class ScopeModelBuilder extends ir.VisitorDefault @override EvaluationComplexity visitListLiteral(ir.ListLiteral node) { EvaluationComplexity complexity = - visitInContext(node.typeArgument, VariableUse.listLiteral); + visitInContext(node.typeArgument, SimpleVariableUse.listLiteral); complexity = complexity.combine(visitExpressions(node.expressions)); if (node.isConst) { return const EvaluationComplexity.constant(); @@ -875,7 +878,7 @@ class ScopeModelBuilder extends ir.VisitorDefault @override EvaluationComplexity visitSetLiteral(ir.SetLiteral node) { EvaluationComplexity complexity = - visitInContext(node.typeArgument, VariableUse.setLiteral); + visitInContext(node.typeArgument, SimpleVariableUse.setLiteral); complexity = complexity.combine(visitExpressions(node.expressions)); if (node.isConst) { return const EvaluationComplexity.constant(); @@ -893,9 +896,9 @@ class ScopeModelBuilder extends ir.VisitorDefault @override EvaluationComplexity visitMapLiteral(ir.MapLiteral node) { EvaluationComplexity complexity = - visitInContext(node.keyType, VariableUse.mapLiteral); + visitInContext(node.keyType, SimpleVariableUse.mapLiteral); complexity = complexity - .combine(visitInContext(node.valueType, VariableUse.mapLiteral)); + .combine(visitInContext(node.valueType, SimpleVariableUse.mapLiteral)); complexity = complexity.combine(visitNodes(node.entries)); if (node.isConst) { return const EvaluationComplexity.constant(); @@ -1009,9 +1012,9 @@ class ScopeModelBuilder extends ir.VisitorDefault if (node.arguments.types.isNotEmpty) { VariableUse usage; if (node.target.kind == ir.ProcedureKind.Factory) { - usage = VariableUse.constructorTypeArgument(node.target); + usage = ConstructorTypeArgumentVariableUse(node.target); } else { - usage = VariableUse.staticTypeArgument(node.target); + usage = StaticTypeArgumentVariableUse(node.target); } visitNodesInContext(node.arguments.types, usage); @@ -1049,7 +1052,7 @@ class ScopeModelBuilder extends ir.VisitorDefault if (node.arguments.types.isNotEmpty) { visitNodesInContext( - node.arguments.types, VariableUse.constructorTypeArgument(target)); + node.arguments.types, ConstructorTypeArgumentVariableUse(target)); } visitArguments(node.arguments); return node.isConst @@ -1085,7 +1088,7 @@ class ScopeModelBuilder extends ir.VisitorDefault receiver.variable.parent is ir.LocalFunction), "Unexpected local function invocation ${node} " "(${node.runtimeType})."); - VariableUse usage = VariableUse.instanceTypeArgument(node); + final usage = InstanceTypeArgumentVariableUse(node); visitNodesInContext(node.arguments.types, usage); } EvaluationComplexity complexity = visitArguments(node.arguments); @@ -1112,7 +1115,7 @@ class ScopeModelBuilder extends ir.VisitorDefault receiver.variable.parent is ir.LocalFunction), "Unexpected local function invocation ${node} " "(${node.runtimeType})."); - VariableUse usage = VariableUse.instanceTypeArgument(node); + final usage = InstanceTypeArgumentVariableUse(node); visitNodesInContext(node.arguments.types, usage); } visitArguments(node.arguments); @@ -1129,7 +1132,7 @@ class ScopeModelBuilder extends ir.VisitorDefault receiver.variable.parent is ir.LocalFunction), "Unexpected local function invocation ${node} " "(${node.runtimeType})."); - VariableUse usage = VariableUse.instanceTypeArgument(node); + final usage = InstanceTypeArgumentVariableUse(node); visitNodesInContext(node.arguments.types, usage); } visitArguments(node.arguments); @@ -1146,7 +1149,7 @@ class ScopeModelBuilder extends ir.VisitorDefault is ir.LocalFunction)), "Unexpected local function invocation ${node} " "(${node.runtimeType})."); - VariableUse usage = VariableUse.instanceTypeArgument(node); + final usage = InstanceTypeArgumentVariableUse(node); visitNodesInContext(node.arguments.types, usage); } visitArguments(node.arguments); @@ -1156,10 +1159,9 @@ class ScopeModelBuilder extends ir.VisitorDefault @override EvaluationComplexity visitLocalFunctionInvocation( ir.LocalFunctionInvocation node) { - _markVariableAsUsed(node.variable, VariableUse.explicit); + _markVariableAsUsed(node.variable, SimpleVariableUse.explicit); if (node.arguments.types.isNotEmpty) { - VariableUse usage = - VariableUse.localTypeArgument(node.localFunction, node); + final usage = LocalTypeArgumentVariableUse(node.localFunction, node); visitNodesInContext(node.arguments.types, usage); } visitArguments(node.arguments); @@ -1279,7 +1281,7 @@ class ScopeModelBuilder extends ir.VisitorDefault @override EvaluationComplexity visitCatch(ir.Catch node) { - visitInContext(node.guard, VariableUse.explicit); + visitInContext(node.guard, SimpleVariableUse.explicit); if (node.exception != null) { visitNode(node.exception!); } @@ -1295,7 +1297,7 @@ class ScopeModelBuilder extends ir.VisitorDefault @override EvaluationComplexity visitInstantiation(ir.Instantiation node) { EvaluationComplexity typeArgumentsComplexity = visitNodesInContext( - node.typeArguments, VariableUse.instantiationTypeArgument(node)); + node.typeArguments, InstantiationTypeArgumentVariableUse(node)); EvaluationComplexity expressionComplexity = visitNode(node.expression); EvaluationComplexity complexity = @@ -1403,7 +1405,7 @@ class ScopeModelBuilder extends ir.VisitorDefault EvaluationComplexity visitSuperInitializer(ir.SuperInitializer node) { if (node.arguments.types.isNotEmpty) { visitNodesInContext(node.arguments.types, - VariableUse.constructorTypeArgument(node.target)); + ConstructorTypeArgumentVariableUse(node.target)); } visitArguments(node.arguments); return const EvaluationComplexity.lazy(); @@ -1414,7 +1416,7 @@ class ScopeModelBuilder extends ir.VisitorDefault ir.RedirectingInitializer node) { if (node.arguments.types.isNotEmpty) { visitNodesInContext(node.arguments.types, - VariableUse.constructorTypeArgument(node.target)); + ConstructorTypeArgumentVariableUse(node.target)); } visitArguments(node.arguments); return const EvaluationComplexity.lazy(); diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart index 97be79dc3be2..4af7d4323211 100644 --- a/pkg/compiler/lib/src/js_model/closure.dart +++ b/pkg/compiler/lib/src/js_model/closure.dart @@ -226,55 +226,56 @@ class ClosureDataBuilder { MemberEntity outermostEntity) { bool includeForRti(Set useSet) { for (VariableUse usage in useSet) { - switch (usage.kind) { - case VariableUseKind.explicit: + switch (usage) { + case SimpleVariableUse.explicit: return true; - case VariableUseKind.implicitCast: + case SimpleVariableUse.implicitCast: if (_annotationsData .getImplicitDowncastCheckPolicy(outermostEntity) .isEmitted) { return true; } break; - case VariableUseKind.localType: + case SimpleVariableUse.localType: break; - case VariableUseKind.constructorTypeArgument: - ConstructorEntity constructor = - _elementMap.getConstructor(usage.member!); + case ConstructorTypeArgumentVariableUse(:final member): + ConstructorEntity constructor = _elementMap.getConstructor(member); if (rtiNeed.classNeedsTypeArguments(constructor.enclosingClass)) { return true; } break; - case VariableUseKind.staticTypeArgument: - FunctionEntity method = - _elementMap.getMethod(usage.member as ir.Procedure); + case StaticTypeArgumentVariableUse(:final procedure): + FunctionEntity method = _elementMap.getMethod(procedure); if (rtiNeed.methodNeedsTypeArguments(method)) { return true; } break; - case VariableUseKind.instanceTypeArgument: - Selector selector = _elementMap.getSelector(usage.invocation!); + case InstanceTypeArgumentVariableUse(:final invocation): + Selector selector = _elementMap.getSelector(invocation); if (rtiNeed.selectorNeedsTypeArguments(selector)) { return true; } break; - case VariableUseKind.localTypeArgument: + case LocalTypeArgumentVariableUse( + :final localFunction, + :final invocation + ): // TODO(johnniwinther): We should be able to track direct local // function invocations and not have to use the selector here. - Selector selector = _elementMap.getSelector(usage.invocation!); - if (rtiNeed.localFunctionNeedsTypeArguments(usage.localFunction!) || + Selector selector = _elementMap.getSelector(invocation); + if (rtiNeed.localFunctionNeedsTypeArguments(localFunction) || rtiNeed.selectorNeedsTypeArguments(selector)) { return true; } break; - case VariableUseKind.memberParameter: + case MemberParameterVariableUse(:final member): if (_annotationsData .getParameterCheckPolicy(outermostEntity) .isEmitted) { return true; } else { FunctionEntity method = - _elementMap.getMethod(usage.member as ir.Procedure); + _elementMap.getMethod(member as ir.Procedure); if (rtiNeed.methodNeedsSignature(method)) { return true; } @@ -285,67 +286,64 @@ class ClosureDataBuilder { } } break; - case VariableUseKind.localParameter: + case LocalParameterVariableUse(:final localFunction): if (_annotationsData .getParameterCheckPolicy(outermostEntity) .isEmitted) { return true; - } else if (rtiNeed - .localFunctionNeedsSignature(usage.localFunction!)) { + } else if (rtiNeed.localFunctionNeedsSignature(localFunction)) { return true; - } else if (rtiNeed - .localFunctionNeedsTypeArguments(usage.localFunction!)) { + } else if (rtiNeed.localFunctionNeedsTypeArguments(localFunction)) { // Stubs generated for this local function might make use of this // type parameter for default type arguments. return true; } break; - case VariableUseKind.memberReturnType: + case MemberReturnTypeVariableUse(:final member): FunctionEntity method = - _elementMap.getMethod(usage.member as ir.Procedure); + _elementMap.getMethod(member as ir.Procedure); if (rtiNeed.methodNeedsSignature(method)) { return true; } break; - case VariableUseKind.localReturnType: - if (usage.localFunction!.function.asyncMarker != - ir.AsyncMarker.Sync) { + case LocalReturnTypeVariableUse(:final localFunction): + if (localFunction.function.asyncMarker != ir.AsyncMarker.Sync) { // The Future/Iterator/Stream implementation requires the type. return true; } - if (rtiNeed.localFunctionNeedsSignature(usage.localFunction!)) { + if (rtiNeed.localFunctionNeedsSignature(localFunction)) { return true; } break; - case VariableUseKind.fieldType: + case SimpleVariableUse.fieldType: if (_annotationsData .getParameterCheckPolicy(outermostEntity) .isEmitted) { return true; } break; - case VariableUseKind.listLiteral: + case SimpleVariableUse.listLiteral: if (rtiNeed.classNeedsTypeArguments( _elementMap.commonElements.jsArrayClass)) { return true; } break; - case VariableUseKind.setLiteral: + case SimpleVariableUse.setLiteral: if (rtiNeed.classNeedsTypeArguments( _elementMap.commonElements.setLiteralClass)) { return true; } break; - case VariableUseKind.mapLiteral: + case SimpleVariableUse.mapLiteral: if (rtiNeed.classNeedsTypeArguments( _elementMap.commonElements.mapLiteralClass)) { return true; } break; - case VariableUseKind.instantiationTypeArgument: + case InstantiationTypeArgumentVariableUse(:final instantiation): // TODO(johnniwinther): Use the static type of the expression. if (rtiNeed.instantiationNeedsTypeArguments( - null, usage.instantiation!.typeArguments.length)) { + null, instantiation.typeArguments.length)) { return true; } break;