0d93a85916
Change-Id: If0a7894406458b0cb6f4e1c5e4d60a6377b2459b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/98044 Commit-Queue: Ryan Macnak <rmacnak@google.com> Auto-Submit: Alexander Markov <alexmarkov@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
182 lines
5.4 KiB
Dart
182 lines
5.4 KiB
Dart
// Copyright (c) 2019, 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 vm.bytecode.ast_remover;
|
|
|
|
import 'package:kernel/ast.dart' hide MapEntry;
|
|
import '../metadata/bytecode.dart';
|
|
|
|
/// Drops kernel AST for members with bytecode.
|
|
/// Can preserve removed AST and restore it if needed.
|
|
class ASTRemover extends Transformer {
|
|
final BytecodeMetadataRepository metadata;
|
|
final stashes = <Node, _Stash>{};
|
|
|
|
ASTRemover(Component component)
|
|
: metadata = component.metadata[new BytecodeMetadataRepository().tag] {
|
|
stashes[component] = new _ComponentStash(component.mainMethod,
|
|
new Map<String, MetadataRepository<dynamic>>.from(component.metadata));
|
|
component.mainMethod = null;
|
|
component.metadata.removeWhere((tag, md) => tag != metadata.tag);
|
|
}
|
|
|
|
@override
|
|
visitLibrary(Library node) {
|
|
stashes[node] = new _LibraryStash(
|
|
new List<Expression>.from(node.annotations),
|
|
new List<Field>.from(node.fields),
|
|
new List<Procedure>.from(node.procedures),
|
|
new List<Reference>.from(node.additionalExports));
|
|
|
|
node.annotations.clear();
|
|
node.fields.clear();
|
|
node.procedures.clear();
|
|
node.additionalExports.clear();
|
|
|
|
super.visitLibrary(node);
|
|
|
|
return node;
|
|
}
|
|
|
|
@override
|
|
visitLibraryDependency(LibraryDependency node) {
|
|
stashes[node] = new _LibraryDependencyStash(
|
|
new List<Expression>.from(node.annotations));
|
|
|
|
node.annotations.clear();
|
|
|
|
super.visitLibraryDependency(node);
|
|
|
|
return node;
|
|
}
|
|
|
|
// Still referenced from function types which may appear in class supertypes.
|
|
@override
|
|
visitTypedef(Typedef node) {
|
|
stashes[node] = new _TypedefStash(node.annotations);
|
|
|
|
node.annotations = const <Expression>[];
|
|
|
|
super.visitTypedef(node);
|
|
|
|
// TODO(alexmarkov): fix Typedef visitor to visit these fields.
|
|
transformList(node.positionalParameters, this, node);
|
|
transformList(node.namedParameters, this, node);
|
|
|
|
return node;
|
|
}
|
|
|
|
// May appear in typedefs.
|
|
@override
|
|
visitVariableDeclaration(VariableDeclaration node) {
|
|
stashes[node] = new _VariableDeclarationStash(node.annotations);
|
|
|
|
node.annotations = const <Expression>[];
|
|
|
|
super.visitVariableDeclaration(node);
|
|
|
|
return node;
|
|
}
|
|
|
|
@override
|
|
visitClass(Class node) {
|
|
stashes[node] = new _ClassStash(
|
|
node.annotations,
|
|
new List<Field>.from(node.fields),
|
|
new List<Procedure>.from(node.procedures),
|
|
new List<Constructor>.from(node.constructors));
|
|
|
|
node.annotations = const <Expression>[];
|
|
node.fields.clear();
|
|
node.procedures.clear();
|
|
node.constructors.clear();
|
|
|
|
super.visitClass(node);
|
|
|
|
return node;
|
|
}
|
|
|
|
void restoreAST() {
|
|
stashes.forEach((Node node, _Stash stash) {
|
|
if (node is Component) {
|
|
_ComponentStash componentStash = stash as _ComponentStash;
|
|
node.mainMethod = componentStash.mainMethod;
|
|
node.metadata.addAll(componentStash.metadata);
|
|
} else if (node is Library) {
|
|
_LibraryStash libraryStash = stash as _LibraryStash;
|
|
node.annotations.addAll(libraryStash.annotations);
|
|
node.fields.addAll(libraryStash.fields);
|
|
node.procedures.addAll(libraryStash.procedures);
|
|
node.additionalExports.addAll(libraryStash.additionalExports);
|
|
} else if (node is LibraryDependency) {
|
|
_LibraryDependencyStash libraryDependencyStash =
|
|
stash as _LibraryDependencyStash;
|
|
node.annotations.addAll(libraryDependencyStash.annotations);
|
|
} else if (node is Typedef) {
|
|
_TypedefStash typedefStash = stash as _TypedefStash;
|
|
node.annotations = typedefStash.annotations;
|
|
} else if (node is VariableDeclaration) {
|
|
_VariableDeclarationStash variableDeclarationStash =
|
|
stash as _VariableDeclarationStash;
|
|
node.annotations = variableDeclarationStash.annotations;
|
|
} else if (node is Class) {
|
|
_ClassStash classStash = stash as _ClassStash;
|
|
node.annotations = classStash.annotations;
|
|
node.fields.addAll(classStash.fields);
|
|
node.procedures.addAll(classStash.procedures);
|
|
node.constructors.addAll(classStash.constructors);
|
|
} else {
|
|
throw 'Unexpected ${node.runtimeType} $node';
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
abstract class _Stash {}
|
|
|
|
class _ClassStash extends _Stash {
|
|
final List<Expression> annotations;
|
|
final List<Field> fields;
|
|
final List<Procedure> procedures;
|
|
final List<Constructor> constructors;
|
|
|
|
_ClassStash(
|
|
this.annotations, this.fields, this.procedures, this.constructors);
|
|
}
|
|
|
|
class _LibraryStash extends _Stash {
|
|
final List<Expression> annotations;
|
|
final List<Field> fields;
|
|
final List<Procedure> procedures;
|
|
final List<Reference> additionalExports;
|
|
|
|
_LibraryStash(
|
|
this.annotations, this.fields, this.procedures, this.additionalExports);
|
|
}
|
|
|
|
class _LibraryDependencyStash extends _Stash {
|
|
final List<Expression> annotations;
|
|
|
|
_LibraryDependencyStash(this.annotations);
|
|
}
|
|
|
|
class _TypedefStash extends _Stash {
|
|
final List<Expression> annotations;
|
|
|
|
_TypedefStash(this.annotations);
|
|
}
|
|
|
|
class _VariableDeclarationStash extends _Stash {
|
|
final List<Expression> annotations;
|
|
|
|
_VariableDeclarationStash(this.annotations);
|
|
}
|
|
|
|
class _ComponentStash extends _Stash {
|
|
final Procedure mainMethod;
|
|
final Map<String, MetadataRepository<dynamic>> metadata;
|
|
|
|
_ComponentStash(this.mainMethod, this.metadata);
|
|
}
|