Generating classes at runtime / compile time with Dart - dart

A few questions about code generation with Dart:
Can dart generate a class at runtime with Dart for code running on the Dart VM?
Is there any sort of code generation equivalent to Java annotation processing at compile / pre run time?

1) Dart VM and dart2js don't support generating code at runtime.
One workaround is to generate code to a file and load it in a new isolate (can also be a data URI). The application can communicate with the generated code running in another isolate only by message passing.
2) This is what transformers are for, but transformers are only applied to dart2js (or pub serve at development time), but not to code run on the server side Dart VM.
https://github.com/dart-lang/build (currently only in developer preview) can be used for code generation for browser and server-side code. It's a tool that monitors source files and updates generated code when source file change.

I've now discovered that the dart team has a library for generating sources. It seems useful for generating sources pre-compile time: https://pub.dartlang.org/packages/source_gen

Related

Is there a way to determine the directory of the file in which the Dart file is being executed?

I'm writing a dart package in which I require the path to a file within the package to access the file for the package to work. The package is not written for the web platform.
My understanding of where packages are stored is limited, however, I would assume that there won't be a common directory for each platform, and even within platforms, I suppose it would vary based on how dart was installed on the specific machine.
Despite this being rather obvious that Dart as an AOT language would mean that the file being executed is just one snapshot. I would want to know if there is a way I can access the directory structure of package without having the end-user having to pass path values to me.
To give you some context, I want to load a dynamic library on runtime using dart:ffi, and do so within a package which will be published to pub.dev with the libraries. Do let me know if you have any ideas.
What I've tried so far:
Directory.current.path: This is obviously not going to work.
${File(Platform.resolvedExecutable).parent.path: This seems to be a workaround for Windows machines, I don't know how this would be useful for Linux, MacOS, or even Android and iOS for that matter.
Directory.fromUri(Platform.script) :
This leads me to the snapshot created by the compiler on Linux, nevertheless, of no use to me.
It definitely won't work with ahead-of-time compilation, because then the compiled code is nowhere near the source code.
If your program is being run on the stand-alone VM, and has direct access to the source code, you can potentially use Isolate.resolvePackageUri from dart:isolate to convert a known package: URI to a file:URI, which can then be used withdart:io` to load the file.
Future<File?> fileFromPackageUri(Uri packageUri) async {
var fileUri = await Isolate.resolvePackageUri(packageUri);
if (fileUri == null) return null; // No such pacakge.
return File.fromUri(fileUri);
}
Again, this only works when running from source. Otherwise you need to find a way to deploy your native library along with the Dart program and know where to find it.

How to get compiled down version of dart code

Is there a way to get compiled down version of a dart code for a particular target? Say the following code compiled for Dart VM.
I'm new to Dart and quite often come across high level abstract code and wonder how it is translated in VM.
names.forEach(print);
Dart is not compiled to something like Java-bytecode or DotNet IL.
Dart is compiled to machine code by the VM either ahead of time (AoT) or just in time (JiT)
https://mrale.ph/dartvm/
The name "Dart VM" is historical. Dart VM is a virtual machine in a
sense that it provides an execution environment for a high-level
programming language, however it does not imply that Dart is always
interpreted or JIT-compiled, when executing on Dart VM. For example,
Dart code can be compiled into machine code using Dart VM AOT pipeline
and then executed within a stripped version of the Dart VM, called
precompiled runtime, which does not contain any compiler components
and is incapable of loading Dart source code dynamically.
Dart 2 uses Kernel AST though generated by the common front-end (CFE)
There is some abstraction happening from the Dart language though
https://github.com/dart-lang/sdk/blob/master/pkg/kernel/README.md
Dart Kernel is a small high-level language derived from Dart. It is
designed for use as an intermediate format for whole-program analysis
and transformations, and to be consumed by codegen and execution
backends.
The kernel language has an in-memory representation in Dart and can be
serialized as binary or text.
Both the kernel language and its implementations are unstable and are under development.
See also https://github.com/dart-lang/sdk/blob/master/pkg/kernel/binary.md

How can I run dart2js dynamically in a Dart server web app?

I want to compile dart code to JS on-the-fly without invoking dart2js at the command line. Eg., (written in Dart) read in some dart code from a file and transform it to JS (must be in memory, filesystem is not writable).
I thought maybe dart2js would effectively just be a cli over a pub package I can call manually, but I can't find any information on doing this at runtime :(
(note: I know this idea sucks and it'll be very slow; it's just for something I'm prototyping and will ultimately use dart2js normally, I just can't address that yet)
https://try-dart-lang.appspot.com/ does this. The source is available. Its basically dart2js run through dart2js.
Not sure if this is the right repository https://github.com/peter-ahe-google/orphan-try
I guess Peter would be ok with pinging him about more information.
The project was replaced by pub.dartlang.org which uses a service running on the server https://github.com/dart-lang/dart-services where source is posted to for dart2js translation.

Dart: Possible to exchange source code on the fly in a running system?

In this article it says: "The Dart VM reads and executes source code, which means there is no compile step between edit and run.". Does that mean that you can exchange source-code on the fly in a running Dart system like in Erlang? Maybe the compiler is removed from the runtime system and then this is no longer possible. So that's why I'm asking.
Dart is run "natively" only in Dartium, which is a flavour of Chrome with DartVM. When you develop an application you still need to compile it it to JavaScript. This way you get fast development lifecycle and in the end you can compile code to JS. Because it's compiled code there is lots more room for compiler to run optimisations on the code. So from my perspective, the compiler is still there and I don't think you would be able to replace code at runtime.
You can send around source code and run it, but it would need to be in a separate isolate. Isolates do have some relationship to Erlang concepts.
The Dart VM doesn't support hot swapping (Called live edit in V8). However, based on mailing list discussions, it sounds like this is something that the authors do want to support in the future.
However, as the others have mentioned, it is possible to dynamically load code into another isolate.

Compile dart in the browser

In my application I generate big dart classes. Right now I compile them on the server, which takes CPU time. It would be much better to compile the Dart code within the browser. The code is then loaded via spawnURI.
Is it possible to invoke the dart2js compiler from within Dart code in a supported way as it is done in try.dartlang.org or do I need to copy the compiler into my project?
Compiling Dart to JavaScript will be faster on the server, because you can run dart2js via Dart VM. try.dartlang.org is running in a special version of dart2js, which has not been merged into the main source code.

Resources