Руководство по GritQL¶
GritQL — язык запросов для поиска и исправления исходного кода с семантикой, похожей на SQL и другие декларативные языки запросов.
Шаблоны¶
Основа каждого запроса GritQL — шаблон для поиска в кодовой базе. Если вы знаете JavaScript, вы уже знаете GritQL: любой валидный фрагмент JavaScript-кода становится шаблоном GritQL, если заключить его в обратные кавычки.
Например, этот запрос найдет все места, где мы логируем "Hello world!" в кодовой базе:
Нажмите кнопку "Run Pattern", чтобы выполнить запрос на примере файла. Обратите внимание: он находит случаи, когда вызов разбит на несколько строк или использует одинарные кавычки вместо двойных, но игнорирует комментарий.
Это происходит потому, что GritQL ориентирован на структурное сопоставление, а не только на поиск по строкам. Каждый фрагмент кода автоматически преобразуется в синтаксическое дерево перед сопоставлением с кодовой базой.
Warning
Минус структурного сопоставления в том, что каждый фрагмент кода должен быть валидным JavaScript. Если нужно искать произвольные строки, используйте кавычки: "console.log("
Метапеременные¶
Во многих случаях нужно сопоставить шаблон, похожий на конкретный фрагмент кода, но не полностью совпадающий. Для этого замените нужные части на метапеременные: любой идентификатор, который начинается с символа доллара ($).
Например, этот запрос найдет все вызовы console.log независимо от того, какое сообщение они выводят:
Метапеременные можно называть как угодно, но мы рекомендуем использовать говорящие имена, чтобы было понятно, что они представляют.
Переписывания¶
GritQL полезен для поиска, но его главная сила — в возможности переписывать код. Чтобы превратить запрос в переписывание, добавьте =>, а затем фрагмент кода, которым нужно заменить совпадение.
Например, этот запрос найдет все вызовы console.log и заменит их на логирование через Winston:
Обратите внимание, что в заменяющем фрагменте кода можно использовать метапеременные, чтобы сохранить нужные части исходного кода.
Условия¶
Простых запросов часто достаточно, но можно добавить секцию where, чтобы фильтровать результаты. where похож на where в SQL и задает набор дополнительных условий, которые все должны быть истинными для совпадения.
Самое частое условие использует оператор сопоставления <:, чтобы проверить, соответствует ли метапеременная другому шаблону.
Например, можно использовать побочный запрос, чтобы заменить ориентированный на пользователя console.log на alert:
Условия в GritQL поддерживают все обычные булевы операторы вроде and, or и отрицания.
Например, можно использовать отрицание, чтобы исключить пользовательские сообщения из переписывания на Winston.
Альтернативные шаблоны¶
Обратите внимание, что в предыдущем примере мы использовали регулярное выражение для сопоставления сообщения вместо фрагмента кода.
В GritQL в качестве шаблонов также можно использовать регулярные выражения, строковые литералы и узлы AST.
Например, можно исключить вызовы console.log, где аргумент не строка, сославшись на узел AST string():
Составные шаблоны¶
Булевы выражения можно использовать и для объединения нескольких шаблонов в один.
Например, or позволяет сопоставить либо console.log, либо console.error:
Обратите внимание, что переписывания тоже являются шаблонами, поэтому их можно использовать и в условиях. Это позволяет строить вложенные переписывания.
Например, этот составной запрос переписывает все console.log в winston.debug, а все console.error в winston.warn:
Модификаторы шаблонов¶
В условиях часто нужно сопоставлять по контексту шаблона, а не только по самому шаблону. Для этого можно использовать ключевые слова-модификаторы, которые меняют поведение шаблона.
Например, модификатор within позволяет подняться вверх по синтаксическому дереву и сопоставлять console.log только если он находится внутри блока try/catch:
Вы могли заметить метапеременную $_ в секции within. Это анонимная метапеременная, которая сопоставляется с любым шаблоном. Она полезна, когда нужен заполнитель без привязки значения.
Вызовы шаблонов¶
При рефакторинге часто нужно переиспользовать общие шаблоны. Можно "вызвать" заранее определенный шаблон, обрамляя его скобками. Это похоже на вызов функции в языке программирования, и такие вызовы тоже могут принимать именованные аргументы.
В Grit есть богатая стандартная библиотека встроенных шаблонов, которые можно использовать в запросах.
Например, если нужно сопоставить все JavaScript-литералы со значением "42", можно вызвать шаблон literal из стандартной библиотеки Grit:
Источник: https://docs.grit.io/tutorials/gritql