Skip to content

Commit

Permalink
[dart2js] Convert VariableUse to a sealed class hierarchy.
Browse files Browse the repository at this point in the history
Change-Id: I28d71d81031e3e6eefc2b4f6decfe375099a1c32
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371185
Reviewed-by: Stephen Adams <[email protected]>
Commit-Queue: Mayank Patke <[email protected]>
  • Loading branch information
fishythefish authored and Commit Queue committed Jun 13, 2024
1 parent 18994e6 commit bf83cc3
Show file tree
Hide file tree
Showing 3 changed files with 247 additions and 195 deletions.
294 changes: 173 additions & 121 deletions pkg/compiler/lib/src/ir/closure.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 }
Expand Down
Loading

0 comments on commit bf83cc3

Please sign in to comment.