Skip to content

Commit 3b24f36

Browse files
johnniwinthercommit-bot@chromium.org
authored andcommitted
[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 <[email protected]> Commit-Queue: Johnni Winther <[email protected]>
1 parent f0fe238 commit 3b24f36

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:kernel/ast.dart';
6+
import 'package:kernel/visitor.dart';
7+
import '../frontend_server.dart';
8+
9+
// Transformer/visitor for toString
10+
// If we add any more of these, they really should go into a separate library.
11+
12+
/// A [RecursiveVisitor] that replaces [Object.toString] overrides with
13+
/// `super.toString()`.
14+
class ToStringVisitor extends RecursiveVisitor<void> {
15+
/// The [packageUris] must not be null.
16+
ToStringVisitor(this._packageUris) : assert(_packageUris != null);
17+
18+
/// A set of package URIs to apply this transformer to, e.g. 'dart:ui' and
19+
/// 'package:flutter/foundation.dart'.
20+
final Set<String> _packageUris;
21+
22+
/// Turn 'dart:ui' into 'dart:ui', or
23+
/// 'package:flutter/src/semantics_event.dart' into 'package:flutter'.
24+
String _importUriToPackage(Uri importUri) =>
25+
'${importUri.scheme}:${importUri.pathSegments.first}';
26+
27+
bool _isInTargetPackage(Procedure node) {
28+
return _packageUris
29+
.contains(_importUriToPackage(node.enclosingLibrary.importUri));
30+
}
31+
32+
bool _hasKeepAnnotation(Procedure node) {
33+
for (ConstantExpression expression
34+
in node.annotations.whereType<ConstantExpression>()) {
35+
if (expression.constant is! InstanceConstant) {
36+
continue;
37+
}
38+
final InstanceConstant constant = expression.constant as InstanceConstant;
39+
if (constant.classNode.name == '_KeepToString' &&
40+
constant.classNode.enclosingLibrary.importUri.toString() ==
41+
'dart:ui') {
42+
return true;
43+
}
44+
}
45+
return false;
46+
}
47+
48+
@override
49+
void visitProcedure(Procedure node) {
50+
if (node.name.text == 'toString' &&
51+
node.enclosingClass != null &&
52+
node.enclosingLibrary != null &&
53+
!node.isStatic &&
54+
!node.isAbstract &&
55+
!node.enclosingClass.isEnum &&
56+
_isInTargetPackage(node) &&
57+
!_hasKeepAnnotation(node)) {
58+
node.function.body.replaceWith(
59+
ReturnStatement(
60+
SuperMethodInvocation(
61+
node.name,
62+
Arguments(<Expression>[]),
63+
),
64+
),
65+
);
66+
}
67+
}
68+
69+
@override
70+
void defaultMember(Member node) {}
71+
}
72+
73+
/// Replaces [Object.toString] overrides with calls to super for the specified
74+
/// [packageUris].
75+
class ToStringTransformer extends ProgramTransformer {
76+
/// The [packageUris] parameter must not be null, but may be empty.
77+
ToStringTransformer(this._child, this._packageUris)
78+
: assert(_packageUris != null);
79+
80+
final ProgramTransformer _child;
81+
82+
/// A set of package URIs to apply this transformer to, e.g. 'dart:ui' and
83+
/// 'package:flutter/foundation.dart'.
84+
final Set<String> _packageUris;
85+
86+
@override
87+
void transform(Component component) {
88+
assert(_child is! ToStringTransformer);
89+
if (_packageUris.isNotEmpty) {
90+
component.visitChildren(ToStringVisitor(_packageUris));
91+
}
92+
_child?.transform(component);
93+
}
94+
}

0 commit comments

Comments
 (0)