Version 8 by komaz
on Nov 22, 2010 17:45.

compared with
Version 9 by komaz
on Nov 22, 2010 18:07.

Key
This line was removed.
This word was removed. This word was added.
This line was added.

Changes (7)

View Page History
{noformat}

So, what we want here - the DSL source just defines a list of fully qualified static methods, and DSL plugin just creates instance local static methods which route to corresponding 'foreign' static methods:
{noformat}
class Sample
{
private static File os(Str str) { File.os(str) }
...
}
{noformat}

The creation of method routers and their bodies look fairly simple, but there's a problem - again, DSL plugins are called a bit too late and compiler have already generated a lot of compiler errors. Fail? No! We can do another black magic trick - go through all complier [errs|http://fantom.org/doc/compiler/Compiler#errs] and remove those which caused by (yet) undefined methods:
{noformat}
newQnames := qnames.a
//build qnames of new instance methods
newQnames := qnames.map { "${type.qname}.${it[it.indexr(".")..-1]}" }
//build compiler error message for further filtering
errMsgs := newQnames.map { "Unknown method '$it'" }
compiler.errs = compiler.errs.exclude { it.msg == "Unknown method '$newQname'" errMsgs.contains(it.msg) }
{noformat}

However we also need to manually go through all expressions and _adjust_ [CallExpr|http://fantom.org/doc/compiler/CallExpr] instances to insert correct references to our newly created methods. After then everything compiles and runs as expected, though console output will still display compilation errors during building. The dirty code of {{StaticImportDsl}} can be found [here|^StaticImportDsl.fan].

In fact, the example above have nothing common with initial purpose of DSLs, it is complete compiler plugin which significantly changes the source code meaning.