[frontend_server] Move ToStringTransformer to the Dart repo
The reduces the dependency of flutter/engine on the cfe internals. Context: https://dart-review.googlesource.com/c/sdk/+/172180 had to be reverted because the refactoring of the package:kernel code broke the flutter/engine. A follow-up CL is needed in the flutter repo to use the moved classes instead. Change-Id: I674ab3a09569d615b1549a5465da0f658945ec7e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/172762 Reviewed-by: Dan Field <dnfield@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
f0fe238bac
commit
3b24f36209
@@ -0,0 +1,94 @@
|
||||
// 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.
|
||||
|
||||
import 'package:kernel/ast.dart';
|
||||
import 'package:kernel/visitor.dart';
|
||||
import '../frontend_server.dart';
|
||||
|
||||
// Transformer/visitor for toString
|
||||
// If we add any more of these, they really should go into a separate library.
|
||||
|
||||
/// A [RecursiveVisitor] that replaces [Object.toString] overrides with
|
||||
/// `super.toString()`.
|
||||
class ToStringVisitor extends RecursiveVisitor<void> {
|
||||
/// The [packageUris] must not be null.
|
||||
ToStringVisitor(this._packageUris) : assert(_packageUris != null);
|
||||
|
||||
/// A set of package URIs to apply this transformer to, e.g. 'dart:ui' and
|
||||
/// 'package:flutter/foundation.dart'.
|
||||
final Set<String> _packageUris;
|
||||
|
||||
/// Turn 'dart:ui' into 'dart:ui', or
|
||||
/// 'package:flutter/src/semantics_event.dart' into 'package:flutter'.
|
||||
String _importUriToPackage(Uri importUri) =>
|
||||
'${importUri.scheme}:${importUri.pathSegments.first}';
|
||||
|
||||
bool _isInTargetPackage(Procedure node) {
|
||||
return _packageUris
|
||||
.contains(_importUriToPackage(node.enclosingLibrary.importUri));
|
||||
}
|
||||
|
||||
bool _hasKeepAnnotation(Procedure node) {
|
||||
for (ConstantExpression expression
|
||||
in node.annotations.whereType<ConstantExpression>()) {
|
||||
if (expression.constant is! InstanceConstant) {
|
||||
continue;
|
||||
}
|
||||
final InstanceConstant constant = expression.constant as InstanceConstant;
|
||||
if (constant.classNode.name == '_KeepToString' &&
|
||||
constant.classNode.enclosingLibrary.importUri.toString() ==
|
||||
'dart:ui') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
void visitProcedure(Procedure node) {
|
||||
if (node.name.text == 'toString' &&
|
||||
node.enclosingClass != null &&
|
||||
node.enclosingLibrary != null &&
|
||||
!node.isStatic &&
|
||||
!node.isAbstract &&
|
||||
!node.enclosingClass.isEnum &&
|
||||
_isInTargetPackage(node) &&
|
||||
!_hasKeepAnnotation(node)) {
|
||||
node.function.body.replaceWith(
|
||||
ReturnStatement(
|
||||
SuperMethodInvocation(
|
||||
node.name,
|
||||
Arguments(<Expression>[]),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void defaultMember(Member node) {}
|
||||
}
|
||||
|
||||
/// Replaces [Object.toString] overrides with calls to super for the specified
|
||||
/// [packageUris].
|
||||
class ToStringTransformer extends ProgramTransformer {
|
||||
/// The [packageUris] parameter must not be null, but may be empty.
|
||||
ToStringTransformer(this._child, this._packageUris)
|
||||
: assert(_packageUris != null);
|
||||
|
||||
final ProgramTransformer _child;
|
||||
|
||||
/// A set of package URIs to apply this transformer to, e.g. 'dart:ui' and
|
||||
/// 'package:flutter/foundation.dart'.
|
||||
final Set<String> _packageUris;
|
||||
|
||||
@override
|
||||
void transform(Component component) {
|
||||
assert(_child is! ToStringTransformer);
|
||||
if (_packageUris.isNotEmpty) {
|
||||
component.visitChildren(ToStringVisitor(_packageUris));
|
||||
}
|
||||
_child?.transform(component);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user