diff --git a/book.md b/book.md index cafaa1c..e9ba17e 100644 --- a/book.md +++ b/book.md @@ -84,14 +84,206 @@ Данные методы составляют основной программный интерфейс для внешней по отношению к парсеру системы. Позволяют выполнить разбор исходного кода, обход AST с плагинами и выполнить модификацию исходного кода по сгенерированным плагинами заменам. Чаще всего используется метод `Пуск()`, который заключает в себе типовую последовательность вызовов `Разобрать()`, `Подключить()` и `Посетить()`. -Примеры использования данных методов смотрите в скриптах в папке /oscript - -* `Пуск(Исходник: Строка, Плагины: Массив или Обработка, Параметры: Соответствие, Окружение: Структура): Массив` - выполняет разбор исходника в указанном окружении, обход AST с указанными плагинами и указанными параметрами плагинов, возвращает результаты (обычно текстовые) работы плагинов. -* `Разобрать(Исходник: Строка, ВнешнееОкружение: Структура): Структура` - выполняет разбор исходника в указанном окружении и возвращает AST. -* `Подключить(Плагины: Массив или Обработка)` - подключает плагины к парсеру. -* `Посетить(Модуль: Структура, Параметры: Соответствие)` - выполняет обход AST с подключенными плагинами и указанными параметрами плагинов. -* `Токенизировать(Исходник: Строка): ТаблицаЗначений` - выполняет лексический анализ и возвращает таблицу токенов. -* `ВыполнитьЗамены(): Строка` - возвращает исходник после выполнения на нем замен участков текста. +Рабочие примеры использования данных методов смотрите в скриптах в папке /oscript + +* **`Пуск(Исходник, Плагины, Параметры, Окружение): Массив`** - выполняет разбор исходника в указанном окружении, обход AST с указанными плагинами и их параметрами и возвращает результаты (обычно текстовые) работы плагинов. + + Параметры: + * `Исходник: Строка` -- исходный код для анализа. + * `Плагины: Массив или Обработка` -- плагины, с которыми будет выполняться обход AST. + * `Параметры: Соответствие (необязательный)` -- параметры плагинов. + * `Окружение: Структура (необязательный)` -- окружение (контекст), в котором будет выполняться разбор исходника. + + Пример с одним плагином: + + ```bsl + Исходник = ЧтениеТекста.Прочитать(); + + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + + Плагин = ВнешниеОбработки.Создать(ПлагинПуть, Ложь); + + Парсер.Пуск(Исходник, Плагин); // тут выполняется синтаксический анализ и обход АСД с плагинами + + Для Каждого Ошибка Из Парсер.ТаблицаОшибок() Цикл + Сообщить(Ошибка.Текст); // вывод найденных парсером и плагином ошибок + КонецЦикла; + ``` + + Пример с набором плагинов: + + ```bsl + Исходник = ЧтениеТекста.Прочитать(); + + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + + Плагины = Новый Массив; + Плагины.Добавить(ВнешниеОбработки.Создать(Плагин1Путь, Ложь)); + Плагины.Добавить(ВнешниеОбработки.Создать(Плагин2Путь, Ложь)); + + Парсер.Пуск(Исходник, Плагины); // тут выполняется синтаксический анализ и обход АСД с плагинами + + Для Каждого Ошибка Из Парсер.ТаблицаОшибок() Цикл + Сообщить(Ошибка.Текст); // вывод найденных парсером и плагинами ошибок + КонецЦикла; + ``` + + Пример с параметрами плагинов: + + ```bsl + Исходник = ЧтениеТекста.Прочитать(); + + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + Плагин1 = ВнешниеОбработки.Создать(Плагин1Путь, Ложь); + Плагин2 = ВнешниеОбработки.Создать(Плагин2Путь, Ложь); + + Плагины = Новый Массив; + Плагины.Добавить(Плагин1); + Плагины.Добавить(Плагин2); + + Параметры = Новый Соответствие; // у каждого плагина своя структура параметров + Параметры[Плагин1.ЭтотОбъект] = Новый Структура("Параметр1, Параметр2", 1, 2); + Параметры[Плагин2.ЭтотОбъект] = Новый Структура("Параметр1, Параметр2", 3, 4) + + Парсер.Пуск(Исходник, Плагины, Параметры); // тут выполняется синтаксический анализ и обход АСД с плагинами + + Для Каждого Ошибка Из Парсер.ТаблицаОшибок() Цикл + Сообщить(Ошибка.Текст); // вывод найденных парсером и плагинами ошибок + КонецЦикла; + ``` + + Пример с окружением: + + ```bsl + Исходник = ЧтениеТекста.Прочитать(); + + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + + Плагин = ВнешниеОбработки.Создать(ПлагинПуть, Ложь)); + + Окружение = Парсер.Окружение(); + + // например, контекст формы: + Элемент = Парсер.ЭлементОкружения("ЭтаФорма"); + Окружение.Переменные.Вставить("ЭтаФорма", Элемент); // добавили в контекст переменную + // ... + Элемент = Парсер.ЭлементОкружения("РеквизитФормыВЗначение"); + Окружение.Методы.Вставить("РеквизитФормыВЗначение", Элемент); // добавили в контекст метод + // ... + + Парсер.Пуск(Исходник, Плагины,, Окружение); + + Для Каждого Ошибка Из Парсер.ТаблицаОшибок() Цикл + Сообщить(Ошибка.Текст); // вывод найденных парсером и плагином ошибок + КонецЦикла; + ``` + +* **`Разобрать(Исходник, Окружение): Структура`** - выполняет разбор исходника в указанном окружении и возвращает AST. + + Параметры: + * `Исходник: Строка` -- исходный код для анализа. + * `Окружение: Структура (необязательный)` -- окружение (контекст), в котором будет выполняться разбор исходника. + + Пример: + + ```bsl + Исходник = ЧтениеТекста.Прочитать(); + + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + + Окружение = Парсер.Окружение(); + + // например, контекст формы: + Элемент = Парсер.ЭлементОкружения("ЭтаФорма"); + Окружение.Переменные.Вставить("ЭтаФорма", Элемент); // добавили в контекст переменную + // ... + Элемент = Парсер.ЭлементОкружения("РеквизитФормыВЗначение"); + Окружение.Методы.Вставить("РеквизитФормыВЗначение", Элемент); // добавили в контекст метод + // ... + + АСД = Парсер.Разобрать(Исходник, Окружение); + + Сообщить(АСД.Объявления.Количество()); + ``` + +* **`Подключить(Плагины)`** - подключает плагины к парсеру. + + Параметры: + * `Плагины: Массив или Обработка` -- плагины для подключения к парсеру. + + Пример: + + ```bsl + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + Плагин = ВнешниеОбработки.Создать(ПлагинПуть, Ложь); + + АСД = Парсер.Разобрать(Исходник); // тут выполняется синтаксический анализ + Парсер.Подключить(Плагин); // тут плагин подключается к парсеру + Парсер.Посетить(АСД); // тут выполняется обход АСД с вызовом подписок плагина + + Для Каждого Ошибка Из Парсер.ТаблицаОшибок() Цикл + Сообщить(Ошибка.Текст); // вывод найденных парсером и плагином ошибок + КонецЦикла; + ``` + +* **`Посетить(Модуль: Структура, Параметры: Соответствие)`** - выполняет обход AST с подключенными плагинами и указанными параметрами плагинов. + + Параметры: + * `Модуль: Структура` -- АСД для обхода. + * `Параметры: Соответствие (необязательный)` -- параметры плагинов, с которыми нужно выполнить обход. + + Пример: + + ```bsl + Исходник = ЧтениеТекста.Прочитать(); + + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + Плагин = ВнешниеОбработки.Создать(ПлагинПуть, Ложь); + + АСД = Парсер.Разобрать(Исходник); // тут выполняется синтаксический анализ + Парсер.Подключить(Плагин); // тут плагин подключается к парсеру + Парсер.Посетить(АСД); // тут выполняется обход АСД с вызовом подписок плагина + + Для Каждого Ошибка Из Парсер.ТаблицаОшибок() Цикл + Сообщить(Ошибка.Текст); // вывод найденных парсером и плагином ошибок + КонецЦикла; + ``` + +* **`Токенизировать(Исходник: Строка): ТаблицаЗначений`** - выполняет лексический анализ и возвращает таблицу токенов. + + Параметры: + * `Исходник: Строка` -- исходный код для анализа. + + Пример: + + ```bsl + Исходник = ЧтениеТекста.Прочитать(); + + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + + ТаблицаТокенов = Парсер.Токенизировать(Исходник); // тут выполняется лексический анализ + + Для Каждого ДанныеТокена Из ТаблицаТокенов Цикл + Сообщить(ДанныеТокена.Токен); // вывод всех токенов + КонецЦикла; + ``` + +* **`ВыполнитьЗамены(): Строка`** - возвращает исходник после выполнения на нем замен участков текста. + + Пример: + + ```bsl + Исходник = ЧтениеТекста.Прочитать(); + + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + Плагин = ВнешниеОбработки.Создать(ПлагинПуть, Ложь); + + Парсер.Пуск(Исходник, Плагин); // тут плагин наполняет таблицу замен + + ИсправленныйИсходник = Парсер.ВыполнитьЗамены(); // тут по таблице замен последовательно заменяются участки текста в исходнике. + + Сообщить(ИсправленныйИсходник) + ``` #### Дополнительные методы @@ -99,19 +291,324 @@ Примеры использования данных методов смотрите в плагинах в папке /plugins -* `КлючевыеСлова(): Структура` - возвращает перечисление допустимых ключевых слов (например: `КлючевыеСлова.ИначеЕсли`). -* `Токены(): Структура` - возвращает перечисление допустимых токенов (например: `Токены.ЗнакСложения`). -* `Типы(): Структура` - возвращает перечисление допустимых типов узлов AST (например: `Типы.ОператорПрисваивания`). -* `Директивы(): Структура` - возвращает перечисление допустимых директив (например: `Директивы.НаСервереБезКонтекста`). -* `Аннотации(): Структура` - возвращает перечисление допустимых аннотаций (например: `Аннотации.Вместо`). -* `ИнструкцииПрепроцессора(): Структура` - возвращает перечисление допустимых инструкций препроцессора (например: `ИнструкцииПрепроцессора.КонецОбласти`). -* `СимволыПрепроцессора(): Структура` - возвращает перечисление допустимых символов препроцессора (например: `СимволыПрепроцессора.ТолстыйКлиентОбычноеПриложение`). -* `Стек(): Массив` - возвращает стек узлов, который меняется во время обхода AST и позволяет получить текущие родительские узлы в подписках плагинов. -* `Счетчики(): Соответствие` - возвращает счетчики родительских узлов, которые меняются во время обхода AST и позволяет получить количество текущих родительских узлов по типам в подписках плагинов. -* `Исходник(): Строка` - возвращает текущий исходник. -* `ТаблицаТокенов(): ТаблицаЗначений` - возвращает текущую таблицу токенов, которая содержит подробную информацию о положении каждого токена в исходном коде. Каждый узел AST имеет поля `Начало` и `Конец`, которые хранят строки данной таблицы и представляют первый и последний токен узла. Например, получить номер первой строки узла можно так: `НомерСтроки = Узел.Начало.НомерСтроки`. Получить следующий за узлом токен можно так: `ДанныеСледующегоТокена = ТаблицаТокенов[Узел.Конец.Индекс + 1]`. -* `ТаблицаЗамен(): ТаблицаЗначений` - возвращает текущую таблицу замен, в которой плагины могут регистрировать замены. -* `ТаблицаОшибок(): ТаблицаЗначений` - возвращает текущую таблицу ошибок, в которой плагины могут регистрировать ошибки. +* **`КлючевыеСлова(): Структура`** - возвращает перечисление допустимых ключевых слов. + + Пример (фрагмент кода плагина): + + ```bsl + Перем ТаблицаТокенов, КлючевыеСлова; + + Процедура Открыть(Парсер, Параметры) Экспорт + ТаблицаТокенов = Парсер.ТаблицаТокенов(); + КлючевыеСлова = Парсер.КлючевыеСлова(); + КонецПроцедуры + + Функция Закрыть() Экспорт + Для Каждого ДанныеТокена Из ТаблицаТокенов Цикл + Если ДанныеТокена.Токен = КлючевыеСлова.ИначеЕсли Тогда + // ... + КонецЕсли; + КонецЦикла; + Возврат Неопределено; + КонецФункции + ``` + +* **`Токены(): Структура`** - возвращает перечисление допустимых токенов. + + Пример (фрагмент кода плагина): + + ```bsl + Перем ТаблицаТокенов, Токены; + + Процедура Открыть(Парсер, Параметры) Экспорт + ТаблицаТокенов = Парсер.ТаблицаТокенов(); + Токены = Парсер.Токены(); + КонецПроцедуры + + Функция Закрыть() Экспорт + Для Каждого ДанныеТокена Из ТаблицаТокенов Цикл + Если ДанныеТокена.Токен = Токены.ЗнакСложения Тогда + // ... + КонецЕсли; + КонецЦикла; + Возврат Неопределено; + КонецФункции + ``` + +* **`Типы(): Структура`** - возвращает перечисление допустимых типов узлов AST. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Типы; + + Процедура Открыть(Парсер, Параметры) Экспорт + Типы = Парсер.Типы(); + КонецПроцедуры + + Процедура ПосетитьОператоры(Операторы) Экспорт + Для Каждого Оператор Из Операторы Цикл + Если Оператор.Тип = Типы.ОператорПрисваивания Тогда + // ... + КонецЕсли; + КонецЦикла; + КонецПроцедуры + ``` + +* **`Директивы(): Структура`** - возвращает перечисление допустимых директив. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Директивы; + + Процедура Открыть(Парсер, Параметры) Экспорт + Директивы = Парсер.Директивы(); + КонецПроцедуры + + Процедура ПосетитьОбъявлениеПеременнойМодуля(Объявление) Экспорт + Если Объявление.Директивы.Количество() = 1 + И Объявление[0].Директива = Директивы.НаКлиенте Тогда + // ... + КонецЕсли; + КонецПроцедуры + ``` + +* **`Аннотации(): Структура`** - возвращает перечисление допустимых аннотаций. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Аннотации; + + Процедура Открыть(Парсер, Параметры) Экспорт + Аннотации = Парсер.Аннотации(); + КонецПроцедуры + + Процедура ПосетитьОбъявлениеМетода(Объявление) Экспорт + Аннотации = Объявление.Сигнатура.Аннотации; + Если Аннотации.Количество() = 1 + И Аннотации[0].Аннотация = Аннотации.Вместо Тогда + // ... + КонецЕсли; + КонецПроцедуры + ``` + +* **`СимволыПрепроцессора(): Структура`** - возвращает перечисление допустимых символов препроцессора. + + Пример (фрагмент кода плагина): + + ```bsl + Перем СимволыПрепроцессора; + + Процедура Открыть(Парсер, Параметры) Экспорт + СимволыПрепроцессора = Парсер.СимволыПрепроцессора(); + КонецПроцедуры + + Процедура ПосетитьВыражениеПрепроцессораСимвол(Выражение) Экспорт + Если Выражение.Символ = СимволыПрепроцессора.ТолстыйКлиентОбычноеПриложение Тогда + // ... + КонецЕсли; + КонецПроцедуры + ``` + +* **`Стек(): Массив`** - возвращает стек узлов, который меняется во время обхода AST и позволяет получить текущие родительские узлы в подписках плагинов. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Стек; + + Процедура Открыть(Парсер, Параметры) Экспорт + Стек = Парсер.Стек(); + КонецПроцедуры + + Процедура ПосетитьВыражениеТернарное(Выражение) Экспорт + Для Каждого Родитель Из Стек Цикл + Если Родитель.Тип = Типы.ВыражениеТернарное Тогда + Сообщить("Вложенный тернарный оператор"); + Прервать; + КонецЕсли; + КонецЦикла; + КонецПроцедуры + ``` + +* **`Счетчики(): Соответствие`** - возвращает счетчики родительских узлов, которые меняются во время обхода AST и позволяет получить количество текущих родительских узлов по типам в подписках плагинов. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Счетчики; + + Процедура Открыть(Парсер, Параметры) Экспорт + Счетчики = Парсер.Счетчики(); + КонецПроцедуры + + Процедура ПосетитьВыражениеТернарное(Выражение) Экспорт + Если Счетчики[Типы.ВыражениеТернарное] > 0 Тогда + Сообщить("Вложенный тернарный оператор"); + КонецЕсли; + КонецПроцедуры + ``` + +* **`Исходник(): Строка`** - возвращает текущий исходник. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Исходник, Токены, ТаблицаТокенов; + + Процедура Открыть(Парсер, Параметры) Экспорт + Исходник = Парсер.Исходник(); + Токены = Парсер.Токены(); + ТаблицаТокенов = Парсер.ТаблицаТокенов(); + КонецПроцедуры + + Процедура ПосетитьОбъявлениеМетода(ОбъявлениеМетода) Экспорт + ДанныеСледующегоТокена = ТаблицаТокенов[ОбъявлениеМетода.Конец.Индекс + 1]; + Если ДанныеСледующегоТокена.Токен = Токены.Комментарий Тогда + Сообщить(Сред(Исходник, ДанныеСледующегоТокена.Позиция, ДанныеСледующегоТокена.Длина)); + КонецЕсли; + КонецПроцедуры + ``` + +* **`ТаблицаТокенов(): ТаблицаЗначений`** - возвращает текущую таблицу токенов, которая содержит подробную информацию о положении каждого токена в исходном коде. Каждый узел AST имеет поля `Начало` и `Конец`, которые хранят строки данной таблицы и представляют первый и последний токен узла. Например, получить номер первой строки узла можно так: `НомерСтроки = Узел.Начало.НомерСтроки`. Получить следующий за узлом токен можно так: `ДанныеСледующегоТокена = ТаблицаТокенов[Узел.Конец.Индекс + 1]`. + + Колонки: + * `Индекс: Число` -- индекс строки для удобства. + * `Токен: Строка` -- токен из перечисления Токены. + * `НомерСтроки: Число` -- номер строки, в которой находится токен. + * `НомерКолонки: Число` -- номер колонки, в которой начинается токен. + * `Позиция: Число` -- позиция в тексте, в которой начинается токен. + * `Длина: Число` -- длина участка текста, который представляет токен. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Исходник, Токены, ТаблицаТокенов; + + Процедура Открыть(Парсер, Параметры) Экспорт + Исходник = Парсер.Исходник(); + Токены = Парсер.Токены(); + ТаблицаТокенов = Парсер.ТаблицаТокенов(); + КонецПроцедуры + + Процедура ПосетитьОбъявлениеМетода(ОбъявлениеМетода) Экспорт + ДанныеСледующегоТокена = ТаблицаТокенов[ОбъявлениеМетода.Конец.Индекс + 1]; + Если ДанныеСледующегоТокена.Токен = Токены.Комментарий Тогда + Сообщить(Сред(Исходник, ДанныеСледующегоТокена.Позиция, ДанныеСледующегоТокена.Длина)); + КонецЕсли; + КонецПроцедуры + ``` + +* **`ТаблицаОшибок(): ТаблицаЗначений`** - возвращает текущую таблицу ошибок, в которой плагины могут регистрировать ошибки. + + Колонки: + * `Источник: Строка` -- имя обработки, которая зарегистрировала ошибку. + * `Текст: Строка` -- текст ошибки + * `ПозицияНачала: Число` -- позиция в тексте, с которой начинается ошибочный участок. + * `ПозицияКонца: Число` -- позиция в тексте, на которой заканчивается ошибочный участок. + * `ЕстьЗамена: Булево` -- признак, что для ошибки есть замена (исправление) в таблице замен. + * `Код: Число` -- код ошибки (для плагинов всегда 0). + * `НомерСтрокиНачала: Число` -- номер строки, на которой начинается ошибочный участок. + * `НомерКолонкиНачала: Число` -- номер колонки, с которой начинается ошибочный участок. + * `НомерСтрокиКонца: Число` -- номер строки, на которой заканчивается ошибочный участок. + * `НомерКолонкиКонца: Число` -- номер колонки, на которой заканчивается ошибочный участок. + * `МинутНаИсправление: Число` -- примерная оценка затрат на исправление ошибки в минутах. + * `Серьезность: Строка` -- произвольный текст на усмотрение разработчика. + * `Приоритет: Число` -- произвольное число на усмотрение разработчика. + * `Правило: Строка` -- произвольный текст на усмотрение разработчика. + * `Тип: Строка` -- произвольный текст на усмотрение разработчика. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Исходник, Токены, ТаблицаТокенов; + + Процедура Открыть(Парсер, Параметры) Экспорт + Исходник = Парсер.Исходник(); + Токены = Парсер.Токены(); + ТаблицаТокенов = Парсер.ТаблицаТокенов(); + КонецПроцедуры + + Процедура ПосетитьОбъявлениеМетода(ОбъявлениеМетода) Экспорт + + СледующийТокен = ТаблицаТокенов[ОбъявлениеМетода.Конец.Индекс + 1]; + + Если СледующийТокен.Токен = Токены.Комментарий + И СледующийТокен.НомерСтроки = ОбъявлениеМетода.Конец.НомерСтроки Тогда + + Комментарий = СокрП(Сред(Исходник, СледующийТокен.Позиция, СледующийТокен.Длина)); + ПравильныйКомментарий = СтрШаблон(" %1%2", ОбъявлениеМетода.Сигнатура.Имя, "()"); + + Если Комментарий <> ПравильныйКомментарий Тогда + Ошибка("Замыкающий комментарий неактуален", СледующийТокен); + КонецЕсли; + + КонецЕсли; + + КонецПроцедуры + + Процедура Ошибка(Текст, ДанныеТокена) + Ошибка = ТаблицаОшибок.Добавить(); + Ошибка.Источник = "ИмяЭтогоПлагина"; + Ошибка.Текст = Текст; + Ошибка.ПозицияНачала = ДанныеТокена.Позиция; + Ошибка.НомерСтрокиНачала = ДанныеТокена.НомерСтроки; + Ошибка.НомерКолонкиНачала = ДанныеТокена.НомерКолонки; + Ошибка.ПозицияКонца = ДанныеТокена.Позиция + ДанныеТокена.Длина; + Ошибка.НомерСтрокиКонца = ДанныеТокена.НомерСтроки; + Ошибка.НомерКолонкиКонца = ДанныеТокена.НомерКолонки + ДанныеТокена.Длина; + КонецПроцедуры + + ``` + +* **`ТаблицаЗамен(): ТаблицаЗначений`** - возвращает текущую таблицу замен, в которой плагины могут регистрировать замены. + + Колонки: + * `Источник: Число` -- имя обработки, которая зарегистрировала замену. + * `Текст: Строка` -- фрагмент текста, на который нужно заменить указанный участок. + * `Позиция: Число` -- позиция участка текста для замены. + * `Длина: Число` -- длина участка текста для замены. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Исходник, Токены, ТаблицаТокенов, ТаблицаЗамен; + + Процедура Открыть(Парсер, Параметры) Экспорт + Исходник = Парсер.Исходник(); + Токены = Парсер.Токены(); + ТаблицаТокенов = Парсер.ТаблицаТокенов(); + ТаблицаЗамен = Парсер.ТаблицаЗамен(); + КонецПроцедуры + + Процедура ПосетитьОбъявлениеМетода(ОбъявлениеМетода) Экспорт + + СледующийТокен = ТаблицаТокенов[ОбъявлениеМетода.Конец.Индекс + 1]; + + Если СледующийТокен.Токен = Токены.Комментарий + И СледующийТокен.НомерСтроки = ОбъявлениеМетода.Конец.НомерСтроки Тогда + + Комментарий = СокрП(Сред(Исходник, СледующийТокен.Позиция, СледующийТокен.Длина)); + ПравильныйКомментарий = СтрШаблон(" %1%2", ОбъявлениеМетода.Сигнатура.Имя, "()"); + + Если Комментарий <> ПравильныйКомментарий Тогда + Замена(ПравильныйКомментарий, СледующийТокен); + КонецЕсли; + + КонецЕсли; + + КонецПроцедуры + + Процедура Замена(Текст, ДанныеТокена) + НоваяЗамена = ТаблицаЗамен.Добавить(); + НоваяЗамена.Источник = "ИмяЭтогоПлагина"; + НоваяЗамена.Текст = Текст; + НоваяЗамена.Позиция = ДанныеТокена.Позиция; + НоваяЗамена.Длина = ДанныеТокена.Длина; + КонецПроцедуры + ``` #### Продвинутые методы diff --git a/docs/index.html b/docs/index.html index 8838b7c..7b49961 100644 --- a/docs/index.html +++ b/docs/index.html @@ -12,7 +12,8 @@
+ +Перем Результат; + +// Будет вызвана один раз перед обходом дерева. +Процедура Открыть(Парсер, Параметры) Экспорт + Результат = Новый Массив; +КонецПроцедуры // Открыть() + +// Будет вызвана после полного обхода дерева. +// Возвращает текстовый результат работы плагина, если он есть. +Функция Закрыть() Экспорт + Возврат СтрСоединить(Результат); +КонецФункции // Закрыть() + +// Возвращает список процедур-подписок, которые будут вызываться визитером. +// Состав возможных подписок можно посмотреть в парсере в функции Подписки(). +Функция Подписки() Экспорт + Перем Подписки; + Подписки = Новый Массив; + Подписки.Добавить("ПосетитьОператорПрисваивания"); + Возврат Подписки; +КонецФункции // Подписки() + +#Область РеализацияПодписок + +Процедура ПосетитьОператорПрисваивания(ОператорПрисваивания) Экспорт + +КонецПроцедуры // ПосетитьОператорПрисваивания() + +#КонецОбласти // РеализацияПодписок + ++ + +
Перем Типы; Перем Токены; Перем Исходник; Перем ТаблицаТокенов; -Перем Директивы; -Перем ИнструкцииПрепроцессора; -Перем СимволыПрепроцессора; Перем ТаблицаОшибок; Перем ТаблицаЗамен; +Перем Стек; +Перем Счетчики; +Перем Директивы; +Перем Аннотации; +Перем СимволыПрепроцессора; Перем Результат; // Будет вызвана один раз перед обходом дерева. Процедура Открыть(Парсер, Параметры) Экспорт + Типы = Парсер.Типы(); Токены = Парсер.Токены(); Исходник = Парсер.Исходник(); ТаблицаТокенов = Парсер.ТаблицаТокенов(); - Директивы = Парсер.Директивы(); - ИнструкцииПрепроцессора = Парсер.ИнструкцииПрепроцессора(); - СимволыПрепроцессора = Парсер.СимволыПрепроцессора(); ТаблицаОшибок = Парсер.ТаблицаОшибок(); ТаблицаЗамен = Парсер.ТаблицаЗамен(); + Стек = Парсер.Стек(); + Счетчики = Парсер.Счетчики(); + Директивы = Парсер.Директивы(); + Аннотации = Парсер.Аннотации(); + СимволыПрепроцессора = Парсер.СимволыПрепроцессора(); + Результат = Новый Массив; + КонецПроцедуры // Открыть() // Будет вызвана после полного обхода дерева. @@ -108,16 +152,16 @@Шаблон плагина
Функция Подписки() Экспорт Перем Подписки; Подписки = Новый Массив; - //Подписки.Добавить("ПосетитьОператорПрисваивания"); + Подписки.Добавить("ПосетитьОператорПрисваивания"); //Подписки.Добавить("ПокинутьОператорПрисваивания"); Возврат Подписки; КонецФункции // Подписки() #Область РеализацияПодписок -//Процедура ПосетитьОператорПрисваивания(ОператорПрисваивания) Экспорт -// Ошибка("Ошибка в операторе присваивания", ОператорПрисваивания.Начало, ОператорПрисваивания.Конец); -//КонецПроцедуры // ПосетитьОператорПрисваивания() +Процедура ПосетитьОператорПрисваивания(ОператорПрисваивания) Экспорт + Ошибка("Ошибка в операторе присваивания", ОператорПрисваивания.Начало, ОператорПрисваивания.Конец); +КонецПроцедуры // ПосетитьОператорПрисваивания() //Процедура ПокинутьОператорПрисваивания(ОператорПрисваивания) Экспорт // @@ -226,65 +270,65 @@ТаблицаЗамен
Абстрактное синтаксическое дерево
Типы
-
- "Модуль"
-- "ЭлементОкружения"
-- "ОбъявлениеГлобальногоОбъекта"
-- "ОбъявлениеГлобальногоМетода"
-- "ОбъявлениеДирективы"
-- "ОбъявлениеАннотации"
-- "ОбъявлениеПеременнойМодуля"
-- "ОбъявлениеСпискаПеременныхМодуля"
-- "ОбъявлениеСпискаЛокальныхПеременных"
-- "ОбъявлениеЛокальнойПеременной"
-- "ОбъявлениеАвтоПеременной"
-- "ОбъявлениеПараметра"
-- "ОбъявлениеМетода"
-- "ОбъявлениеСигнатурыПроцедуры"
-- "ОбъявлениеСигнатурыФункции"
-- "ВыражениеЛитерал"
-- "ВыражениеПоле"
-- "ВыражениеИндекс"
-- "ВыражениеИдентификатор"
-- "ВыражениеУнарное"
-- "ВыражениеБинарное"
-- "ВыражениеНовый"
-- "ВыражениеТернарное"
-- "ВыражениеСкобочное"
-- "ВыражениеНе"
-- "ВыражениеСтроковое"
-- "ОператорПрисваивания"
-- "ОператорВозврат"
-- "ОператорПрервать"
-- "ОператорПродолжить"
-- "ОператорВызватьИсключение"
-- "ОператорВыполнить"
-- "ОператорПока"
-- "ОператорДля"
-- "ОператорДляКаждого"
-- "ОператорПопытка"
-- "ОператорИсключение"
-- "ОператорПерейти"
-- "ОператорМетка"
-- "ОператорВызоваПроцедуры"
-- "ОператорЕсли"
-- "ОператорИначеЕсли"
-- "ОператорИначе"
-- "ОператорДобавитьОбработчик"
-- "ОператорУдалитьОбработчик"
-- "ИнструкцияПрепроцессораЕсли"
-- "ИнструкцияПрепроцессораИначеЕсли"
-- "ИнструкцияПрепроцессораИначе"
-- "ИнструкцияПрепроцессораКонецЕсли"
-- "ИнструкцияПрепроцессораОбласть"
-- "ИнструкцияПрепроцессораКонецОбласти"
-- "ИнструкцияПрепроцессораВставка"
-- "ИнструкцияПрепроцессораКонецВставки"
-- "ИнструкцияПрепроцессораУдаление"
-- "ИнструкцияПрепроцессораКонецУдаления"
-- "ВыражениеПрепроцессораБинарное"
-- "ВыражениеПрепроцессораНе"
-- "ВыражениеПрепроцессораСимвол"
-- "ВыражениеПрепроцессораСкобочное"
+
- Модуль
+- ЭлементОкружения
+- ОбъявлениеГлобальногоОбъекта
+- ОбъявлениеГлобальногоМетода
+- ОбъявлениеДирективы
+- ОбъявлениеАннотации
+- ОбъявлениеПеременнойМодуля
+- ОбъявлениеСпискаПеременныхМодуля
+- ОбъявлениеСпискаЛокальныхПеременных
+- ОбъявлениеЛокальнойПеременной
+- ОбъявлениеАвтоПеременной
+- ОбъявлениеПараметра
+- ОбъявлениеМетода
+- ОбъявлениеСигнатурыПроцедуры
+- ОбъявлениеСигнатурыФункции
+- ВыражениеЛитерал
+- ВыражениеПоле
+- ВыражениеИндекс
+- ВыражениеИдентификатор
+- ВыражениеУнарное
+- ВыражениеБинарное
+- ВыражениеНовый
+- ВыражениеТернарное
+- ВыражениеСкобочное
+- ВыражениеНе
+- ВыражениеСтроковое
+- ОператорПрисваивания
+- ОператорВозврат
+- ОператорПрервать
+- ОператорПродолжить
+- ОператорВызватьИсключение
+- ОператорВыполнить
+- ОператорПока
+- ОператорДля
+- ОператорДляКаждого
+- ОператорПопытка
+- ОператорИсключение
+- ОператорПерейти
+- ОператорМетка
+- ОператорВызоваПроцедуры
+- ОператорЕсли
+- ОператорИначеЕсли
+- ОператорИначе
+- ОператорДобавитьОбработчик
+- ОператорУдалитьОбработчик
+- ИнструкцияПрепроцессораЕсли
+- ИнструкцияПрепроцессораИначеЕсли
+- ИнструкцияПрепроцессораИначе
+- ИнструкцияПрепроцессораКонецЕсли
+- ИнструкцияПрепроцессораОбласть
+- ИнструкцияПрепроцессораКонецОбласти
+- ИнструкцияПрепроцессораВставка
+- ИнструкцияПрепроцессораКонецВставки
+- ИнструкцияПрепроцессораУдаление
+- ИнструкцияПрепроцессораКонецУдаления
+- ВыражениеПрепроцессораБинарное
+- ВыражениеПрепроцессораНе
+- ВыражениеПрепроцессораСимвол
+- ВыражениеПрепроцессораСкобочное
Модуль¶
@@ -1193,6 +1237,115 @@
+Выра
- Начало: один из ТаблицаТокенов
- Конец: один из ТаблицаТокенов
#Перечисления
Директивы
++
- НаКлиенте
+- НаСервере
+- НаСервереБезКонтекста
+- НаКлиентеНаСервереБезКонтекста
+- НаКлиентеНаСервере
+Аннотации
++
- Перед
+- После
+- Вместо
+- ИзменениеИКонтроль
+СимволыПрепроцессора
++
- Клиент
+- НаКлиенте
+- НаСервере
+- МобильноеПриложениеКлиент
+- МобильноеПриложениеСервер
+- ТолстыйКлиентОбычноеПриложение
+- ТолстыйКлиентУправляемоеПриложение
+- Сервер
+- ВнешнееСоединение
+- ТонкийКлиент
+- ВебКлиент
+Токены
+
- Если
+- Тогда
+- ИначеЕсли
+- Иначе
+- КонецЕсли
+- Для
+- Каждого
+- Из
+- По
+- Пока
+- Цикл
+- КонецЦикла
+- Процедура
+- КонецПроцедуры
+- Функция
+- КонецФункции
+- Перем
+- Знач
+- Возврат
+- Продолжить
+- Прервать
+- И
+- Или
+- Не
+- ДобавитьОбработчик
+- УдалитьОбработчик
+- Попытка
+- Исключение
+- ВызватьИсключение
+- КонецПопытки
+- Новый
+- Выполнить
+- Экспорт
+- Перейти
+- Истина
+- Ложь
+- Неопределено
+- Null
+- Идентификатор
+- Число
+- Строка
+- ДатаВремя
+- НачалоСтроки
+- ПродолжениеСтроки
+- ОкончаниеСтроки
+- ЗнакРавно
+- ЗнакНеРавно
+- ЗнакМеньше
+- ЗнакБольше
+- ЗнакМеньшеИлиРавно
+- ЗнакБольшеИлиРавно
+- ЗнакСложения
+- ЗнакВычитания
+- ЗнакУмножения
+- ЗнакДеления
+- ЗнакОстатка
+- ЛеваяКруглаяСкобка
+- ПраваяКруглаяСкобка
+- ЛеваяКвадратнаяСкобка
+- ПраваяКвадратнаяСкобка
+- ЗнакВопроса
+- Запятая
+- Точка
+- Двоеточие
+- ТочкаСЗапятой
+- _Если
+- _ИначеЕсли
+- _Иначе
+- _КонецЕсли
+- _Область
+- _КонецОбласти
+- _Вставка
+- _КонецВставки
+- _Удаление
+- _КонецУдаления
+- Комментарий
+- Метка
+- Аннотация
+- Директива
+- НачалоТекста
+- КонецТекста
+#Прочее
Доступность
@@ -1208,111 +1361,4 @@
Доступность
- Интеграция: булево