pascalabcnet/documentation/Intellisense/Функции Intellisense.md
AlexanderZemlyak 69149f8c44
Refactor intellisense (#3213)
* Refactor keywords managing to avoid repeating them twice

* Fix build error

* Fix string comparisons and null reference exception

* Manage references in PascalABCLanguageInfo project

* Fix inaccuracy in BaseKeywords.cs

* Move ValidDirectives field to ILanguageInformation

* Basic refactoring of GetPopupHintText + delete ampersend inserting

* Delete other cases of ampersend inserting

* Add check that we parsing PascalABC.NET in GetPopupHintText

Временное решение, нужно будет вынести вторую попытку в интерфейс парсера.

* Refactor CodeCompletionProvider (first iteration)

* Extract shift space actions in separate class

* Replace dollar service character in CodeCompletion by separate boolean (ctrlSpaceAfterDot))

* Refactor GetCompletionDataByFirst method

* Fix GetCompletionDataByFirst behaviour when getting symInfos after uses keyword

* Another iteration of refactoring in CodeCompletionProvider + comments

* Update intellisense documentation

* Fix build error

* Fix encoding

* Squashed commit of the following:

commit 7751fe7e75
Author: samuraiGH <87191377+samuraiGH@users.noreply.github.com>
Date:   Sun Mar 16 13:28:03 2025 +0300

    generating language res file at build time (#3252)

commit d1fce63d69
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Mar 4 08:38:09 2025 +0300

    Сборка после pr SDK

commit d491e88aa7
Author: samuraiGH <87191377+samuraiGH@users.noreply.github.com>
Date:   Mon Mar 3 20:34:51 2025 +0300

    migration to new build system (#3241)

    * converting project files into sdk style
    * new build commands
    * adding new dll into nsis
    * removing unused .cs files

commit 1fd348ec3c
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sun Feb 23 20:49:26 2025 +0300

    NSIS New 3.10

    Ярлык в меню Пуск у всех пользователей

commit 80b7182dc1
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Wed Feb 19 11:50:00 2025 +0300

    _ in names

commit a2b078960b
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Wed Feb 19 10:52:25 2025 +0300

    cnfc2

commit 58f26d469d
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Feb 18 22:28:13 2025 +0300

    перекомпиляция 3.10.3.3611

commit b78a72977f
Author: nevermind322 <81963698+nevermind322@users.noreply.github.com>
Date:   Tue Feb 18 22:02:19 2025 +0300

    fix build on mono (#3249)

    * fix build on mono

    * remove local func

    * fix again

commit c3557e388c
Author: Nikolay Kuznetsov <adasoft@gmail.com>
Date:   Sat Feb 15 20:32:46 2025 +0300

    Update GraphABC.pas (#3244)

    1. Быстрая реализация функции FloodFill
    Для этого добавлена процедура BitmapFloodFill, которая вызывается из метода Picture.FloodFill и процедуры FloodFill

    2.Добавлена поддержка LockDrawing/UnlockDrawing в процедуру FloodFill

commit 9dbac389e1
Author: AlexanderZemlyak <92867056+AlexanderZemlyak@users.noreply.github.com>
Date:   Wed Feb 12 13:57:14 2025 +0300

    Add missing projects to pabcnetc.sln (#3247)

commit 41dfb6f187
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Fri Feb 7 21:41:01 2025 +0300

    [] - преобразование во все контейнеры

    GraphABCHelper - теперь ABCObjects работает под Линукс

    School исправлен согласно последним веяниям []

commit 79bbbd10ff
Author: samuraiGH <87191377+samuraiGH@users.noreply.github.com>
Date:   Wed Jan 29 20:18:37 2025 +0300

    removing files for support fx4.0 (#3240)

commit 88d5c409eb
Author: samuraiGH <87191377+samuraiGH@users.noreply.github.com>
Date:   Tue Jan 28 20:41:55 2025 +0300

    Рефакторинг PascalABCNET.xshd (#3237)

    * refactoring PascalABCNET.xshd

    * removing extra characters

commit 8fbd7fdfc3
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sun Jan 26 23:42:48 2025 +0300

    3.10.3
    faststrings
    EmptyCollection и преобразование ее в List, Dictionary
    t: (real,real) := (1,2)

commit bba132bd5d
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Wed Jan 22 09:14:44 2025 +0300

    Поправил справку по функции

commit 1bd21857cc
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Wed Jan 8 18:46:51 2025 +0300

    Teacher Control Plugin - возможность задать server.dat

commit 0848a1b796
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sat Jan 4 22:54:38 2025 +0300

    Исправление автоформатирования []

commit d45b782a7b
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sat Jan 4 18:45:07 2025 +0300

    Rename PABCSistem in test suite

commit c2347e604b
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sat Jan 4 14:44:51 2025 +0300

    Примеры - устранил неточности

    LightPT - имя сервера вынес в публичную секцию

commit b68b8da970
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Dec 17 15:52:18 2024 +0300

    Примеры Coords1.pas Coords2.pas.pas

commit 8a9788e6f9
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Dec 17 15:06:57 2024 +0300

    Перенес проверку set array на уровень парсера

    Немного поправил Intellisense по наведению для NewSet

    По точке там что то другое работает

commit 874ddebad3
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sat Dec 14 21:00:38 2024 +0300

    Поправил грамматику []

    Теперь нельзя в режиме ## использовать атрибуты

    Зато можно [1,2,3].Print

commit 080fb487e1
Merge: a53dcd9ed a484b0e82
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sat Dec 14 15:25:24 2024 +0300

    Merge branch 'master' of https://github.com/pascalabcnet/pascalabcnet

commit a53dcd9ed2
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sat Dec 14 15:25:16 2024 +0300

    SF Prm Cmb для строк

commit a484b0e82d
Author: Sun Serega <sunserega2@gmail.com>
Date:   Thu Dec 12 13:49:17 2024 +0200

    fix (#3231)

commit 6ef11f249c
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Dec 10 11:05:45 2024 +0300

    3.10.2

commit db9679d89f
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Dec 10 10:59:20 2024 +0300

    Закончил превращение синтаксиса [] по умолчанию в массивы

commit 45fdde24b4
Author: Ivan Bondarev <ibond84@googlemail.com>
Date:   Sun Dec 8 18:08:00 2024 +0100

    #3229

commit 494b47624d
Merge: 5875b9929 7906d73da
Author: Ivan Bondarev <ibond84@googlemail.com>
Date:   Sun Dec 8 10:42:07 2024 +0100

    Merge branch 'master' of https://github.com/pascalabcnet/pascalabcnet

commit 5875b99296
Author: Ivan Bondarev <ibond84@googlemail.com>
Date:   Sun Dec 8 10:41:53 2024 +0100

    platformtarget native - .NET 9.0

commit 7906d73da3
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Dec 3 14:25:37 2024 +0300

    Небольшие изменения в реализации операций с множествами

commit 087591c7b6
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Wed Nov 27 11:37:07 2024 +0300

    3.10.1

    Coords - доработки

    Distance, Middle, DrawText с фоном и рамкой. Глобальные переменные настройки

commit d268d4f83b
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Thu Nov 21 22:24:07 2024 +0300

    NSToBytes переделал с исключением

commit 2bacdc8c28
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Wed Nov 20 13:20:33 2024 +0300

    Комментарии к NewSet

commit e917ac8eca
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Wed Nov 20 12:42:15 2024 +0300

    TypeName для set

commit 206289c6a7
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Nov 19 20:23:03 2024 +0300

    Везде заменил _hs на hs в NewSet

    Убрал вызовы методов расширений NewSet в PABCSystem.pas

    Убрал var в operator +

commit d8262078f6
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Tue Nov 19 13:56:47 2024 +0300

    Исправление мелких ошибок NewSet

    Все тесты проходят.

    Проблема, которая остаётся - в режиме ускорения такие программы падают:

    begin
      var s: set of byte;
      Print(s = [1]);
    end.

    Причина - из dll не вызывается конструктор записи без параметров, хотя он определён. В C# вообще у записей не может быть конструктора по умолчанию - наверное потому. Но для NewSet надо бы сделать исключение

commit f8819665ba
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sat Nov 16 10:56:11 2024 +0300

    NS2

commit 591d9ebe60
Author: Ivan Bondarev <ibond84@googlemail.com>
Date:   Wed Nov 13 21:34:10 2024 +0100

    fix

commit c6505634f4
Author: Ivan Bondarev <ibond84@googlemail.com>
Date:   Wed Nov 13 21:12:33 2024 +0100

    fix

commit a6564df23c
Author: Ivan Bondarev <ibond84@googlemail.com>
Date:   Wed Nov 13 20:52:29 2024 +0100

    fix in new sets

commit 03be5bd931
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Wed Nov 13 22:13:41 2024 +0300

    Переставил operator:= в NewSet

commit 96c68f1666
Author: Ivan Bondarev <ibond84@googlemail.com>
Date:   Tue Nov 12 21:38:07 2024 +0100

    #3223

commit 82776f3c77
Author: Mikhalkovich Stanislav <miks@math.sfedu.ru>
Date:   Sat Nov 9 12:18:19 2024 +0300

    NewSet - много мелких исправлений.

    Все тесты проходят кроме Tests 5 - видимо с pabcrtl.dll

* Update comments in PascalABCLanguageInformation
2025-04-10 13:13:17 +03:00

11 KiB
Raw Blame History

Подсказка при наведении мыши

На верхнем уровне реализуется в классе TooltipServiceManager. Основная логика реализована в методе GetPopupHintText. Вначале вызывается FindExpressionFromAnyPosition для получения нужного expression в виде строки. Затем вызывается нужный парсер для получения дерева выражения (используется часть грамматики, связанная с нетерминалом parts). Если не получается распарсить, то делается попытка с удалением символа разыменования в выражении, пока неясно в какой ситуации это требуется. Еще удаление разыменования присутствует в методе GetDefinitionPosition из CodeCompletionActions. Затем делается еще попытка с тем же выражением без скобочек. При этом, если без скобочек распарсить не удается, то вне зависимости от успешности парсинга полного expression возвращается null. В конце проверяется был ли успешен обход дерева программы визитором (DomSyntaxTreeVisitor). Если это так, то в словаре откомпилированных модулей будет данный модуль и соответствующий ему DomConverter. Тогда есть возможность вызвать метод GetDescription из этого класса, который выдаст нам описание выражения.

Подсказка параметров функции

На нажатие клавиш (скобки, квадратной скобки или запятой) реагирует TextAreaKeyEventHandler из класса CodeCompletionKeyHandler. Там создается экземпляр DefaultInsightDataProvider, который загружается в стек провайдеров. Информация для подсказки формируется в методе SetupDataProvider инсайт-провайдера. После выяснения кода на текущей подстроке вызывается FindExpressionForMethod из LanguageInformation. Далее делается попытка парсинга стандартным парсером языка и наконец из DomConverter вызывается GetNameOfMethod, либо GetIndex в зависимости от нажатой клавиши.

Подсказка по нажатию клавиш

CodeCompletionKeyHandler реагирует на нажатие вызовом метода ShowCompletionWindow. В нем есть обращение к GenerateCompletionDataWithKeyword из класса CodeCompletionProvider. В этом методе выделяется нужная подстрока и есть обращение к методу GetCompletionData. Логика этого метода следующая: Вначале выясняется контекст вызова Intellisense, а именно нажатые пользователем клавиши и т. п. Далее вызывается специальный метод для получения текста выражения, введенного пользователем. При этом

  1. если был нажат ctrl + space или shift + space Вызывается FindPattern из LanguageInformation для получения "токена" до курсора. Если в процессе встретится точка, то вызывается FindExpression.
  2. если был нажат пробел после new Вызывается SkipNew для пропуска new и поиска expression перед ним.
  3. иначе, если пользователем была введена точка вызывается FindExpression (c текущей позиции)

Ниже если был нажат ctrl + space не после точки и pattern пустой то в итоговый список ICompletionData добавляются ключевые слова языка.

Далее, если выражение не пусто, то строится дерево требуемого expression (это не требуется для ctrl + space и shift + space, кроме случая, когда они нажаты в цепочечном выражении с точками). Внутри метода построения дерева делается попытка вызова функции GetTypeAsExpression, а затем GetExpression. Если ничего не удалось построить и мы не в случае пробела после new, то нужно выходить из внешнего метода GetCompletionData.

Далее получаем необходимую информацию о выражениях для нужного expression из таблицы символов (в специальном методе). Если визитор Intellisense успешно не обошел текущий модуль (тогда мы не получим соотв. экземпляр DomConverter), то - Если у нас не случай ctrl + space или shift + space , нужно вернуть пустой массив ICompletionData. - Для случая uses сразу добавляем массив стандартных модулей языка

Иначе, если у нас есть DomConverter: - Если пробел после new, то вызываем GetTypes - Иначе, если uses, то работаем со списком стандартных модулей + пр-в имен в случае семантического Intellisense. - Иначе, если была нажата точка, либо ctrl + space или shift + space сразу после точки, то вызываем GetName для получения всех возможных имен после точки - Иначе, если ctrl + space, то либо ищем имена, подходящие для помещения после точки, начинающиеся на pattern - GetName + StartsWith, либо просто ищем имя по его началу - GetNameByPattern

В конце по полученным SymInfo строится результирующий список CompletionData (без повторений).

[!NOTE] Замечание Случаи обработки ctrl + space и shift + space перед вызовом GetCompletionData обрабатываются не в классе CodeCompletionKeyHandler, а в отдельных классах файла CodeCompletionActions. У ctrl + space класс называется CodeCompletionAllNamesAction, а у shift + space - CodeCompletionShiftSpaceActions. При этом для shift + space в вышеупомянутом классе предварительно проверяются еще два сценария его применения помимо подсказки локальных имен, реализованной в GetCompletionData. Эти сценарии - это автодополнение xml-комментария и автодополнение выражений из файла template.pct языка.

Подсказка по первому символу выражения

Данная ситуация обрабатывается в последней ветке метода TextAreaKeyEventHandler класса CodeCompletionKeyHandler. Оттуда цепочка вызовов приходит к методу GetCompletionDataByFirst. В этом методе мы так же как в GetCompletionData вначале выясняем контекст, а именно должен ли в данной позиции быть введен тип данных, либо мы находимся в секции "uses". Если мы не в "uses", то можно добавить в результирующий список подсказок нужные ключевые слова.

Далее получаем нужную информацию из таблицы символов в специальном методе по следующим правилам: Если DomConverter данного модуля получить невозможно, то в случае "uses" можно добавить список стандартных модулей. Если же DomConverter получен, то - если нужно подсказать типы данных вызывается GetTypeByPattern - если секция "uses", то либо вызывается GetNamespaces когда включен семантический Intellisense, либо просто добавляется список стандартных модулей - во всех остальных ситуациях вызывается GetNameByPattern, причем ему передается пустой pattern

После этого в специальном методе по полученным SymInfo строим результирующий список подсказок без повторений. При этом назначается значение defaultCompletionElement (подсказки, которая выбирается по умолчанию). Это будет либо прошлый выбранный вариант подсказки, либо если такого не найдется, то минимальный элемент по длине.

Переход к определению символа

В CodeCompletionActions есть специальный класс GotoAction, в котором вызывается метод GoToDefinition. В этом методе используется метод GetDefinitionPosition, который в свою очередь (тоже косвенно) использует FindExpressionFromAnyPosition из LanguageInformation и GetDefinition из CodeCompletionProvider. Последний вышеупомянутый метод является оберткой над GetDefinition из DomConverter.