Files
sdk/pkg/kernel/lib/transformations/scanner.dart
T
jlcontreras da6cdc55b4 [cfe] Implement addHashCode to valueClass transformation
Change-Id: Ie566cee214b63f986e07c84e4ae28bfecc80e0a3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/162186
Commit-Queue: Javier López-Contreras <jlcontreras@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
2020-09-11 16:05:52 +00:00

163 lines
4.0 KiB
Dart

library kernel.transformations.scanner;
import '../ast.dart';
import '../kernel.dart';
abstract class Scanner<X extends TreeNode, Y extends TreeNode> {
final Scanner<Y, TreeNode> next;
Scanner(this.next);
bool predicate(X x);
ScanResult<X, Y> scan(TreeNode node);
}
class ScanResult<X extends TreeNode, Y extends TreeNode> {
Map<X, ScanResult<Y, TreeNode>> targets;
Map<X, ScanError> errors;
}
class ScanError {}
abstract class ClassScanner<Y extends TreeNode> implements Scanner<Class, Y> {
final Scanner<Y, TreeNode> next;
ClassScanner(this.next);
bool predicate(Class node);
ScanResult<Class, Y> scan(TreeNode node) {
ScanResult<Class, Y> result = new ScanResult();
result.targets = new Map();
if (node is Class) {
if (predicate(node)) {
result.targets[node] = next?.scan(node);
}
} else if (node is Library) {
_scanLibrary(node, result);
} else if (node is Component) {
_scanComponent(node, result);
}
return result;
}
void _scanLibrary(Library library, ScanResult<Class, Y> result) {
for (Class cls in library.classes) {
if (predicate(cls)) {
result.targets[cls] = next?.scan(cls);
}
}
}
void _scanComponent(Component component, ScanResult<Class, Y> result) {
for (Library library in component.libraries) {
_scanLibrary(library, result);
}
}
}
abstract class FieldScanner<Y extends TreeNode> implements Scanner<Field, Y> {
final Scanner<Y, TreeNode> next;
FieldScanner(this.next);
bool predicate(Field node);
ScanResult<Field, Y> scan(TreeNode node) {
ScanResult<Field, Y> result = new ScanResult();
result.targets = new Map();
if (node is Field) {
if (predicate(node)) {
result.targets[node] = next?.scan(node);
}
} else if (node is Class) {
_scanClass(node, result);
} else if (node is Library) {
_scanLibrary(node, result);
} else if (node is Component) {
_scanComponent(node, result);
}
return result;
}
void _scanClass(Class cls, ScanResult<Field, Y> result) {
for (Field field in cls.fields) {
if (predicate(field)) {
result.targets[field] = next?.scan(field);
}
}
}
void _scanLibrary(Library library, ScanResult<Field, Y> result) {
for (Class cls in library.classes) {
_scanClass(cls, result);
}
for (Field field in library.fields) {
if (predicate(field)) {
result.targets[field] = next?.scan(field);
}
}
}
void _scanComponent(Component component, ScanResult<Field, Y> result) {
for (Library library in component.libraries) {
_scanLibrary(library, result);
}
}
}
abstract class ProcedureScanner<Y extends TreeNode>
implements Scanner<Procedure, Y> {
final Scanner<Y, TreeNode> next;
ProcedureScanner(this.next);
bool predicate(Procedure node);
ScanResult<Procedure, Y> scan(TreeNode node) {
ScanResult<Procedure, Y> result = new ScanResult();
result.targets = new Map();
if (node is Procedure) {
if (predicate(node)) {
result.targets[node] = next?.scan(node);
}
} else if (node is Class) {
_scanClass(node, result);
} else if (node is Library) {
_scanLibrary(node, result);
} else if (node is Component) {
_scanComponent(node, result);
}
return result;
}
void _scanClass(Class cls, ScanResult<Procedure, Y> result) {
for (Procedure procedure in cls.procedures) {
if (predicate(procedure)) {
result.targets[procedure] = next?.scan(procedure);
}
}
}
void _scanLibrary(Library library, ScanResult<Procedure, Y> result) {
for (Class cls in library.classes) {
_scanClass(cls, result);
}
for (Procedure procedure in library.procedures) {
if (predicate(procedure)) {
result.targets[procedure] = next?.scan(procedure);
}
}
}
void _scanComponent(Component component, ScanResult<Procedure, Y> result) {
for (Library library in component.libraries) {
_scanLibrary(library, result);
}
}
}