From 3e17bbc6c46eea186e47fd451f1061e2d2af0f14 Mon Sep 17 00:00:00 2001 From: jensjoha Date: Tue, 26 Jan 2021 09:51:42 +0100 Subject: [PATCH] Use ToStringTransformer from dart frontend_server (#23915) --- flutter_frontend_server/lib/server.dart | 91 +------------------ .../test/to_string_test.dart | 28 +++--- 2 files changed, 18 insertions(+), 101 deletions(-) diff --git a/flutter_frontend_server/lib/server.dart b/flutter_frontend_server/lib/server.dart index 1ced42a4d0d..125b40a2d4c 100644 --- a/flutter_frontend_server/lib/server.dart +++ b/flutter_frontend_server/lib/server.dart @@ -16,8 +16,8 @@ import 'package:frontend_server/frontend_server.dart' as frontend listenAndCompile, argParser, usage, - ProgramTransformer; -import 'package:kernel/ast.dart'; + ProgramTransformer, + ToStringTransformer; import 'package:path/path.dart' as path; import 'package:vm/incremental_compiler.dart'; @@ -150,7 +150,7 @@ Future starter( ]); compiler ??= _FlutterFrontendCompiler( output, - transformer: ToStringTransformer(null, deleteToStringPackageUris), + transformer: frontend.ToStringTransformer(null, deleteToStringPackageUris), ); await compiler.compile(input, options); @@ -170,7 +170,7 @@ Future starter( } compiler ??= _FlutterFrontendCompiler(output, - transformer: ToStringTransformer(transformer, deleteToStringPackageUris), + transformer: frontend.ToStringTransformer(transformer, deleteToStringPackageUris), useDebuggerModuleNames: options['debugger-module-names'] as bool, emitDebugMetadata: options['experimental-emit-debug-metadata'] as bool, unsafePackageSerialization: @@ -184,86 +184,3 @@ Future starter( frontend.listenAndCompile(compiler, input ?? stdin, options, completer); return completer.future; } - -// 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 { - /// 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 _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()) { - 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([]), - ), - ), - ); - } - } - - @override - void defaultMember(Member node) {} -} - -/// Replaces [Object.toString] overrides with calls to super for the specified -/// [packageUris]. -class ToStringTransformer extends frontend.ProgramTransformer { - /// The [packageUris] parameter must not be null, but may be empty. - ToStringTransformer(this._child, this._packageUris) : assert(_packageUris != null); - - final frontend.ProgramTransformer _child; - - /// A set of package URIs to apply this transformer to, e.g. 'dart:ui' and - /// 'package:flutter/foundation.dart'. - final Set _packageUris; - - @override - void transform(Component component) { - assert(_child is! ToStringTransformer); - if (_packageUris.isNotEmpty) { - component.visitChildren(ToStringVisitor(_packageUris)); - } - _child?.transform(component); - } -} diff --git a/flutter_frontend_server/test/to_string_test.dart b/flutter_frontend_server/test/to_string_test.dart index 868667c9b98..8eedc586262 100644 --- a/flutter_frontend_server/test/to_string_test.dart +++ b/flutter_frontend_server/test/to_string_test.dart @@ -4,8 +4,8 @@ import 'dart:io'; -import 'package:flutter_frontend_server/server.dart'; -import 'package:frontend_server/frontend_server.dart' as frontend show ProgramTransformer; +import 'package:frontend_server/frontend_server.dart' as frontend + show ProgramTransformer, ToStringTransformer, ToStringVisitor; import 'package:kernel/kernel.dart'; import 'package:mockito/mockito.dart'; import 'package:path/path.dart' as path; @@ -25,7 +25,7 @@ void main(List args) async { }; test('No packages', () { - final ToStringTransformer transformer = ToStringTransformer(null, {}); + final frontend.ToStringTransformer transformer = frontend.ToStringTransformer(null, {}); final MockComponent component = MockComponent(); transformer.transform(component); @@ -33,7 +33,7 @@ void main(List args) async { }); test('dart:ui package', () { - final ToStringTransformer transformer = ToStringTransformer(null, uiAndFlutter); + final frontend.ToStringTransformer transformer = frontend.ToStringTransformer(null, uiAndFlutter); final MockComponent component = MockComponent(); transformer.transform(component); @@ -42,7 +42,7 @@ void main(List args) async { test('Child transformer', () { final MockTransformer childTransformer = MockTransformer(); - final ToStringTransformer transformer = ToStringTransformer(childTransformer, {}); + final frontend.ToStringTransformer transformer = frontend.ToStringTransformer(childTransformer, {}); final MockComponent component = MockComponent(); transformer.transform(component); @@ -51,7 +51,7 @@ void main(List args) async { }); test('ToStringVisitor ignores non-toString procedures', () { - final ToStringVisitor visitor = ToStringVisitor(uiAndFlutter); + final frontend.ToStringVisitor visitor = frontend.ToStringVisitor(uiAndFlutter); final MockProcedure procedure = MockProcedure(); when(procedure.name).thenReturn(Name('main')); when(procedure.annotations).thenReturn(const []); @@ -65,7 +65,7 @@ void main(List args) async { // // void main() {} // String toString() => 'why?'; - final ToStringVisitor visitor = ToStringVisitor(uiAndFlutter); + final frontend.ToStringVisitor visitor = frontend.ToStringVisitor(uiAndFlutter); final MockProcedure procedure = MockProcedure(); final MockFunctionNode function = MockFunctionNode(); final MockStatement statement = MockStatement(); @@ -84,7 +84,7 @@ void main(List args) async { }); test('ToStringVisitor ignores abstract toString', () { - final ToStringVisitor visitor = ToStringVisitor(uiAndFlutter); + final frontend.ToStringVisitor visitor = frontend.ToStringVisitor(uiAndFlutter); final MockProcedure procedure = MockProcedure(); final MockFunctionNode function = MockFunctionNode(); final MockStatement statement = MockStatement(); @@ -103,7 +103,7 @@ void main(List args) async { }); test('ToStringVisitor ignores static toString', () { - final ToStringVisitor visitor = ToStringVisitor(uiAndFlutter); + final frontend.ToStringVisitor visitor = frontend.ToStringVisitor(uiAndFlutter); final MockProcedure procedure = MockProcedure(); final MockFunctionNode function = MockFunctionNode(); final MockStatement statement = MockStatement(); @@ -122,7 +122,7 @@ void main(List args) async { }); test('ToStringVisitor ignores enum toString', () { - final ToStringVisitor visitor = ToStringVisitor(uiAndFlutter); + final frontend.ToStringVisitor visitor = frontend.ToStringVisitor(uiAndFlutter); final MockProcedure procedure = MockProcedure(); final MockFunctionNode function = MockFunctionNode(); final MockStatement statement = MockStatement(); @@ -141,7 +141,7 @@ void main(List args) async { }); test('ToStringVisitor ignores non-specified libraries', () { - final ToStringVisitor visitor = ToStringVisitor(uiAndFlutter); + final frontend.ToStringVisitor visitor = frontend.ToStringVisitor(uiAndFlutter); final MockProcedure procedure = MockProcedure(); final MockFunctionNode function = MockFunctionNode(); final MockStatement statement = MockStatement(); @@ -160,7 +160,7 @@ void main(List args) async { }); test('ToStringVisitor ignores @keepToString', () { - final ToStringVisitor visitor = ToStringVisitor(uiAndFlutter); + final frontend.ToStringVisitor visitor = frontend.ToStringVisitor(uiAndFlutter); final MockProcedure procedure = MockProcedure(); final MockFunctionNode function = MockFunctionNode(); final MockStatement statement = MockStatement(); @@ -198,7 +198,7 @@ void main(List args) async { } test('ToStringVisitor replaces toString in specified libraries (dart:ui)', () { - final ToStringVisitor visitor = ToStringVisitor(uiAndFlutter); + final frontend.ToStringVisitor visitor = frontend.ToStringVisitor(uiAndFlutter); final MockProcedure procedure = MockProcedure(); final MockFunctionNode function = MockFunctionNode(); final MockStatement statement = MockStatement(); @@ -219,7 +219,7 @@ void main(List args) async { }); test('ToStringVisitor replaces toString in specified libraries (package:flutter)', () { - final ToStringVisitor visitor = ToStringVisitor(uiAndFlutter); + final frontend.ToStringVisitor visitor = frontend.ToStringVisitor(uiAndFlutter); final MockProcedure procedure = MockProcedure(); final MockFunctionNode function = MockFunctionNode(); final MockStatement statement = MockStatement();