[cfe] Make ConstantVisitor(1) a pure interface

This splits ConstantVisitor(1) into a pure interface and a
ConstantVisitor(1)DefaultMixin with the base implementation. This is
a step towards avoid having an accidental default implementation where
a static error would have been preferable.

Also removes BodyVisitor1 which was unused.

TEST=existing

Change-Id: I265754e13e0ebcce5c154b16c7ee36854f4ce9fe
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/325400
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Johnni Winther 2023-09-13 14:02:28 +00:00 committed by Commit Queue
parent 79ad624ef0
commit 36b93f6b08
28 changed files with 434 additions and 189 deletions

View file

@ -2298,8 +2298,10 @@ class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation?>
}
}
// TODO(fishythefish): Remove default mixin.
class TypeInformationConstantVisitor
extends ir.ComputeOnceConstantVisitor<TypeInformation> {
extends ir.ComputeOnceConstantVisitor<TypeInformation>
with ir.OnceConstantVisitorDefaultMixin<TypeInformation> {
final KernelTypeGraphBuilder builder;
final ir.ConstantExpression expression;

View file

@ -220,7 +220,9 @@ class ImpactBuilderData {
}
}
class ConstantImpactVisitor extends ir.VisitOnceConstantVisitor {
// TODO(fishythefish): Remove default mixin.
class ConstantImpactVisitor extends ir.VisitOnceConstantVisitor
with ir.OnceConstantVisitorDefaultMixin<void> {
final ImpactRegistry registry;
final ir.LibraryDependency? import;
final ir.ConstantExpression expression;

View file

@ -225,7 +225,9 @@ class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
}
}
class ConstantValuefier extends ir.ComputeOnceConstantVisitor<ConstantValue> {
// TODO(fishythefish): Remove default mixin.
class ConstantValuefier extends ir.ComputeOnceConstantVisitor<ConstantValue>
with ir.OnceConstantVisitorDefaultMixin<ConstantValue> {
final IrToElementMap elementMap;
ConstantValuefier(this.elementMap);

View file

@ -413,10 +413,4 @@ class ConstantNodeIndexerVisitor implements ir.ConstantVisitor<void> {
void visitNullConstant(ir.NullConstant node) {
_register(node);
}
@override
void defaultConstant(ir.Constant node) {
throw UnimplementedError(
"Unexpected constant: $node (${node.runtimeType})");
}
}

View file

@ -108,7 +108,8 @@ class Constants {
}
}
class ConstantInstantiator extends ConstantVisitor<w.ValueType> {
class ConstantInstantiator extends ConstantVisitor<w.ValueType>
with ConstantVisitorDefaultMixin<w.ValueType> {
final Constants constants;
final w.BaseFunction? function;
final w.InstructionsBuilder b;
@ -222,7 +223,8 @@ class ConstantInstantiator extends ConstantVisitor<w.ValueType> {
}
}
class ConstantCreator extends ConstantVisitor<ConstantInfo?> {
class ConstantCreator extends ConstantVisitor<ConstantInfo?>
with ConstantVisitorDefaultMixin<ConstantInfo?> {
final Constants constants;
ConstantCreator(this.constants);

View file

@ -50,7 +50,9 @@ import 'type_recipe_generator.dart';
import 'type_table.dart';
class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
with SharedCompiler<Library, Class, InterfaceType, FunctionNode>
with
SharedCompiler<Library, Class, InterfaceType, FunctionNode>,
OnceConstantVisitorDefaultMixin<js_ast.Expression>
implements
StatementVisitor<js_ast.Statement>,
ExpressionVisitor<js_ast.Expression>,

View file

@ -175,10 +175,6 @@ class ConstantWeakener extends ComputeOnceConstantVisitor<Constant?> {
return value;
}
@override
Constant? defaultConstant(Constant node) => throw new UnsupportedError(
"Unhandled constant ${node} (${node.runtimeType})");
@override
Constant? visitNullConstant(NullConstant node) => null;
@ -353,6 +349,34 @@ class ConstantWeakener extends ComputeOnceConstantVisitor<Constant?> {
@override
Constant? visitUnevaluatedConstant(UnevaluatedConstant node) => null;
@override
Constant? visitConstructorTearOffConstant(ConstructorTearOffConstant node) =>
null;
@override
Constant? visitRedirectingFactoryTearOffConstant(
RedirectingFactoryTearOffConstant node) =>
null;
@override
Constant? visitTypedefTearOffConstant(TypedefTearOffConstant node) {
List<DartType>? types;
for (int index = 0; index < node.types.length; index++) {
DartType? type = computeConstCanonicalType(
node.types[index], _evaluator.coreTypes,
isNonNullableByDefault: _evaluator.isNonNullableByDefault);
if (type != null) {
types ??= node.types.toList(growable: false);
types[index] = type;
}
}
if (types != null) {
return new TypedefTearOffConstant(
node.parameters, node.tearOffConstant, types);
}
return null;
}
}
class ConstantsTransformer extends RemovingTransformer {

View file

@ -109,9 +109,6 @@ class _ErrorReporter implements ErrorReporter {
class UnevaluatedConstantFinder extends ComputeOnceConstantVisitor<bool> {
UnevaluatedConstantFinder();
@override
bool defaultConstant(Constant node) => false;
@override
bool visitUnevaluatedConstant(UnevaluatedConstant node) => true;
@ -173,4 +170,40 @@ class UnevaluatedConstantFinder extends ComputeOnceConstantVisitor<bool> {
}
return false;
}
@override
bool visitBoolConstant(BoolConstant node) => false;
@override
bool visitConstructorTearOffConstant(ConstructorTearOffConstant node) =>
false;
@override
bool visitDoubleConstant(DoubleConstant node) => false;
@override
bool visitIntConstant(IntConstant node) => false;
@override
bool visitNullConstant(NullConstant node) => false;
@override
bool visitRedirectingFactoryTearOffConstant(
RedirectingFactoryTearOffConstant node) =>
false;
@override
bool visitStaticTearOffConstant(StaticTearOffConstant node) => false;
@override
bool visitStringConstant(StringConstant node) => false;
@override
bool visitSymbolConstant(SymbolConstant node) => false;
@override
bool visitTypeLiteralConstant(TypeLiteralConstant node) => false;
@override
bool visitTypedefTearOffConstant(TypedefTearOffConstant node) => false;
}

View file

@ -310,9 +310,6 @@ class TypeLabeler implements DartTypeVisitor<void>, ConstantVisitor<void> {
addNullability(node.nullability);
}
@override
void defaultConstant(Constant node) {}
@override
void visitNullConstant(NullConstant node) {
result.add('${node.value}');

View file

@ -339,10 +339,6 @@ class ConstantToTextVisitor implements ConstantVisitor<void> {
}
}
@override
void defaultConstant(Constant node) => throw new UnimplementedError(
'Unexpected constant $node (${node.runtimeType})');
@override
void visitNullConstant(NullConstant node) {
sb.write('Null()');

View file

@ -377,6 +377,7 @@ degrades
degree
del
delegated
delegating
delimit
delimiting
demands

View file

@ -0,0 +1,2 @@
--force-constructor-tear-off-lowering=0
--nnbd-agnostic

View file

@ -0,0 +1,12 @@
// Copyright (c) 2023, 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.
import 'main_lib.dart';
test() {
const a = C.new;
const b = D.new;
var m = const {C.new: true, D.new: false};
var n = const {c: true, d: false};
}

View file

@ -0,0 +1,34 @@
library;
import self as self;
import "dart:core" as core;
import "main_lib.dart" as mai;
import "org-dartlang-testcase:///main_lib.dart";
static method test() → dynamic {
core::Map<<unrelated T extends core::Object? = dynamic>() → mai::A<core::int?>, core::bool> m = #C6;
core::Map<<unrelated T extends core::Object? = dynamic>() → mai::A<core::int?>, core::bool> n = #C6;
}
library;
import self as mai;
import "dart:core" as core;
typedef C<unrelated T extends core::Object? = dynamic> = mai::A<core::int>;
typedef D<unrelated T extends core::Object? = dynamic> = mai::A<core::int?>;
class A<T extends core::Object? = dynamic> extends core::Object {
constructor •() → mai::A<mai::A::T%>
: super core::Object::•()
;
}
static const field <unrelated T extends core::Object? = dynamic>() → mai::A<core::int> c = #C2;
static const field <unrelated T extends core::Object? = dynamic>() → mai::A<core::int?> d = #C4;
constants {
#C1 = constructor-tearoff mai::A::•
#C2 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
#C3 = true
#C4 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int?>)
#C5 = false
#C6 = <<unrelated T extends core::Object? = dynamic>() → mai::A<core::int?>, core::bool>{#C2:#C3, #C4:#C5}
}

View file

@ -0,0 +1,34 @@
library;
import self as self;
import "dart:core" as core;
import "main_lib.dart" as mai;
import "org-dartlang-testcase:///main_lib.dart";
static method test() → dynamic {
core::Map<<unrelated T extends core::Object? = dynamic>() → mai::A<core::int?>, core::bool> m = #C6;
core::Map<<unrelated T extends core::Object? = dynamic>() → mai::A<core::int?>, core::bool> n = #C6;
}
library;
import self as mai;
import "dart:core" as core;
typedef C<unrelated T extends core::Object? = dynamic> = mai::A<core::int>;
typedef D<unrelated T extends core::Object? = dynamic> = mai::A<core::int?>;
class A<T extends core::Object? = dynamic> extends core::Object {
constructor •() → mai::A<mai::A::T%>
: super core::Object::•()
;
}
static const field <unrelated T extends core::Object? = dynamic>() → mai::A<core::int> c = #C2;
static const field <unrelated T extends core::Object? = dynamic>() → mai::A<core::int?> d = #C4;
constants {
#C1 = constructor-tearoff mai::A::•
#C2 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
#C3 = true
#C4 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int?>)
#C5 = false
#C6 = <<unrelated T extends core::Object? = dynamic>() → mai::A<core::int?>, core::bool>{#C2:#C3, #C4:#C5}
}

View file

@ -0,0 +1,3 @@
import 'main_lib.dart';
test() {}

View file

@ -0,0 +1,3 @@
import 'main_lib.dart';
test() {}

View file

@ -0,0 +1,34 @@
library;
import self as self;
import "dart:core" as core;
import "main_lib.dart" as mai;
import "org-dartlang-testcase:///main_lib.dart";
static method test() → dynamic {
core::Map<<unrelated T extends core::Object? = dynamic>() → mai::A<core::int?>, core::bool> m = #C6;
core::Map<<unrelated T extends core::Object? = dynamic>() → mai::A<core::int?>, core::bool> n = #C6;
}
library;
import self as mai;
import "dart:core" as core;
typedef C<unrelated T extends core::Object? = dynamic> = mai::A<core::int>;
typedef D<unrelated T extends core::Object? = dynamic> = mai::A<core::int?>;
class A<T extends core::Object? = dynamic> extends core::Object {
constructor •() → mai::A<mai::A::T%>
: super core::Object::•()
;
}
static const field <unrelated T extends core::Object? = dynamic>() → mai::A<core::int> c = #C2;
static const field <unrelated T extends core::Object? = dynamic>() → mai::A<core::int?> d = #C4;
constants {
#C1 = constructor-tearoff mai::A::•
#C2 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
#C3 = true
#C4 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int?>)
#C5 = false
#C6 = <<unrelated T extends core::Object? = dynamic>() →* mai::A<core::int?>*, core::bool*>{#C2:#C3, #C4:#C5}
}

View file

@ -0,0 +1,20 @@
library;
import self as self;
import "dart:core" as core;
import "main_lib.dart" as mai;
import "org-dartlang-testcase:///main_lib.dart";
static method test() → dynamic {
core::Map<<unrelated T extends core::Object? = dynamic>() → mai::A<core::int?>, core::bool> m = #C6;
core::Map<<unrelated T extends core::Object? = dynamic>() → mai::A<core::int?>, core::bool> n = #C6;
}
constants {
#C1 = constructor-tearoff mai::A::•
#C2 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
#C3 = true
#C4 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int?>)
#C5 = false
#C6 = <<unrelated T extends core::Object? = dynamic>() →* mai::A<core::int?>*, core::bool*>{#C2:#C3, #C4:#C5}
}

View file

@ -0,0 +1,26 @@
library;
import self as self;
import "org-dartlang-testcase:///main_lib.dart";
static method test() → dynamic
;
library;
import self as self2;
import "dart:core" as core;
typedef C<unrelated T extends core::Object? = dynamic> = self2::A<core::int>;
typedef D<unrelated T extends core::Object? = dynamic> = self2::A<core::int?>;
class A<T extends core::Object? = dynamic> extends core::Object {
constructor •() → self2::A<self2::A::T%>
;
}
static const field <unrelated T extends core::Object? = dynamic>() → self2::A<core::int> c = #C2;
static const field <unrelated T extends core::Object? = dynamic>() → self2::A<core::int?> d = #C3;
constants {
#C1 = constructor-tearoff self2::A::•
#C2 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
#C3 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int?>)
}

View file

@ -0,0 +1,34 @@
library;
import self as self;
import "dart:core" as core;
import "main_lib.dart" as mai;
import "org-dartlang-testcase:///main_lib.dart";
static method test() → dynamic {
core::Map<<unrelated T extends core::Object? = dynamic>() → mai::A<core::int?>, core::bool> m = #C6;
core::Map<<unrelated T extends core::Object? = dynamic>() → mai::A<core::int?>, core::bool> n = #C6;
}
library;
import self as mai;
import "dart:core" as core;
typedef C<unrelated T extends core::Object? = dynamic> = mai::A<core::int>;
typedef D<unrelated T extends core::Object? = dynamic> = mai::A<core::int?>;
class A<T extends core::Object? = dynamic> extends core::Object {
constructor •() → mai::A<mai::A::T%>
: super core::Object::•()
;
}
static const field <unrelated T extends core::Object? = dynamic>() → mai::A<core::int> c = #C2;
static const field <unrelated T extends core::Object? = dynamic>() → mai::A<core::int?> d = #C4;
constants {
#C1 = constructor-tearoff mai::A::•
#C2 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
#C3 = true
#C4 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int?>)
#C5 = false
#C6 = <<unrelated T extends core::Object? = dynamic>() →* mai::A<core::int?>*, core::bool*>{#C2:#C3, #C4:#C5}
}

View file

@ -0,0 +1,13 @@
// Copyright (c) 2023, 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.
class A<T> {
A();
}
typedef C<T> = A<int>;
typedef D<T> = A<int?>;
const c = C.new;
const d = D.new;

View file

@ -0,0 +1 @@
main_lib.dart

View file

@ -48,10 +48,6 @@ class ConstantReplacer implements ConstantVisitor<Constant?> {
return newConstants;
}
/// By default, don't change the [node].
@override
Constant? defaultConstant(Constant node) => null;
/// Visits [node] if not already visited to compute a value for [node].
///
/// If the value has already been computed the cached value is returned
@ -65,35 +61,34 @@ class ConstantReplacer implements ConstantVisitor<Constant?> {
}
@override
Constant? visitBoolConstant(BoolConstant node) => defaultConstant(node);
Constant? visitBoolConstant(BoolConstant node) => null;
@override
Constant? visitConstructorTearOffConstant(ConstructorTearOffConstant node) =>
defaultConstant(node);
null;
@override
Constant? visitDoubleConstant(DoubleConstant node) => defaultConstant(node);
Constant? visitDoubleConstant(DoubleConstant node) => null;
@override
Constant? visitIntConstant(IntConstant node) => defaultConstant(node);
Constant? visitIntConstant(IntConstant node) => null;
@override
Constant? visitNullConstant(NullConstant node) => defaultConstant(node);
Constant? visitNullConstant(NullConstant node) => null;
@override
Constant? visitRedirectingFactoryTearOffConstant(
RedirectingFactoryTearOffConstant node) =>
defaultConstant(node);
null;
@override
Constant? visitStaticTearOffConstant(StaticTearOffConstant node) =>
defaultConstant(node);
Constant? visitStaticTearOffConstant(StaticTearOffConstant node) => null;
@override
Constant? visitStringConstant(StringConstant node) => defaultConstant(node);
Constant? visitStringConstant(StringConstant node) => null;
@override
Constant? visitSymbolConstant(SymbolConstant node) => defaultConstant(node);
Constant? visitSymbolConstant(SymbolConstant node) => null;
@override
Constant? visitInstanceConstant(InstanceConstant node) {

View file

@ -919,6 +919,8 @@ abstract class DartTypeVisitor<R> {
R visitRecordType(RecordType node);
}
/// Helper mixin for [DartTypeVisitor] that implements visit methods by
/// delegating to the [defaultDartType] method.
mixin DartTypeVisitorDefaultMixin<R> implements DartTypeVisitor<R> {
@override
R defaultDartType(DartType node);
@ -972,6 +974,8 @@ abstract class DartTypeVisitor1<R, A> {
R visitRecordType(RecordType node, A arg);
}
/// Helper mixin for [DartTypeVisitor1] that implements visit methods by
/// delegating to the [defaultDartType] method.
mixin DartTypeVisitor1DefaultMixin<R, A> implements DartTypeVisitor1<R, A> {
@override
R defaultDartType(DartType node, A arg);
@ -1017,75 +1021,157 @@ mixin DartTypeVisitor1DefaultMixin<R, A> implements DartTypeVisitor1<R, A> {
abstract class ConstantVisitor<R> {
const ConstantVisitor();
R visitNullConstant(NullConstant node);
R visitBoolConstant(BoolConstant node);
R visitIntConstant(IntConstant node);
R visitDoubleConstant(DoubleConstant node);
R visitStringConstant(StringConstant node);
R visitSymbolConstant(SymbolConstant node);
R visitMapConstant(MapConstant node);
R visitListConstant(ListConstant node);
R visitSetConstant(SetConstant node);
R visitRecordConstant(RecordConstant node);
R visitInstanceConstant(InstanceConstant node);
R visitInstantiationConstant(InstantiationConstant node);
R visitTypedefTearOffConstant(TypedefTearOffConstant node);
R visitStaticTearOffConstant(StaticTearOffConstant node);
R visitConstructorTearOffConstant(ConstructorTearOffConstant node);
R visitRedirectingFactoryTearOffConstant(
RedirectingFactoryTearOffConstant node);
R visitTypeLiteralConstant(TypeLiteralConstant node);
R visitUnevaluatedConstant(UnevaluatedConstant node);
}
/// Helper mixin for [ConstantVisitor] that implements visit methods by
/// delegating to the [defaultConstant] method.
mixin ConstantVisitorDefaultMixin<R> implements ConstantVisitor<R> {
R defaultConstant(Constant node);
@override
R visitNullConstant(NullConstant node) => defaultConstant(node);
@override
R visitBoolConstant(BoolConstant node) => defaultConstant(node);
@override
R visitIntConstant(IntConstant node) => defaultConstant(node);
@override
R visitDoubleConstant(DoubleConstant node) => defaultConstant(node);
@override
R visitStringConstant(StringConstant node) => defaultConstant(node);
@override
R visitSymbolConstant(SymbolConstant node) => defaultConstant(node);
@override
R visitMapConstant(MapConstant node) => defaultConstant(node);
@override
R visitListConstant(ListConstant node) => defaultConstant(node);
@override
R visitSetConstant(SetConstant node) => defaultConstant(node);
@override
R visitRecordConstant(RecordConstant node) => defaultConstant(node);
@override
R visitInstanceConstant(InstanceConstant node) => defaultConstant(node);
@override
R visitInstantiationConstant(InstantiationConstant node) =>
defaultConstant(node);
@override
R visitTypedefTearOffConstant(TypedefTearOffConstant node) =>
defaultConstant(node);
@override
R visitStaticTearOffConstant(StaticTearOffConstant node) =>
defaultConstant(node);
@override
R visitConstructorTearOffConstant(ConstructorTearOffConstant node) =>
defaultConstant(node);
@override
R visitRedirectingFactoryTearOffConstant(
RedirectingFactoryTearOffConstant node) =>
defaultConstant(node);
@override
R visitTypeLiteralConstant(TypeLiteralConstant node) => defaultConstant(node);
@override
R visitUnevaluatedConstant(UnevaluatedConstant node) => defaultConstant(node);
}
abstract class ConstantVisitor1<R, A> {
const ConstantVisitor1();
R visitNullConstant(NullConstant node, A arg);
R visitBoolConstant(BoolConstant node, A arg);
R visitIntConstant(IntConstant node, A arg);
R visitDoubleConstant(DoubleConstant node, A arg);
R visitStringConstant(StringConstant node, A arg);
R visitSymbolConstant(SymbolConstant node, A arg);
R visitMapConstant(MapConstant node, A arg);
R visitListConstant(ListConstant node, A arg);
R visitSetConstant(SetConstant node, A arg);
R visitRecordConstant(RecordConstant node, A arg);
R visitInstanceConstant(InstanceConstant node, A arg);
R visitInstantiationConstant(InstantiationConstant node, A arg);
R visitStaticTearOffConstant(StaticTearOffConstant node, A arg);
R visitTypedefTearOffConstant(TypedefTearOffConstant node, A arg);
R visitConstructorTearOffConstant(ConstructorTearOffConstant node, A arg);
R visitRedirectingFactoryTearOffConstant(
RedirectingFactoryTearOffConstant node, A arg);
R visitTypeLiteralConstant(TypeLiteralConstant node, A arg);
R visitUnevaluatedConstant(UnevaluatedConstant node, A arg);
}
/// Helper mixin for [ConstantVisitor1] that implements visit methods by
/// delegating to the [defaultConstant] method.
mixin ConstantVisitor1DefaultMixin<R, A> implements ConstantVisitor1<R, A> {
R defaultConstant(Constant node, A arg);
@override
R visitNullConstant(NullConstant node, A arg) => defaultConstant(node, arg);
@override
R visitBoolConstant(BoolConstant node, A arg) => defaultConstant(node, arg);
@override
R visitIntConstant(IntConstant node, A arg) => defaultConstant(node, arg);
@override
R visitDoubleConstant(DoubleConstant node, A arg) =>
defaultConstant(node, arg);
@override
R visitStringConstant(StringConstant node, A arg) =>
defaultConstant(node, arg);
@override
R visitSymbolConstant(SymbolConstant node, A arg) =>
defaultConstant(node, arg);
@override
R visitMapConstant(MapConstant node, A arg) => defaultConstant(node, arg);
@override
R visitListConstant(ListConstant node, A arg) => defaultConstant(node, arg);
@override
R visitSetConstant(SetConstant node, A arg) => defaultConstant(node, arg);
@override
R visitRecordConstant(RecordConstant node, A arg) =>
defaultConstant(node, arg);
@override
R visitInstanceConstant(InstanceConstant node, A arg) =>
defaultConstant(node, arg);
@override
R visitInstantiationConstant(InstantiationConstant node, A arg) =>
defaultConstant(node, arg);
@override
R visitStaticTearOffConstant(StaticTearOffConstant node, A arg) =>
defaultConstant(node, arg);
@override
R visitTypedefTearOffConstant(TypedefTearOffConstant node, A arg) =>
defaultConstant(node, arg);
@override
R visitConstructorTearOffConstant(ConstructorTearOffConstant node, A arg) =>
defaultConstant(node, arg);
@override
R visitRedirectingFactoryTearOffConstant(
RedirectingFactoryTearOffConstant node, A arg) =>
defaultConstant(node, arg);
@override
R visitTypeLiteralConstant(TypeLiteralConstant node, A arg) =>
defaultConstant(node, arg);
@override
R visitUnevaluatedConstant(UnevaluatedConstant node, A arg) =>
defaultConstant(node, arg);
}
abstract class _ConstantCallback<R> {
R defaultConstant(Constant node);
R visitNullConstant(NullConstant node);
R visitBoolConstant(BoolConstant node);
R visitIntConstant(IntConstant node);
@ -1178,41 +1264,12 @@ class _ConstantCallbackVisitor<R> implements ConstantVisitor<R> {
@override
R visitNullConstant(NullConstant node) => _callback.visitNullConstant(node);
@override
R defaultConstant(Constant node) => _callback.defaultConstant(node);
}
/// Visitor-like class used for visiting a [Constant] node while computing a
/// value for each subnode. The visitor caches the computed values ensuring that
/// each subnode is only visited once.
abstract class ComputeOnceConstantVisitor<R> implements _ConstantCallback<R> {
late final _ConstantCallbackVisitor<R> _visitor;
Map<Constant, R> cache = new LinkedHashMap.identity();
ComputeOnceConstantVisitor() {
_visitor = new _ConstantCallbackVisitor<R>(this);
}
/// Visits [node] if not already visited to compute a value for [node].
///
/// If the value has already been computed the cached value is returned
/// immediately.
///
/// Call this method to compute values for subnodes recursively, while only
/// visiting each subnode once.
R visitConstant(Constant node) {
return cache[node] ??= processValue(node, node.accept(_visitor));
}
/// Returns the computed [value] for [node].
///
/// Override this method to process the computed value before caching.
R processValue(Constant node, R value) {
return value;
}
@override
/// Helper mixin for [ComputeOnceConstantVisitor] and [VisitOnceConstantVisitor]
/// that implements the visit methods by delegating to the [defaultConstant]
/// method.
mixin OnceConstantVisitorDefaultMixin<R> implements _ConstantCallback<R> {
R defaultConstant(Constant node);
@override
@ -1259,6 +1316,36 @@ abstract class ComputeOnceConstantVisitor<R> implements _ConstantCallback<R> {
R visitUnevaluatedConstant(UnevaluatedConstant node) => defaultConstant(node);
}
/// Visitor-like class used for visiting a [Constant] node while computing a
/// value for each subnode. The visitor caches the computed values ensuring that
/// each subnode is only visited once.
abstract class ComputeOnceConstantVisitor<R> implements _ConstantCallback<R> {
late final _ConstantCallbackVisitor<R> _visitor;
Map<Constant, R> cache = new LinkedHashMap.identity();
ComputeOnceConstantVisitor() {
_visitor = new _ConstantCallbackVisitor<R>(this);
}
/// Visits [node] if not already visited to compute a value for [node].
///
/// If the value has already been computed the cached value is returned
/// immediately.
///
/// Call this method to compute values for subnodes recursively, while only
/// visiting each subnode once.
R visitConstant(Constant node) {
return cache[node] ??= processValue(node, node.accept(_visitor));
}
/// Returns the computed [value] for [node].
///
/// Override this method to process the computed value before caching.
R processValue(Constant node, R value) {
return value;
}
}
/// Visitor-like class used for visiting each subnode of a [Constant] node once.
///
/// The visitor records the visited node to ensure that each subnode is only
@ -1280,54 +1367,6 @@ abstract class VisitOnceConstantVisitor implements _ConstantCallback<void> {
node.accept(_visitor);
}
}
@override
void defaultConstant(Constant node);
@override
void visitNullConstant(NullConstant node) => defaultConstant(node);
@override
void visitBoolConstant(BoolConstant node) => defaultConstant(node);
@override
void visitIntConstant(IntConstant node) => defaultConstant(node);
@override
void visitDoubleConstant(DoubleConstant node) => defaultConstant(node);
@override
void visitStringConstant(StringConstant node) => defaultConstant(node);
@override
void visitSymbolConstant(SymbolConstant node) => defaultConstant(node);
@override
void visitMapConstant(MapConstant node) => defaultConstant(node);
@override
void visitListConstant(ListConstant node) => defaultConstant(node);
@override
void visitSetConstant(SetConstant node) => defaultConstant(node);
@override
void visitRecordConstant(RecordConstant node) => defaultConstant(node);
@override
void visitInstanceConstant(InstanceConstant node) => defaultConstant(node);
@override
void visitInstantiationConstant(InstantiationConstant node) =>
defaultConstant(node);
@override
void visitTypedefTearOffConstant(TypedefTearOffConstant node) =>
defaultConstant(node);
@override
void visitStaticTearOffConstant(StaticTearOffConstant node) =>
defaultConstant(node);
@override
void visitConstructorTearOffConstant(ConstructorTearOffConstant node) =>
defaultConstant(node);
@override
void visitRedirectingFactoryTearOffConstant(
RedirectingFactoryTearOffConstant node) =>
defaultConstant(node);
@override
void visitTypeLiteralConstant(TypeLiteralConstant node) =>
defaultConstant(node);
@override
void visitUnevaluatedConstant(UnevaluatedConstant node) =>
defaultConstant(node);
}
abstract class MemberReferenceVisitor<R> {
@ -1395,7 +1434,6 @@ abstract class Visitor<R> extends TreeVisitor<R>
R visitRecordType(RecordType node) => defaultDartType(node);
// Constants
@override
R defaultConstant(Constant node) => defaultNode(node);
@override
R visitNullConstant(NullConstant node) => defaultConstant(node);
@ -1546,7 +1584,6 @@ abstract class Visitor1<R, A> extends TreeVisitor1<R, A>
R visitExtensionType(ExtensionType node, A arg) => defaultDartType(node, arg);
// Constants
@override
R defaultConstant(Constant node, A arg) => defaultNode(node, arg);
@override
R visitNullConstant(NullConstant node, A arg) => defaultConstant(node, arg);
@ -2428,64 +2465,3 @@ abstract class StatementVisitor1<R, A> {
R visitFunctionDeclaration(FunctionDeclaration node, A arg) =>
defaultStatement(node, arg);
}
abstract class BodyVisitor1<R, A> extends ExpressionVisitor1<R, A>
implements StatementVisitor1<R, A> {
const BodyVisitor1();
@override
R defaultStatement(Statement node, A arg);
@override
R visitExpressionStatement(ExpressionStatement node, A arg) =>
defaultStatement(node, arg);
@override
R visitBlock(Block node, A arg) => defaultStatement(node, arg);
@override
R visitAssertBlock(AssertBlock node, A arg) => defaultStatement(node, arg);
@override
R visitEmptyStatement(EmptyStatement node, A arg) =>
defaultStatement(node, arg);
@override
R visitAssertStatement(AssertStatement node, A arg) =>
defaultStatement(node, arg);
@override
R visitLabeledStatement(LabeledStatement node, A arg) =>
defaultStatement(node, arg);
@override
R visitBreakStatement(BreakStatement node, A arg) =>
defaultStatement(node, arg);
@override
R visitWhileStatement(WhileStatement node, A arg) =>
defaultStatement(node, arg);
@override
R visitDoStatement(DoStatement node, A arg) => defaultStatement(node, arg);
@override
R visitForStatement(ForStatement node, A arg) => defaultStatement(node, arg);
@override
R visitForInStatement(ForInStatement node, A arg) =>
defaultStatement(node, arg);
@override
R visitSwitchStatement(SwitchStatement node, A arg) =>
defaultStatement(node, arg);
@override
R visitContinueSwitchStatement(ContinueSwitchStatement node, A arg) =>
defaultStatement(node, arg);
@override
R visitIfStatement(IfStatement node, A arg) => defaultStatement(node, arg);
@override
R visitReturnStatement(ReturnStatement node, A arg) =>
defaultStatement(node, arg);
@override
R visitTryCatch(TryCatch node, A arg) => defaultStatement(node, arg);
@override
R visitTryFinally(TryFinally node, A arg) => defaultStatement(node, arg);
@override
R visitYieldStatement(YieldStatement node, A arg) =>
defaultStatement(node, arg);
@override
R visitVariableDeclaration(VariableDeclaration node, A arg) =>
defaultStatement(node, arg);
@override
R visitFunctionDeclaration(FunctionDeclaration node, A arg) =>
defaultStatement(node, arg);
}

View file

@ -419,7 +419,8 @@ class _MemberVisitor extends RecursiveVisitor {
}
}
class _ConstantVisitor extends ConstantVisitor<void> {
class _ConstantVisitor extends ConstantVisitor<void>
with ConstantVisitorDefaultMixin<void> {
final RapidTypeAnalysis rta;
final Set<Constant> visited = {};

View file

@ -2673,7 +2673,8 @@ class RuntimeTypeTranslatorImpl extends DartTypeVisitor<TypeExpr>
}
}
class ConstantAllocationCollector extends ConstantVisitor<Type> {
class ConstantAllocationCollector extends ConstantVisitor<Type>
with ConstantVisitorDefaultMixin<Type> {
final SummaryCollector summaryCollector;
final Map<Constant, Type> constants = <Constant, Type>{};

View file

@ -2086,7 +2086,8 @@ class _TreeShakerPass2 extends RemovingTransformer {
}
}
class _TreeShakerConstantVisitor extends ConstantVisitor<Null> {
class _TreeShakerConstantVisitor extends ConstantVisitor<Null>
with ConstantVisitorDefaultMixin<Null> {
final TreeShaker shaker;
final _TreeShakerTypeVisitor typeVisitor;
final Set<Constant> constants = new Set<Constant>();