Вывод синтаксического дерева кода
Синтаксическое дерево - внутренняя структура, которую интерпретатор javascript создает из исходного кода.
Обычно синтаксическое дерево создается для выполнения, но также может использоваться и для оптимизации, чем, собственно, и занимается google closure compiler.
Как правило, синтаксическое дерево может вам понадобиться, если вы захотите разобраться в каких-то оптимизациях, либо пишете расширение к компилятору. Такое расширение получает синтаксическое дерево, и поэтому может делать с кодом все, что угодно.
Так как синтаксическое дерево заточено под выполнение, то оно содержит все значимые элементы - без лишних пробелов, комментариев и т.п.
Поэтому чтение файла в синтаксическое дерево, а потом генерация кода по этому дереву - само по себе является оптимизацией. Это соответствует значению флага --compilation_level , равному WHITESPACE_ONLY .
Простейший способ получить синтаксическое дерево - это использовать флаг --print_tree .
Например, для скрипта ast.js :
function Animal(speed) {
/** @type {number} */
this.speed = speed
}
Печать дерева:
java -jar compiler.jar --js ast.js --use_only_custom_externs --print_tree
Флаг --use_only_custom_externs при печати дерева необходим, иначе дерево будет также содержать все стандартные экстерны.
Результат:
BLOCK [synthetic: 1]
BLOCK [synthetic: 1]
SCRIPT [source name: null] [encoded source length: 0] [base line: -1] [end line: -1] 1 [sourcename: /dev/null] [synthetic: 1]
BLOCK [synthetic: 1]
SCRIPT [source name: null] [encoded source length: 0] [base line: -1] [end line: -1] 1 [sourcename: ast.js] [synthetic: 1]
FUNCTION Animal 1 [sourcename: ast.js]
NAME Animal 1
LP 1
NAME a 1
BLOCK 1
EXPR_RESULT 3
ASSIGN 3 [jsdoc_info: JSDocInfo]
GETPROP 3
THIS 3
STRING speed 3
NAME a 3
Как видите, выводится основная информация. Сверху - несколько служебных строк, а ниже - наша функция.
Аннотация /** @type {number} */ превратилась во внутреннюю структуру JSDocInfo .
Обратите внимание, дерево печатается для уже откомпилированного кода, со всеми оптимизациями и заменами. Поэтому, в частности, локальная переменная speed в дереве называется a .
Вы также можете получить дерево в более красивом виде, используя флаг --print_ast :
java -jar compiler.jar --js ast.js --use_only_custom_externs --print_ast >ast.dot
Полученный текст - граф в формате DOT, для просмотра которого обычно используется утилита graphviz, работающая под основными ОС.
Запустив эту утилиту и преобразовав в ней файл ast.dot , получим картинку:
Выглядит красивее, но в тестовом дереве --print_tree содержится больше информации, поэтому обычно удобнее использовать текстовый формат, а графический - больше для диаграмм. Вдруг кто-нибудь решит диплом или диссертацию написать по оптимизации javascript
|
Спасибо! Для диплома кое что у Вас тут забрал.
Как то, слабо описано... Но спасибо и за такое...
Как-то неадекватно описано... Но и это я ценю...