Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a compiler preprocessor in Dart?

Since a compilation is required before launching a dart application, i wonder if compiler preprocessor is available, or is scheduled in a near future for Dart.
My searches on the net / inside the dart site have proven unsuccessful so far.

( By preprocessor, i mean something like :

#define max(A,B)    ( (A) > (B) ? (A):(B)) 

or :

#define NumType double
#define NumTypeZero 0.0

// used with :
NumType myNum = NumTypeZero;

or :

#define DEBUG 

// use
#ifdef DEBUG
   print('var1 : $var1, var2:$var2, ...');
#endif

)

Edit : I wonder why there's not allready a pre-processor because it seems we are 'near' from that point :
- Dart has to scan the files for library dependencies to load the libraries in the right order.
- Dart editor also scan files for syntax, type checking and other checks.
- It's possible to have some automated file processing launched within the editor (i couldn't find a valuable link for this, please let me know if you have one).

like image 299
GameAlchemist Avatar asked Nov 29 '13 14:11

GameAlchemist


3 Answers

Basically what the other guys said...

If you're compiling with dart2js, the tree-shaking will already throw out the code inside an if (DEBUG) {} block, if DEBUG is a constant and false. So you can just use if statements.

You can also use assert() statements. The assert, and the expression passed to it will be thrown away when compiling with dart2js for production mode.

So this is actually the same behaviour that you'd get with #ifdefs - you can think of dart2js as your preprocessor ;)

I also don't see any reason why you would want to use #defines instead of constants.

If you want to run your code in the DartVM, you can use dart2js --output-type=dart to do tree-shaking on your dart source.

Update: Also see String.fromEnvironment(), bool.fromEnvironment(), and int.fromEnvironment(). You can set these environment variables when compiling by using "dart2js -D<env-var-name>=<value>".

like image 161
Greg Lowe Avatar answered Oct 19 '22 12:10

Greg Lowe


At this time there is no preprocessor for Dart. I do not believe that one is planned in the near future either. See Issue 7238

Dart does not require compilation. Only to generate Javascript usable by apps outside of the Dart VM. For instance server side Dart scripts never require compilation. They can generate snapshots to decrease load times but that is less of a compilation step and more storing the state of the VM after the application has launched.

That said, there have been numerous discussions about dependency injection or other dependency management systems based on environment but no consensus or decisions have been reached at this point. See Issue 76

Edit:

1) I hesitate to use the term 'right order' on loading libraries. For the Dart VM itself, it essentially loads all of the library symbols on loading the script and then begins executing the code and matching the symbols to those in the table. The dart2js compiler does something similar but will then also implement treeshaking to try to isolate code that is not used and omit it from the final compilation. But I'm far from a VM or JavaScript compiler guru to have more information on how that process is completed.

2) Similar to other interpreted languages many/most checks are preformed at runtime as opposed to a compile time step. And in fact the Dart VM is designed to run with type checking disabled. It is only enabled for development and actually imposes a significant penalty on the speed of execution.

3) I believe you are referring to the build.dart file. You can find more information at Build.dart and the Dart Editor

Also note that the Dart editor is actually running a dart script called dart_analyzer to validate the code as you type. It is improving but still far from perfect. It does a number of steps to try and assume and associate types and values to the code, but it must also conform to the dart language specification. Thus even if the analyzer is able to assume a type based on surrounding code, it must still provide a warning for instance that type Node has no getter 'value' associated with it, even though the analyzer knows that Node being passed is actually a text input field.

like image 31
Matt B Avatar answered Oct 19 '22 12:10

Matt B


From http://blog.sethladd.com/2013/12/compile-time-dead-code-elimination-with.html

Suppose you have code like this:

log(String msg) {
  if (const String.fromEnvironment('DEBUG') != null) {
    print('debug: $msg');
  }
}

main() {
  log('In production, I do not exist');
}

When compiled with dart2js -DDEBUG=true app.dart, the output includes the logging behavior:

  main: function() {
    H.printString("debug: In the production release, I do not exist");
  }

(the log function is inlined, but the print still happens)

However, if -DDEBUG is not set, the logging behavior is not included in the generated JavaScript code:

  main: function() {
  }
like image 3
Seth Ladd Avatar answered Oct 19 '22 13:10

Seth Ladd