blob: 5592a2d16ef3ef50265f5c9045bb3117d300ce59 [file] [log] [blame]
// 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);
}