blob: bfb81f2c396231f82e869c25a8152499019d0e7e [file] [log] [blame]
// Copyright (c) 2021, 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 '../constants/values.dart' show ConstantValue;
import '../elements/entities.dart';
/// [EntityData] is the base class of wrapped [Entity] objects. Each
/// [EntityData] child knows how to use an [EntityDataCollector] to collect
/// [EntityDataInfo]. [EntityData] objects are canonicalized and must be created
/// by an [EntityDataRegistry].
abstract class EntityData<T> {
final T entity;
EntityData(this.entity);
void accept(EntityDataVisitor visitor);
/// Whether or not the [EntityData] needs to be updated recursively.
bool get needsRecursiveUpdate => true;
}
class ClassEntityData extends EntityData<ClassEntity> {
@override
void accept(EntityDataVisitor visitor) {
visitor.visitClassEntityData(entity);
}
ClassEntityData(ClassEntity entity) : super(entity);
}
class ClassTypeEntityData extends EntityData<ClassEntity> {
@override
void accept(EntityDataVisitor visitor) {
visitor.visitClassTypeEntityData(entity);
}
ClassTypeEntityData(ClassEntity entity) : super(entity);
}
class MemberEntityData extends EntityData<MemberEntity> {
@override
void accept(EntityDataVisitor visitor) {
visitor.visitMemberEntityData(entity);
}
MemberEntityData(MemberEntity entity) : super(entity);
}
class LocalFunctionEntityData extends EntityData<Local> {
@override
void accept(EntityDataVisitor) {}
// Note: local functions are not updated recursively because the
// dependencies are already visited as dependencies of the enclosing member.
@override
bool get needsRecursiveUpdate => false;
LocalFunctionEntityData(Local entity) : super(entity);
}
class ConstantEntityData extends EntityData<ConstantValue> {
@override
void accept(EntityDataVisitor visitor) {
visitor.visitConstantEntityData(entity);
}
ConstantEntityData(ConstantValue entity) : super(entity);
}
/// A registry used to canonicalize [EntityData].
class EntityDataRegistry {
/// Map of [Entity] / [ConstantValue] to [EntityData], used by all non
/// [ClassTypeEntityData].
final Map<Object, EntityData> _nonClassTypeData = {};
/// Map of [ClassEntity] to [EntityData], used by [ClassTypeEntityData].
final Map<ClassEntity, ClassTypeEntityData> _classTypeData = {};
EntityData createClassEntityData(ClassEntity cls) {
return _nonClassTypeData[cls] ??= ClassEntityData(cls);
}
EntityData createClassTypeEntityData(ClassEntity cls) {
return _classTypeData[cls] ??= ClassTypeEntityData(cls);
}
EntityData createConstantEntityData(ConstantValue constant) {
return _nonClassTypeData[constant] ??= ConstantEntityData(constant);
}
EntityData createLocalFunctionEntityData(Local localFunction) {
return _nonClassTypeData[localFunction] ??=
LocalFunctionEntityData(localFunction);
}
EntityData createMemberEntityData(MemberEntity member) {
return _nonClassTypeData[member] ??= MemberEntityData(member);
}
}
/// A trivial visitor to facilate interacting with [EntityData].
abstract class EntityDataVisitor {
void visitClassEntityData(ClassEntity element);
void visitClassTypeEntityData(ClassEntity element);
void visitConstantEntityData(ConstantValue constant);
void visitMemberEntityData(MemberEntity member);
}