Перенёс массу инфы в Wiki
http://xn---115-f4d0bap3j.xn-----6kcaje ... 1%84%D0%B0
(Хотя зря оно в Wiki, нужно в Markdown и положить в репозиторий, а вообще нужно расширить язык до того, чтобы хранить доку в нём. Но пока некогда, поэтому пусть будет в Wiki).
Исходя из всего понятого, план теперь примерно такой:
* Переменная в WITH должна быть именованным объектом, причём её имя должно быть Модуль.Процедура.Body.With<Номер>.ИмяПеременной, а место определения, видимо, должно указывать на тип. TFAOParser.VarDecl отвечает за разбор переменной и, наверное, содержит достаточно информации, чтобы синтезировать переменную. Мы синтезируем переменную в SynthesizeVariableForWithStatement по аналогии с TFAOParser.VarDecl
* Соответственно, scope должен знать номер своего WITH и при разборе следующего WITH этот номер должен увеличиваться на 1. Будем хранить в поле counterOfWithStatements. Имя будет создаваться в CreateScopeForWithStatement и пополняться в CreateWith (ownerScope становится известен позже). Когда мы создаём Scope для WITH, мы заполняем его так:
parent - охватывающий scope, cs, ownerBody - тело операторов внутри данного WITH? owner - это будет переменная с именем от переменной и типом из WITH, к-рую мы должны будем синтезировать из того, что нам дали. superQualident не нужен (он не для тех). Вроде всё.
* Возможно, надо поменять TraverseScope, чтобы показывать WITH-ы в дереве кода. Думаю, что надо, т.к. без этого сломается переход к определению - он пытаеся раскрыть дерево в нужном месте, а если узла нет, то и раскрывать негде.
* В SearchUses меняем SearchStatements - там для WITHStatement нужно проходить не в scope, а в нашем scope, взятом из WITHStatement.
* А затем нужно протянуть Scope в любое Expression? Хотя вроде нет. В SearchUses мы управляем текущим scope, а в TraverseScope управляем обходом. Поэтому по идее не должно быть нужно.
разметил все эти места меткой todowith