blob: 49e9d891f68dcb1c2e065da1d3bbe8f5e593f54b [file] [edit]
// Copyright (c) 2024, 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 '../code_generator.dart';
import '../config_provider/config_types.dart' show CompoundDependencies;
import 'ast.dart';
class FindByValueCompoundsVisitation extends Visitation {
// Set of [Compounds] that are either directly included, or referred to by
// value (ie not by pointer).
final byValueCompounds = <Compound>{};
@override
void visitCompound(Compound node) {
node.visitChildren(visitor);
byValueCompounds.add(node);
}
@override
void visitPointerType(PointerType node) {
if (node.child.typealiasType is Compound && node is! ConstantArray) {
// Don't visit compounds through pointers. We're only interested in
// compounds that are referred to by value.
} else {
node.visitChildren(visitor);
}
}
// If a node is only referred to by value through a directly included
// typealias, that doesn't count as by-value. The best way to implement this
// logic is to just exclude typealiases from the root set.
static Iterable<AstNode> rootNodes(Iterable<AstNode> included) =>
included.where((n) => n is! Typealias);
}
class ClearOpaqueCompoundMembersVisitation extends Visitation {
final Set<Compound> byValueCompounds;
final Set<Binding> included;
ClearOpaqueCompoundMembersVisitation(this.byValueCompounds, this.included);
void _visitImpl(Compound node) {
// If a compound isn't referred to by value, isn't explicitly included by
// the config filters, and the compound is configured with opaque deps,
// convert the compound to be opaque by deleting its members.
if (!byValueCompounds.contains(node) &&
!included.contains(node) &&
node.dependencies == CompoundDependencies.opaque) {
node.members.clear();
}
}
@override
void visitStruct(Struct node) => _visitImpl(node);
@override
void visitUnion(Union node) => _visitImpl(node);
}