Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

158 lines (118 sloc) 12.067 kb
1. Done! При обновлении CompileUnit, после того как стало известно, что не требуется перестраивать дерево типов
нужно закинуть в тело измененного метода PExpr-эшон полученый в результате парсинга файла.
2. Done! На всякий пожарный (чёрт, не люблю я это слово!) предотвратить добавление сообщений получаемых при
парсинге текста тела методов в PExpr осуществляемое в методах MethodBuilderEx.
3. Done! Сообщения об ошибках типизации выводятся не верно (при изменении тела метода). Надо разобраться в чем дело,
и устранить проблему.
4. Надо исправить появление дублирующихся сообщений при открытии проекта.
5. По новой логике релокешон помещается в задание UpdateCompileUnit. Так как этот тип задания может быть отменен
вновь появляющися заданием, то релокешон рано или поздно будет работать не корректно. Надо это пофиксить.
Возможные пути решения проблемы:
1. Не отменять запросы UpdateCompileUnit.
2. Как-то накапливать все не примененные релокешоны и объеденять их перед применением.
Второй путь видится более производительным, так как с одной стороны разные релокешоны (не применные до
некоторого момента) обеденяются, что сокращает время на релокешон, а сдругой лишние запросы на парсинг могут
быть отменены (на них так же не прийдется тратить время).
6. Рассмотреть возможность отмечать начало и окончание выдачи связанных сообщений об ошибках. Для этого можно завести в ManagerClass два метода виртуальных:
1) BeginRelatedMessages() и EndRelatedMessages(). Engine будет их перехватывать и связывать сообщения путем добавления всех последующих сообщений
в список связанных сообщений (RelatedMessage) первого сообщения.
ЭТО НУЖНО СДЕЛАТЬ ОБЯЗАТЕЛЬНО!!!
Возможно имеет смысл не выводить сообщения об ошибке для неудачных перегрузок, если тип объекта для которых они вычисляются неизвестен!
Это предотвратило бы выдачу наведенных сообщений об ошибках.
ВОПРОС! Имеет ли смысл выводить сообщения об ошибке типизации доступа к члену если тип объекта None?
Похоже, что - нет, так как это явно наведенная ошибка. Может ли она возникать в условиях когда нет других ошибок?
План
1. Поправить вывод хинтов для сообщений об ошибсках. Сейчас выводится первое попавшееся сообщение, а надо выводить список всех сообщений плю описание типа для элемента который находится под курсором. Возможно следует поправить сообщения компилятора так, чтобы множественные сообщения выводились одной строкой, а не несколькими. Так же возможно имеет смысл реализовать продинутый интерфейс для ошибок вроде резрешения перегрузок.
2. Дореализовать хинты к методам (выпадающие по Ctrl+Shift+Space).
3. Вынести парсинг структуры файла из обработчика синхронизации комбов в поток парсинга. Саму же синхронизацию комбов нужно сделать на основе результата этой операции.
3.1. + В каждом NemerleSource заводим поле TopDeclaration[] Declarations.
В него будут добавляться рспарсиваемые TopDeclaration-ы.
3.2. + Создаем бэкграунд-парсинг ParstTopDeclaration.Он парсит исходник и заполняет Declarations.
3.3. + При редактировании немедленно запускаем ParstTopDeclaration в потоке бэкграунд-парсера.
3.4. В UpdateDropDownTypes() используем Declarations для заполнения комбов и обновления их текущих индексов.
3.5. Вызываем UpdateDropDownTypes() в HandleParseResponse вызванный для ParstTopDeclaration.
4. Попытаться сделать комплит в строках используемых как тела встроенных DSL-ей. Для этого нужно при начале комплита попытаться сформировать поддельный токен (на основании PExpr/TExpr который найдется под курсором (если найдется)). Кроме того надо поправить парсинг $-строк так, чтобы там использовался бы комплитный лексер, так чтобы комплит работал бы и в строках.
5. Реализовать релокешон при изменении неважных частей файлов, так чтобы при форматировании кода не производилась перестройка дерева типов и проверка методов. В принципе не приорететная задача, так как при работе в многопоточном режиме проблем с производительностью особо нет.
6. Нужно удалять сообщения об ошибках размещенные компилятором при появлении сообщений от построения дерева типов и проверок методов. Кроме того нужно удалять сообщения добавленые интеллисенсом когда появляются сообщения об ошибках от компил-*-ятора.
6.1. Можо удалять все ссобщения созданные компилятором в момент когда начинают отображаться
сообщения появившиеся в ходе построения дерева типов (при изменении основной структуры проекта).
6.2. Можно удалять только те сообщения компилятора которые совпадают по тексту и локешону с сообщениями
добавляемыми при прострении дерева типов и проерке методов.
7. Переписать ProcessRegions() так, чтобы он работал даже при отсутствии проекта. Ну, и имеет смысл перенести его в ParseTopDeclaration(),
так как для ProcessRegions() нужно именно наличие TopDeclaration-ов.
Код парсинга и построения Decl нужно вынести в единый метод и использовать как при построении дерева типов, так и при парсинге
ParstTopDeclaration-ов. По уму можно даже сделать так, чтобы результат работы парсера ParstTopDeclaration использовался бы при построении
дерева типов. Тогда можно будет еще более ускорить построение дерева типов, так как фактически парситься будет только измененный файл.
8. Done! Востановить разбор регионов внутри методов.
9. !!!! Надо полность переписать код бэкграунд-парсинга.
Задачи:
Бэкграунд-парсинг должен позволять выполнить асинхронный запрос на работу с движком компилятора.
Вся работа с движком компилятора должна вестись в отдельном потоке. Это должен быть всегда один. Параллельная работа с движком компилятора недопустима!
Все должно выглядеть как асинхронный вызов метода. Методу передаются параметры и колбэк-метод который должен вызваться после того как запрос будет
выполенен в другом потоке.
Для этого заводим отдельный поток который можно срубать, если что.
В ЛэгвиджСервисе заводим очередь запросов. При появлении нового запроса ставим его в очередь. В будущем нужно реалзовать просмотр этой очереди
и удаление запросов которые не имеют смысл в связи с появлением нового запроса. Например, если запущен запрос перестроения дерева, то все
предыдущие запросы теряют смысл, или, если запущен запрос парсинга компалерЮнита, то предыдущие такие же запросы не имеют смысла и их нужно удалить
из очереди.
Кроме того нужно завести очередь ответов. В нее должны помещаться результаты вычисления полученные в бэкграунд-потоке (при выполнении запросов).
Гуи-поток должен разбирать эту очередь и вызвать колбэки или просто обновлять необходимую информацию в GUI IDE.
10. При подстветке парных скобок, если выбрана закрывающая скобка, выводить информацию о том, что за текст идет перед открывающей скобокй.
11. Все объекты которые меняют состояние должны хранить исходное состояние (полученое при парсинге исходников). Все изменнениях производимые
компилятором и макросами должны помещаться в другие переменные! В первую очередь нужно переделать тело метода.
Общая стратегия редактирования.
Типы запросов на теневую работу:
1. Построение дерева типов.
2. Парсинг CompilerUnit-а.
3. Проверка тел методов. -- За раз может быть проверено от одного до Х (по умолчанию 100) методв.
Критерий остановки - истечение кванта (по умолчанию .3 сек.).
Методы выбираются из очереди.
4. Получение хинта к методу. -- *
5. Получение хинта к токену находящемуся под мышыным курсором. -- *
6. Подстветка связаных идентификаторов. -- *
7. Автодополнение (auto completion) при вводе. -- * (хотя можно организовать урезанный комплешон).
* Работате только при наличии проекта.
Типы ответов теневого потока GUI-потоку:
1. Построено дерево типов. -- Нужно отобразить сообщения об ошибках парсига АСТ верхнего уровня и инициализировать очердь типизации тел методов.
2. Построен CompilerUnit. -- Нужно: 1. Синхронизировать комбы. 2. Сравнить CompilerUnit с тем что был получен при построении дерева типов и если
они различаются запустить процедуру построения дерева типов (запрос 1).
3. Сформирован список регионов. -- Нужно объеденить регионы из файла и региотры из полученного списка. Это нужно чтобы сохранить состояние регинов.
Например, если пользователь закрыл регион, то нужно постараться оставить его закрытым. Похоже студия сохраняет
список регинов для файлов входящих в проект.
4. Найден ответный токен. -- Подсветить парные токены. Возможно (если скобки находятся на разных строках) вывести в
статусбар дополнительную информацию.
5. Метод проверен -- Заполнить Error List сообщениями об ошибках.
GUI-поток:
1. При каждом редактировании запускаем теневой парсинг CompilerUnit-а для текущего NemerleSource.
2. Если файл подключен к проекту вызываем функцию projectInfo.AddRelocation() которая пытается перестроить локешоны, так чтобы они сохраняли
свою аткулаьность. Если редактирование производилось внутри некоторого метода, то AddRelocation() вернет сброшенный метод (resetedMember),
т.е. метод тело котого изменилось. Если resetedMember не пуст, то запускаем процедуру теневой проверки метода (типизации для получения списка
сообщений об ошибках).
3. Получив оповещение об окончании построения CompilerUnit-а вызваем синхронизацию комбов. Если файл подключен к проекту сравниваем АСТ из
нового CompilerUnit-а с АСТ из CompilerUnit-а полученного при построении дерева типов. Сравнение производится до уровня тел членов.
Если есть различия, запускаем процедуру теневого построения дерева типов (тем самым сбрасываем текущее дерево типов).
4. Получив оповещение об окончании построения регионов, извлекаем из него список регионов и объеденяем их с регионами присутствующими в редакторе.
Поток парсинга:
1. Парсинг CompilerUnit-а.
После окончания парсинга помещаем CompilerUnit в класс NemerleSource и оповещаем GUI-поток.
Далее производим вычисление регионов на базе просмотра АСТ из полученного CompilerUnit. По окончании оповещаем GUI-поток. Данное опопвещение
должно содержать сформированный список регионов.
2. Парсинг дерева типов.
3. Проверка тел методов (их типизация).
4. Проверка тела (типизация) сброшенного метода.
Чушь: Возможно из я что-то заблы из того что здесь написано...
1. При каждом редактировании запускаем теневой парсинг текущего файла (CompilerUnit-а) и получаем AST CompilerUnit-а.
После окончания парсинга CompilerUnit-а теневой поток помещает CompilerUnit в класс NemerleSource.
2. Если файл подключен к проекту и редатирование осуществлено внутри метода, то вызываем процедуру релокешона. Она исправит локешоны АСТ
CompilerUnit-а полученного при предыдущей типизации. Так же релокешон исправит локешоны TypeBuilder-ов, MemberBuilder-ов и АСТ членов
(как типизированное, так и нетипизированное).
3. Если файл подключен к проекту сравниваем полученное в результате парсинга CompilerUnit-а АСТ с АСТ полученным при построении дерева типов.
CompilerUnit полученный при построении дерева типов должно храниться в коллекции CompilerUnit.
CompilerUnit полученный при теневом парсинге должен быть помещен в классе NemerleSource.
Сравнение производится до уровня тел членов.
Если аст CompilerUnit различается, то запускаем теневое перестроение дерева типов.
При построении дерева типов нужно брать CompilerUnit-ты из NemerleSource. Это позволит сократить время на парсинг всего проекта.
4. Лексер будет извлекать GlobalEnv из CompilerUnit-а в данный момент находящегося в NemerleSource.
5. При появлении информации о регионах нужно смержить регионы с регионами которые в данный момент находятся в редакторе.
CompilerUnit содержащий TopDeclaration-ы (АСТ типов), регионы
и пространство имен верхнего уровня (Decl.Namespace, в котором описана иерархия пространств имен, юснигов и типов)).
Jump to Line
Something went wrong with that request. Please try again.