flex-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Frank Wienberg <fr...@jangaroo.net>
Subject Re: [FlaconJS] pseudo emitter algorithm
Date Sun, 02 Dec 2012 10:21:42 GMT
Sorry for joining this discussion so late. Like before, I just would like
to contribute how we approached the problem at Jangaroo.
Some time ago, we created our own declarative, XML-based language, targeted
at creating Ext JS UIs, thus called EXML. EXML is very similar to MXML. The
main difference is that, to have IDE support and validation, EXML is
XML-Schema-based. For every module containing EXML files, an XSD is
generated, describing all available classes and their properties. EXML is
translated to ActionScript, which is then compiled to JavaScript, so we use
two chained compilers for EXML->AS and AS->JS.

After discovering that MXML is acutally not as tied to Flex components as I
used to think (I stumbled across this blog
I experimented with using MXML to define Ext JS UIs. I already have a
prototype of MXML support for Jangaroo on a github
uses a different approach.
Things became quite complicated with EXML when we wanted to make EXML->AS
generation more intelligent. The EXML->AS compiler needed to inspect
ActionScript classes, but these again could be referring to ActionScript
classes generated from EXML. So we have a circular dependency here, which
was complex to deal with.
Thus, for my MXML prototype, I chose a different approach, namely to
integrate MXML->JS compilation directly into the Jangaroo compiler, so that
when the compilation process needs class acme.Foo, it looks for both
acme/Foo.as and acme/Foo.mxml. If an MXML file is found, internally, the
compiler still generates ActionScript code, parses it into an AST, and then
hands it on to its standard JS code generator. While this may not be the
most efficient solution, it provides best reuse of software components and
works great!

There is one important aspect to consider when deciding which route to take.
If you, like Bernd Paradies, see JavaScript's role in this process as an
machine language, it is completely valid to generate JS code from ABC.
But this is not the viewpoint we take for Jangaroo. We chose ActionScript,
not Dart, TypeScript or Haxe, as the high-level language to compile to
JavaScript, because it is so very similar to JavaScript. In fact, it is a
super set of JavaScript, so that you can copy-paste JavaScript code into
your ActionScript program and it works!
When you look at Jangaroo-generated JavaScript code, it closely resembles
the original ActionScript source code. We optimized the compiler as well as
the runtime to give the impression that the JS code is actually the AS code
that you, the developer, wrote. Every source file results in a separate JS
file, which is also loaded separately in "debug mode". Even the line
numbers are kept precisely. This allows for debugging directly in the
browser without the need for any additional / new debugger tools.
Of course, this approach would not be possible at all when generating JS
code from ABC, not from AS/AST.

We would like to provide something similar for MXML, too. So the ideal
solution would be a mixture of the approaches described in this thread.
Combine Alex' datastructures and the AST->JS approach. This is also very
similar to how Ext JS UIs are specified using nested JS Object literals.
The idea would be to generate AS code from MXML that contains both the
datastructures and the code fragments (<fx:Script>), keeping the line
numbers (if possible). Then compile the resulting AS to JS, using the
AST-based method.
The format could look like so (pseudo-code):

01 <s:Panel xmlns:s="..."
02     title="hello world">
03   <s:Button label="click me!">
04     <s:click>
05       trace('clicked ' + event.source.label);
06     </s:click>
07   </s:Button>
08 </s:Panel>

could become something like

01 package ... { import ...; public class MyPanel extends Panel { public
function MyPanel() { MxmlUtil.apply(this, {
02     title: "hello world", children: [
03   { type: Button, label: "click me!",
04     click: function(event:MouseEvent) {
05       trace('clicked ' + event.source.label);
06     }
07   }
08 ]});}}}

When using the Jangaroo approach, this could be compiled to JavaScript,
keeping the line numbers for code fragments. So if you set a JavaScript
breakpoint in line 05, this would exactly correspond to line 5 of your MXML
source code!

There is just one game changer that would convince me that this effort is
not necessary, and that is JavaScript source maps support in all major
browsers. Then, the generated JavaScript code could look as ugly as you
like to have it, but the compiler would still have to provide the mapping
to the original source code. This should be possible using ABC with debug
information, shouldn't it?

What do you think?

  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message