| // Copyright (c) 2022, 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 'dart:io'; |
| |
| import 'package:_fe_analyzer_shared/src/util/relativize.dart'; |
| import 'package:dart_style/dart_style.dart' show DartFormatter; |
| |
| const String dataTypeOutputPrefix = 'datatype'; |
| |
| const List<int> dataTypeHierarchySizes = [ |
| 1, |
| 2, |
| 3, |
| 4, |
| 5, |
| 6, |
| 7, |
| 8, |
| 12, |
| 16, |
| 24, |
| 32, |
| 48, |
| 64, |
| 96, |
| 128, |
| 192, |
| 256, |
| // 512, too many nested expressions or statements |
| // 1024, |
| ]; |
| |
| void main() { |
| Uri dataFolder = Platform.script.resolve('generated/'); |
| generateDataTypeTests(dataFolder); |
| for (int size in dataTypeHierarchySizes) { |
| generateDataTypeHierarchy(dataFolder, size); |
| } |
| } |
| |
| void generateDataTypeTests(Uri dataFolder) { |
| Uri fileUri = dataFolder.resolve('${dataTypeOutputPrefix}.dart'); |
| StringBuffer sb = new StringBuffer(); |
| sb.writeln(''' |
| // Copyright (c) 2022, 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. |
| |
| // Generated by |
| // |
| // ${relativizeUri(Uri.base, Platform.script, isWindows)} |
| |
| import '../test_datatypes.dart';'''); |
| |
| for (int size in dataTypeHierarchySizes) { |
| sb.writeln(''' |
| import '${dataTypeOutputPrefix}$size.dart';'''); |
| } |
| |
| sb.writeln(''' |
| |
| List<Test> tests = ['''); |
| |
| for (int size in dataTypeHierarchySizes) { |
| sb.writeln(''' |
| Test<Base$size>( |
| $size, |
| createData$size, |
| {dynamicDispatchStrategy: incByDynamicDispatch$size, |
| ifThenElseStrategy: incByIfThenElseDispatch$size, |
| visitorStrategy: incByVisitorDispatch$size}), |
| '''); |
| } |
| |
| sb.writeln(''' |
| ]; |
| '''); |
| |
| String result = new DartFormatter().format(sb.toString()); |
| new File.fromUri(fileUri).writeAsStringSync(result); |
| } |
| |
| void generateDataTypeHierarchy(Uri dataFolder, int size) { |
| Uri fileUri = dataFolder.resolve('${dataTypeOutputPrefix}${size}.dart'); |
| StringBuffer sb = new StringBuffer(); |
| sb.writeln(''' |
| // Copyright (c) 2022, 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. |
| |
| // Generated by |
| // |
| // ${relativizeUri(Uri.base, Platform.script, isWindows)} |
| '''); |
| sb.writeln(''' |
| import '../test_datatypes.dart'; |
| |
| abstract class Base$size { |
| void dynamicDispatch(Counter counter); |
| |
| R accept<R, A>(Visitor$size<R, A> visitor, A arg); |
| } |
| '''); |
| for (int i = 0; i < size; i++) { |
| sb.writeln(''' |
| class Sub$i extends Base$size { |
| @override |
| void dynamicDispatch(Counter counter) { |
| counter.inc(); |
| } |
| |
| void ifThenElseDispatch$i(Counter counter) { |
| counter.inc(); |
| } |
| |
| void visitorDispatch$i(Counter counter) { |
| counter.inc(); |
| } |
| |
| @override |
| R accept<R, A>(Visitor$size<R, A> visitor, A arg) { |
| return visitor.visitSub$i(this, arg); |
| } |
| } |
| '''); |
| } |
| sb.writeln(''' |
| List<Base$size> createData$size() { |
| return ['''); |
| for (int i = 0; i < size; i++) { |
| sb.writeln(''' |
| Sub$i(),'''); |
| } |
| sb.writeln(''' |
| ]; |
| } |
| '''); |
| sb.writeln(''' |
| void incByDynamicDispatch$size(Base$size base, Counter counter) { |
| base.dynamicDispatch(counter); |
| } |
| '''); |
| |
| sb.writeln(''' |
| void incByIfThenElseDispatch$size(Base$size base, Counter counter) {'''); |
| for (int i = 0; i < size; i++) { |
| if (i == 0) { |
| sb.writeln(''' |
| if (base is Sub$i) {'''); |
| } else { |
| sb.writeln(''' |
| } else if (base is Sub$i) {'''); |
| } |
| sb.write(''' |
| base.ifThenElseDispatch$i(counter); |
| '''); |
| } |
| sb.writeln(''' |
| } |
| } |
| '''); |
| |
| sb.writeln(''' |
| const Visitor$size<void, Counter> visitor = CounterVisitor$size(); |
| |
| void incByVisitorDispatch$size(Base$size base, Counter counter) { |
| base.accept(visitor, counter); |
| } |
| '''); |
| |
| sb.writeln(''' |
| abstract class Visitor$size<R, A> {'''); |
| for (int i = 0; i < size; i++) { |
| sb.writeln(''' |
| R visitSub$i(Sub$i sub, A arg);'''); |
| } |
| sb.writeln(''' |
| } |
| '''); |
| |
| sb.writeln(''' |
| class CounterVisitor$size implements Visitor$size<void, Counter> { |
| const CounterVisitor$size(); |
| '''); |
| |
| for (int i = 0; i < size; i++) { |
| sb.writeln(''' |
| @override |
| void visitSub$i(Sub$i sub, Counter counter) { |
| sub.visitorDispatch$i(counter); |
| } |
| '''); |
| } |
| sb.writeln(''' |
| } |
| '''); |
| |
| String result = new DartFormatter().format(sb.toString()); |
| new File.fromUri(fileUri).writeAsStringSync(result); |
| } |