abdd5765ee
TEST=Only the comments were changed. Change-Id: I8d4778746759466ea4c64f0eabe498da353fdd22 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/240041 Reviewed-by: Johnni Winther <johnniwinther@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com> Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
289 lines
7.2 KiB
Dart
289 lines
7.2 KiB
Dart
// 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.
|
|
|
|
library kernel.transformations.scanner;
|
|
|
|
import '../ast.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 = new Map();
|
|
Map<X, ScanError>? errors;
|
|
|
|
@override
|
|
String toString() => 'ScanResult<$X,$Y>';
|
|
}
|
|
|
|
class ScanError {}
|
|
|
|
abstract class ClassScanner<Y extends TreeNode?> implements Scanner<Class, Y> {
|
|
@override
|
|
final Scanner<Y, TreeNode?>? next;
|
|
|
|
ClassScanner(this.next);
|
|
|
|
@override
|
|
bool predicate(Class node);
|
|
|
|
@override
|
|
ScanResult<Class, Y> scan(TreeNode node) {
|
|
ScanResult<Class, Y> result = new ScanResult<Class, Y>();
|
|
|
|
if (node is Class) {
|
|
if (predicate(node)) {
|
|
result.targets[node] = next?.scan(node);
|
|
// TODO(cstefantsova): 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<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> {
|
|
@override
|
|
final Scanner<Y, TreeNode>? next;
|
|
|
|
FieldScanner(this.next);
|
|
|
|
@override
|
|
bool predicate(Field node);
|
|
|
|
@override
|
|
ScanResult<Field, Y> scan(TreeNode node) {
|
|
ScanResult<Field, Y> result = new ScanResult<Field, Y>();
|
|
|
|
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<Field, Y> result) {
|
|
if (predicate(field)) {
|
|
result.targets[field] = next?.scan(field);
|
|
}
|
|
}
|
|
|
|
void _scanClass(Class cls, ScanResult<Field, Y> result) {
|
|
for (Field field in cls.fields) {
|
|
_scanField(field, result);
|
|
}
|
|
}
|
|
|
|
void _scanLibrary(Library library, ScanResult<Field, Y> result) {
|
|
for (Class cls in library.classes) {
|
|
_scanClass(cls, result);
|
|
}
|
|
for (Field field in library.fields) {
|
|
_scanField(field, result);
|
|
}
|
|
}
|
|
|
|
void _scanComponent(Component component, ScanResult<Field, Y> result) {
|
|
for (Library library in component.libraries) {
|
|
_scanLibrary(library, result);
|
|
}
|
|
}
|
|
}
|
|
|
|
abstract class MemberScanner<Y extends TreeNode> implements Scanner<Member, Y> {
|
|
@override
|
|
final Scanner<Y, TreeNode?>? next;
|
|
|
|
MemberScanner(this.next);
|
|
|
|
@override
|
|
bool predicate(Member node);
|
|
|
|
@override
|
|
ScanResult<Member, Y> scan(TreeNode node) {
|
|
ScanResult<Member, Y> result = new ScanResult<Member, Y>();
|
|
|
|
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<Member, Y> result) {
|
|
if (predicate(member)) {
|
|
result.targets[member] = next?.scan(member);
|
|
}
|
|
}
|
|
|
|
void _scanClass(Class cls, ScanResult<Member, Y> result) {
|
|
for (Member member in cls.members) {
|
|
_scanMember(member, result);
|
|
}
|
|
}
|
|
|
|
void _scanLibrary(Library library, ScanResult<Member, Y> result) {
|
|
for (Class cls in library.classes) {
|
|
_scanClass(cls, result);
|
|
}
|
|
for (Member member in library.members) {
|
|
_scanMember(member, result);
|
|
}
|
|
}
|
|
|
|
void _scanComponent(Component component, ScanResult<Member, Y> result) {
|
|
for (Library library in component.libraries) {
|
|
_scanLibrary(library, result);
|
|
}
|
|
}
|
|
}
|
|
|
|
abstract class ProcedureScanner<Y extends TreeNode?>
|
|
implements Scanner<Procedure, Y> {
|
|
@override
|
|
final Scanner<Y, TreeNode>? next;
|
|
|
|
ProcedureScanner(this.next);
|
|
|
|
@override
|
|
bool predicate(Procedure node);
|
|
|
|
@override
|
|
ScanResult<Procedure, Y> scan(TreeNode node) {
|
|
ScanResult<Procedure, Y> result = new ScanResult<Procedure, Y>();
|
|
|
|
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<Procedure, Y> result) {
|
|
if (predicate(procedure)) {
|
|
result.targets[procedure] = next?.scan(procedure);
|
|
}
|
|
}
|
|
|
|
void _scanClass(Class cls, ScanResult<Procedure, Y> result) {
|
|
for (Procedure procedure in cls.procedures) {
|
|
_scanProcedure(procedure, result);
|
|
}
|
|
}
|
|
|
|
void _scanLibrary(Library library, ScanResult<Procedure, Y> result) {
|
|
for (Class cls in library.classes) {
|
|
_scanClass(cls, result);
|
|
}
|
|
for (Procedure procedure in library.procedures) {
|
|
_scanProcedure(procedure, result);
|
|
}
|
|
}
|
|
|
|
void _scanComponent(Component component, ScanResult<Procedure, Y> result) {
|
|
for (Library library in component.libraries) {
|
|
_scanLibrary(library, result);
|
|
}
|
|
}
|
|
}
|
|
|
|
abstract class ExpressionScanner<Y extends TreeNode>
|
|
extends RecursiveResultVisitor<void> implements Scanner<Expression, Y> {
|
|
@override
|
|
final Scanner<Y, TreeNode>? next;
|
|
ScanResult<Expression, Y>? _result;
|
|
|
|
ExpressionScanner(this.next);
|
|
|
|
@override
|
|
bool predicate(Expression node);
|
|
|
|
@override
|
|
ScanResult<Expression, Y> scan(TreeNode node) {
|
|
ScanResult<Expression, Y> result =
|
|
_result = new ScanResult<Expression, Y>();
|
|
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<Y extends TreeNode?>
|
|
extends RecursiveVisitor
|
|
implements Scanner<InstanceInvocationExpression, Y> {
|
|
@override
|
|
final Scanner<Y, TreeNode>? next;
|
|
ScanResult<InstanceInvocationExpression, Y>? _result;
|
|
|
|
MethodInvocationScanner(this.next);
|
|
|
|
@override
|
|
bool predicate(InstanceInvocationExpression node);
|
|
|
|
@override
|
|
ScanResult<InstanceInvocationExpression, Y> scan(TreeNode node) {
|
|
ScanResult<InstanceInvocationExpression, Y> result =
|
|
_result = new ScanResult<InstanceInvocationExpression, Y>();
|
|
node.accept(this);
|
|
_result = null;
|
|
return result;
|
|
}
|
|
|
|
@override
|
|
void visitInstanceInvocation(InstanceInvocation node) {
|
|
if (predicate(node)) {
|
|
_result!.targets[node] = next?.scan(node);
|
|
// TODO: Update result.errors.
|
|
}
|
|
}
|
|
}
|