[cfe] Implements ValueClassScanner
Change-Id: I36b839280513a75d92797d5999ecb567e6999a5c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/162180
Commit-Queue: Javier López-Contreras <jlcontreras@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
diff --git a/pkg/kernel/lib/transformations/scanner.dart b/pkg/kernel/lib/transformations/scanner.dart
new file mode 100644
index 0000000..5083fa6
--- /dev/null
+++ b/pkg/kernel/lib/transformations/scanner.dart
@@ -0,0 +1,51 @@
+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) {
+ for (Class cls in node.classes) {
+ if (predicate(cls)) {
+ result.targets[cls] = next?.scan(cls);
+ }
+ }
+ } else if (node is Component) {
+ for (Library library in node.libraries) {
+ for (Class cls in library.classes) {
+ if (predicate(cls)) {
+ result.targets[cls] = next?.scan(cls);
+ }
+ }
+ }
+ }
+ return result;
+ }
+}
diff --git a/pkg/kernel/lib/transformations/value_class.dart b/pkg/kernel/lib/transformations/value_class.dart
index afda4be..9e38786 100644
--- a/pkg/kernel/lib/transformations/value_class.dart
+++ b/pkg/kernel/lib/transformations/value_class.dart
@@ -8,15 +8,31 @@
import '../kernel.dart';
import '../core_types.dart' show CoreTypes;
import '../class_hierarchy.dart' show ClassHierarchy;
+import './scanner.dart';
+
+class ValueClassScanner extends ClassScanner<Null> {
+ ValueClassScanner() : super(null);
+
+ bool predicate(Class node) {
+ for (Expression annotation in node.annotations) {
+ if (annotation is ConstantExpression &&
+ annotation.constant is StringConstant) {
+ StringConstant constant = annotation.constant;
+ if (constant.value == 'valueClass') {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
void transformComponent(
Component node, CoreTypes coreTypes, ClassHierarchy hierarchy) {
- for (Library library in node.libraries) {
- for (Class cls in library.classes) {
- if (isValueClass(cls)) {
- transformValueClass(cls, coreTypes, hierarchy);
- }
- }
+ ValueClassScanner scanner = new ValueClassScanner();
+ ScanResult<Class, Null> valueClasses = scanner.scan(node);
+ for (Class valueClass in valueClasses.targets.keys) {
+ transformValueClass(valueClass, coreTypes, hierarchy);
}
}