// Copyright (c) 2020, 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. // @dart = 2.9 library kernel.transformations.scanner; import '../ast.dart'; import '../kernel.dart'; abstract class Scanner { final Scanner next; Scanner(this.next); bool predicate(X x); ScanResult scan(TreeNode node); } class ScanResult { Map> targets = new Map(); Map errors; } class ScanError {} abstract class ClassScanner implements Scanner { final Scanner next; ClassScanner(this.next); bool predicate(Class node); ScanResult scan(TreeNode node) { ScanResult result = new ScanResult(); if (node is Class) { if (predicate(node)) { result.targets[node] = next?.scan(node); // TODO(dmitryas): set result.errors when specification is landed, // same with all other places where targets is set } } else if (node is Library) { _scanLibrary(node, result); } else if (node is Component) { _scanComponent(node, result); } return result; } void _scanLibrary(Library library, ScanResult result) { for (Class cls in library.classes) { if (predicate(cls)) { result.targets[cls] = next?.scan(cls); } } } void _scanComponent(Component component, ScanResult result) { for (Library library in component.libraries) { _scanLibrary(library, result); } } } abstract class FieldScanner implements Scanner { final Scanner next; FieldScanner(this.next); bool predicate(Field node); ScanResult scan(TreeNode node) { ScanResult result = new ScanResult(); if (node is Field) { _scanField(node, result); } 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 _scanField(Field field, ScanResult result) { if (predicate(field)) { result.targets[field] = next?.scan(field); } } void _scanClass(Class cls, ScanResult result) { for (Field field in cls.fields) { _scanField(field, result); } } void _scanLibrary(Library library, ScanResult result) { for (Class cls in library.classes) { _scanClass(cls, result); } for (Field field in library.fields) { _scanField(field, result); } } void _scanComponent(Component component, ScanResult result) { for (Library library in component.libraries) { _scanLibrary(library, result); } } } abstract class MemberScanner implements Scanner { final Scanner next; MemberScanner(this.next); bool predicate(Member node); ScanResult scan(TreeNode node) { ScanResult result = new ScanResult(); if (node is Member) { _scanMember(node, result); } 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 _scanMember(Member member, ScanResult result) { if (predicate(member)) { result.targets[member] = next?.scan(member); } } void _scanClass(Class cls, ScanResult result) { for (Member member in cls.members) { _scanMember(member, result); } } void _scanLibrary(Library library, ScanResult result) { for (Class cls in library.classes) { _scanClass(cls, result); } for (Member member in library.members) { _scanMember(member, result); } } void _scanComponent(Component component, ScanResult result) { for (Library library in component.libraries) { _scanLibrary(library, result); } } } abstract class ProcedureScanner implements Scanner { final Scanner next; ProcedureScanner(this.next); bool predicate(Procedure node); ScanResult scan(TreeNode node) { ScanResult result = new ScanResult(); if (node is Procedure) { _scanProcedure(node, result); } 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 _scanProcedure(Procedure procedure, ScanResult result) { if (predicate(procedure)) { result.targets[procedure] = next?.scan(procedure); } } void _scanClass(Class cls, ScanResult result) { for (Procedure procedure in cls.procedures) { _scanProcedure(procedure, result); } } void _scanLibrary(Library library, ScanResult result) { for (Class cls in library.classes) { _scanClass(cls, result); } for (Procedure procedure in library.procedures) { _scanProcedure(procedure, result); } } void _scanComponent(Component component, ScanResult result) { for (Library library in component.libraries) { _scanLibrary(library, result); } } } abstract class ExpressionScanner extends RecursiveResultVisitor implements Scanner { final Scanner next; ScanResult _result; ExpressionScanner(this.next); bool predicate(Expression node); ScanResult scan(TreeNode node) { ScanResult result = _result = new ScanResult(); node.accept(this); _result = null; return result; } void visitExpression(Expression node) { if (predicate(node)) { _result.targets[node] = next?.scan(node); // TODO: Update result.errors. } } } abstract class MethodInvocationScanner extends RecursiveVisitor implements Scanner { final Scanner next; ScanResult _result; MethodInvocationScanner(this.next); bool predicate(MethodInvocation node); ScanResult scan(TreeNode node) { ScanResult result = _result = new ScanResult(); node.accept(this); _result = null; return result; } void visitMethodInvocation(MethodInvocation node) { if (predicate(node)) { _result.targets[node] = next?.scan(node); // TODO: Update result.errors. } } }