Есть ли в Dart препроцессор компилятора?

Поскольку перед запуском приложения dart требуется компиляция, мне интересно, доступен ли препроцессор компилятора или он запланирован на ближайшее время для Dart.
Мои поиски в сети / на сайте дартс пока не увенчались успехом.

(Под препроцессором я имею в виду что-то вроде:

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

или же:

#define NumType double
#define NumTypeZero 0.0

// used with :
NumType myNum = NumTypeZero;

или же:

#define DEBUG 

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

)

Изменить: Интересно, почему не все уже препроцессор, потому что кажется, что мы "близки" с этого момента:
- Дарт должен сканировать файлы на наличие библиотечных зависимостей, чтобы загрузить библиотеки в правильном порядке.
- Dart Editor также сканирует файлы на предмет синтаксиса, проверки типов и других проверок.
- Возможно, в редакторе запущена некоторая автоматизированная обработка файлов (я не смог найти для этого ценную ссылку, пожалуйста, дайте мне знать, если она у вас есть).

4 ответа

Решение

В основном то, что сказали другие парни...

Если вы компилируете с помощью dart2js, тряска дерева уже выбросит код внутри блока if (DEBUG) {}, если DEBUG является константой и ложью. Так что вы можете просто использовать операторы if.

Вы также можете использовать операторы assert(). Assert и переданное ему выражение будут выброшены при компиляции с помощью dart2js для производственного режима.

Так что на самом деле это то же самое поведение, которое вы бы получили с #ifdefs - вы можете думать о dart2js как о вашем препроцессоре;)

Я также не вижу причин, по которым вы захотите использовать #defines вместо констант.

Если вы хотите запустить свой код в DartVM, вы можете использовать dart2js --output-type=dart, чтобы потрясти дерево вашего источника дротиков.

Обновление: также смотрите String.fromEnvironment (), bool.fromEnvironment () и int.fromEnvironment (). Вы можете установить эти переменные окружения при компиляции, используя "dart2js -D=".

На данный момент нет препроцессора для Dart. Я не верю, что это планируется в ближайшее время. См. Выпуск 7238.

Дротик не требует компиляции. Только для создания Javascript, используемого приложениями вне виртуальной машины Dart. Например, сценарии Dart на стороне сервера никогда не требуют компиляции. Они могут генерировать моментальные снимки, чтобы уменьшить время загрузки, но это меньше этап компиляции и больше сохраняет состояние виртуальной машины после запуска приложения.

Тем не менее, были многочисленные дискуссии о внедрении зависимостей или других системах управления зависимостями, основанными на среде, но на данный момент не было достигнуто никакого консенсуса или решений. Смотрите выпуск 76

Редактировать:

1) Я не решаюсь использовать термин "правильный порядок" при загрузке библиотек. Для самой виртуальной машины Dart при загрузке сценария она по существу загружает все символы библиотеки, а затем начинает выполнение кода и сопоставление символов с символами в таблице. Компилятор dart2js делает что-то подобное, но затем также реализует Treehaking, чтобы попытаться изолировать неиспользуемый код и исключить его из окончательной компиляции. Но я далек от гуру компиляторов виртуальных машин или JavaScript, чтобы иметь больше информации о том, как этот процесс завершается.

2) Подобно другим интерпретируемым языкам, многие / большинство проверок выполняются во время выполнения, а не на этапе компиляции. На самом деле виртуальная машина Dart предназначена для работы с отключенной проверкой типов. Он включен только для разработки и фактически накладывает существенный штраф на скорость выполнения.

3) Я полагаю, что вы имеете в виду файл build.dart. Вы можете найти больше информации на Build.dart и Dart Editor.

Также обратите внимание, что редактор Dart фактически запускает скрипт dart с именем dart_analyzer для проверки кода при вводе. Это улучшается, но все еще далеко от совершенства. Он делает несколько шагов, чтобы попытаться предположить и связать типы и значения с кодом, но он также должен соответствовать спецификации языка dart. Таким образом, даже если анализатор может принять тип, основанный на окружающем коде, он все равно должен предоставить предупреждение, например, о том, что тип Node не имеет связанного с ним значения getter, даже если анализатор знает, что передаваемый Node на самом деле является текстом. поле ввода.

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

Предположим, у вас есть такой код:

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

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

Когда скомпилировано с dart2js -DDEBUG=true app.dart, вывод включает в себя поведение регистрации:

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

(функция журнала встроена, но печать все еще происходит)

Однако, если -DDEBUG не задан, поведение ведения журнала не включается в сгенерированный код JavaScript:

  main: function() {
  }

Нет, нет, и я сомневаюсь, что будет.

Для вашего первого примера эквивалентным было бы просто определить max(a, b) => a > b? а: б;

Или проще импортировать "dart:math";

который включает это уже.

Эквивалентом второго будет typedef для NumType, но сейчас Dart typedefs работает только для типов функций. Более общие typedefs, вероятно, появятся в более поздних версиях. Для части 0.0 просто const numTypeZero = 0.0;

В настоящее время нет эквивалента ifdef для выполнения условного кода. Однако, если в начале вашей программы вы определили const DEBUG = false; и написал if (DEBUG) print("вещи");

это будет примерно то, что вы хотите.

Вещи, которые вы ищете, очень много идиом, и часто предназначены для производительности. Компилятор Dart довольно умен и не нуждается в некоторых из них.

Так, например, определение max таким образом, по-видимому, заставляет его быть встроенным. Дарт встроит все это сам, если посчитает, что это того стоит, и способен изменить свое решение на полпути к исполнению. Объявление чего-либо как "const" делает его константой времени компиляции, так что это почти тот же эффект, что и #define. Возможность уменьшить размер кода путем определения таких символов, как DEBUG - это то, чего Дарт сейчас не хватает, хотя условная компиляция, вероятно, важнее по другим причинам, чем размер. Если вы работаете в браузере, а компилятор находится в браузере, то смысл уменьшения размера кода в загрузке. Если вы дождетесь запуска компилятора, будет слишком поздно, вы уже загрузили код. Если вы компилируете в JS раньше времени, в операторе if будет пропущен код, квалифицируемый константой false. Есть также режим dart2dart, который будет выполнять такие трансформации, а также минимизацию на источнике Dart. Но это не так важно, пока не появятся браузеры, в которых Dart изначально работает.

Другие вопросы по тегам