Skip to content

Instantly share code, notes, and snippets.

@sma
Last active February 23, 2021 15:08
Show Gist options
  • Save sma/b877cdc7e7668363502e8f620465683d to your computer and use it in GitHub Desktop.
Save sma/b877cdc7e7668363502e8f620465683d to your computer and use it in GitHub Desktop.
not even a proof of concept of a Dart to Swift transpiler
import 'fake_material.dart';
class Counter extends StatefulWidget {
@override
CounterState createState() {
return CounterState();
}
}
class CounterState extends State<Counter> {
int _count = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Row(
children: [
Text('$_count'),
FlatButton(
onPressed: () {
setState(() {
_count += 1;
});
},
child: Text('Increment'),
),
],
),
),
);
}
}
abstract class BuildContext {}
abstract class Widget {}
abstract class StatelessWidget extends Widget {
Widget build(BuildContext context);
}
abstract class StatefulWidget extends Widget {
State createState();
}
abstract class State<T extends StatefulWidget> {
void setState(void Function() callback) {
callback();
}
Widget build(BuildContext context);
}
class Scaffold extends Widget {
Scaffold({this.body});
final Widget body;
}
class Center extends Widget {
Center({this.child});
final Widget child;
}
class Row extends Widget {
Row({this.children});
final List<Widget> children;
}
class Text extends Widget {
Text(this.text);
final String text;
}
class FlatButton extends Widget {
FlatButton({this.onPressed, this.child});
final void Function() onPressed;
final Widget child;
}
import 'dart:io';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
class SwiftEmitter extends RecursiveAstVisitor<void> {
SwiftEmitter(this.sink);
final IOSink sink;
int _indentation = 0;
void emit(String line) {
if (line.startsWith('}')) _indentation--;
sink.writeln('${Iterable.generate(_indentation, (_) => ' ').join()}$line');
if (line.endsWith('{')) _indentation++;
}
@override
void visitClassDeclaration(ClassDeclaration node) {
emit('class ${node.name}: ${node.extendsClause.superclass} {');
super.visitClassDeclaration(node);
emit('}');
}
@override
void visitFieldDeclaration(FieldDeclaration node) {
for (final variable in node.fields.variables) {
emit('var ${variable.name}: ${node.fields.type} = ${variable.initializer}');
}
}
@override
void visitMethodDeclaration(MethodDeclaration node) {
final p = node.parameters.parameters //
.map((p) => '_ ${p.identifier}: ${(p as SimpleFormalParameter).type}')
.join(', ');
final r = '-> ${node.returnType}';
emit('func ${node.name}($p) $r {');
super.visitMethodDeclaration(node);
emit('}');
}
@override
void visitReturnStatement(ReturnStatement node) {
super.visitReturnStatement(node);
emit('return ${node.expression}');
}
}
void main(List<String> args) {
const example = ['lib/counter.dart'];
for (final arg in args.isNotEmpty ? args : example) {
final result = parseFile(
path: File(arg).absolute.path,
featureSet: FeatureSet.latestLanguageVersion(),
);
result.unit.accept(SwiftEmitter(stdout));
}
}
class Counter: StatefulWidget {
func createState() -> CounterState {
return CounterState()
}
}
class CounterState: State<Counter> {
var _count: int = 0
func build(_ context: BuildContext) -> Widget {
return Scaffold(body: Center(child: Row(children: [Text('$_count'), FlatButton(onPressed: () {setState(() {_count += 1;});}, child: Text('Increment'))])))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment