Nemerle и Source Outliner Power Toy
От: hi_octane Беларусь  
Дата: 23.09.07 03:49
Оценка:
Файлы немерла не показывает стандартный ClassView. Посему начал прикручивать к Nemerle один из любимых плагинов Source Outliner. Сразу наступил на мелкую проблемку: при инициализации плагина Document.ProjectItem почему-то null (для C# и VB.NET там лежит ProjectItem). Обошлось через Document.ActiveWindow.ProjectItem который оказывается установлен как надо. Но дальше — хуже — при обращении к projectItem.FileCodeModel.CodeElements всё зависает. Подозорение на компилятор немерла, но проверить возможности пока нет Если кто-нить может сходу врубиться/поправить -- буду очень благодарен и постараюсь довести поддержку немерла этим плагином до рабочего состояния или сделать его частью интеграции.

вот изменения которые я делал:
        private void ContinueLoadingCodeModel()
        {
            ProjectItem projectItem = null; 

            try
            {                
                // Read the code model only if the document and project item opened are not null.
                if (_currentDocument != null)
                {
                    projectItem = _currentDocument.ProjectItem;
                    if(projectItem == null)
                        projectItem = _currentDocument.ActiveWindow.ProjectItem;
                }

                if(projectItem == null)
                {
                    State = OutlineFileManagerState.DoneLoadingCodeModel;
                    return;
                }
            }
            catch (ArgumentException)
            {
                State = OutlineFileManagerState.DoneLoadingCodeModel;
                return;
            }

            EnvDTE.FileCodeModel fileCodeModel = projectItem.FileCodeModel;
            if (fileCodeModel == null)
            {
                State = OutlineFileManagerState.DoneLoadingCodeModel;
                return;
            }

            // Only C# and VB are currently supported.
            if ((fileCodeModel.Language != CodeModelLanguageConstants.vsCMLanguageCSharp)
                && (fileCodeModel.Language != CodeModelLanguageConstants.vsCMLanguageVB)
                && (fileCodeModel.Language != "EDCC3B79-0BAD-11DB-BC1A-00112FDE8B61")) //Nemerle
            {
                TreeView.Hide();
                State = OutlineFileManagerState.DoneLoadingCodeModel;
                return;
            }

            EnvDTE.CodeElements fileCodeElements = fileCodeModel.CodeElements;
            ^^^^^^^^^^^^^^^^^  ЗДЕСЬ ВИСНЕТ ^^^^^^^^^^^^^^^^^^^^^^^^

            int nFileCodeElements = fileCodeElements.Count;

            ...
Re: Nemerle и Source Outliner Power Toy
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.10.07 12:56
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>Файлы немерла не показывает стандартный ClassView. Посему начал прикручивать к Nemerle один из любимых плагинов Source Outliner.


А чем он хорош?

_> ...при обращении к projectItem.FileCodeModel.CodeElements всё зависает...


Как я понимаю через это свойство вынимается CodeModel — некий внутренний формат в МС на недо-АСТ. У нас он не реализован. Так что этот способ работать не будет.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Nemerle и Source Outliner Power Toy
От: hi_octane Беларусь  
Дата: 08.10.07 13:20
Оценка:
_>>Файлы немерла не показывает стандартный ClassView. Посему начал прикручивать к Nemerle один из любимых плагинов Source Outliner.

VD>А чем он хорош?


Ускоряет навигацию по объявлениям в текущем файле. Например, у меня один парсер на немерле расположился в одном большом файле, и разделять смысла нет (фактически весь парсер -- один большой метод на матчах с пачкой локальных функций), и лазить по нему уже довольно неудобно. Ещё одно отличие от окон типа ClassView — в дереве аутлайнера элементы отображаются в порядке следования в исходном файле — беглого взгляда часто достаточно чтобы ориентироваться в файле в целом.

_>> ...при обращении к projectItem.FileCodeModel.CodeElements всё зависает...


VD>Как я понимаю через это свойство вынимается CodeModel — некий внутренний формат в МС на недо-АСТ. У нас он не реализован. Так что этот способ работать не будет.


А какой будет? Подойдёт любой, лишь бы можно было получить доступ ко всем объявленным в текущем файле методам, полям, структурам, вариантам, локальным функциям и т.п, очень желательно с номерами строк в которых они были объявлены.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[3]: Nemerle и Source Outliner Power Toy
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.10.07 16:07
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>Ускоряет навигацию по объявлениям в текущем файле. Например, у меня один парсер на немерле расположился в одном большом файле, и разделять смысла нет (фактически весь парсер -- один большой метод на матчах с пачкой локальных функций), и лазить по нему уже довольно неудобно.


А чем это поможет для матчей? К тому же по матчам должен бегать комбик где список функций вадается (над редактором кода).

_> Ещё одно отличие от окон типа ClassView — в дереве аутлайнера элементы отображаются в порядке следования в исходном файле — беглого взгляда часто достаточно чтобы ориентироваться в файле в целом.


А если надо по алфавиту найти?

_>А какой будет? Подойдёт любой, лишь бы можно было получить доступ ко всем объявленным в текущем файле методам, полям, структурам, вариантам, локальным функциям и т.п, очень желательно с номерами строк в которых они были объявлены.


На вскидку не скажу, но конечно же все что нужно есть. Проще всего поглядеть как реализованы те же комбы в редакторе. По моему, по имени файла можно получить объект Source, а из него все что нужно. В прочем, я уже хорошо все подзабыл. Завтра попробую глянуть. Напомни мне если забуду.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Nemerle и Source Outliner Power Toy
От: hi_octane Беларусь  
Дата: 17.10.07 09:43
Оценка:
_>>Ускоряет навигацию по объявлениям в текущем файле. Например, у меня один парсер на немерле расположился в одном большом файле, и разделять смысла нет (фактически весь парсер -- один большой метод на матчах с пачкой локальных функций), и лазить по нему уже довольно неудобно.

VD>А чем это поможет для матчей? К тому же по матчам должен бегать комбик где список функций вадается (над редактором кода).


Внутри матчей иногда и локальные функции встречаются, часто даже с одинаковыми именами, да ещё и анонимные тоже встречаются, хочется их хоть списком объявлений внутри метода видеть...

_>> Ещё одно отличие от окон типа ClassView — в дереве аутлайнера элементы отображаются в порядке следования в исходном файле — беглого взгляда часто достаточно чтобы ориентироваться в файле в целом.


VD>А если надо по алфавиту найти?


Так сделаю кнопочки сортировки, по уму даже несколько -- по типу объявления, по алфавиту и т.п., можно и над фильтрами подумать (например если сейчас находишься внутри статического метода -- то автоматом применять фильтр для статических членов -- тогда сразу видно будет видно, что может быть вызвано из метода который пишешь). Но для перехода по клику по-любому нужно ещё и номера строк в которых идентификаторы были объявлены.

_>>А какой будет? Подойдёт любой, лишь бы можно было получить доступ ко всем объявленным в текущем файле методам, полям, структурам, вариантам, локальным функциям и т.п, очень желательно с номерами строк в которых они были объявлены.


VD>На вскидку не скажу, но конечно же все что нужно есть. Проще всего поглядеть как реализованы те же комбы в редакторе. По моему, по имени файла можно получить объект Source, а из него все что нужно. В прочем, я уже хорошо все подзабыл. Завтра попробую глянуть. Напомни мне если забуду.


Плиз, любой кусок кода, который мне позволит имея доступ к текущему документу студии (или по имени открытого документа) получить доступ к списку или дереву, или любой другой коллекции объявлений/идентификаторов в этом документе с их номерами строк. А там уже посмотрю -- или интеграцию ещё одним окошком дополню, или проект SourceOutliner докручу до поддержки любимого языка...
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[5]: Nemerle и Source Outliner Power Toy
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.10.07 11:04
Оценка: 2 (1)
Здравствуйте, hi_octane, Вы писали:

Поправил кривые ссылки

_>Внутри матчей иногда и локальные функции встречаются, часто даже с одинаковыми именами, да ещё и анонимные тоже встречаются, хочется их хоть списком объявлений внутри метода видеть...


Ну, попробуй. А вось выйдет что-то удобное.

_>Так сделаю кнопочки сортировки, по уму даже несколько -- по типу объявления, по алфавиту и т.п., можно и над фильтрами подумать (например если сейчас находишься внутри статического метода -- то автоматом применять фильтр для статических членов -- тогда сразу видно будет видно, что может быть вызвано из метода который пишешь).


Хорошо бы сделать фильтр по сроке. Чтобы по умолчанию искал подстроку, а если в строке есть символы '*' или '?', то чтобы использовались символы подстановки (wildcards).

_>Но для перехода по клику по-любому нужно ещё и номера строк в которых идентификаторы были объявлены.


У любого элемента АСТ в Интерграции есть Location. В нем записано имя файла и позиция элемента в этом файле. Погляди как сделана навигация.

_>Плиз, любой кусок кода, который мне позволит имея доступ к текущему документу студии (или по имени открытого документа) получить доступ к списку или дереву, или любой другой коллекции объявлений/идентификаторов в этом документе с их номерами строк. А там уже посмотрю -- или интеграцию ещё одним окошком дополню, или проект SourceOutliner докручу до поддержки любимого языка...


Вот в этом файле:
http://nemerle.org/svn/vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleTypeAndMemberDropdownBars .cs
Находится код заполняющий комбы студийного редактора.
Смотри код фунции OnSynchronizeDropdowns.

Главный код здесь:
IEnumerable decls = AstUtils.GetAllDeclarations(
    _source.ProjectInfo.Engine.ParseTopDeclarations(
    new SourceTextManager(_source)));


Вот это:
_source.ProjectInfo.Engine.ParseTopDeclarations(
    new SourceTextManager(_source))

Специальный метод который если был отпарсен код всего проекта, возвращает закэшированный при парсинге список TopDeclaration-ов (т.е. АСТ типов и т.п.), иначе парсит файл и возвращает тот же список. Понятно, что отпарсить один файл сильно быстрее нежели весь проект. Это позволяет обращаться к этой функции более часто.

Теперь как получить доступ к проекту если ты находишся внутри кода Интеграции:
ProjectInfo info = ProjectInfo.FindProject(filePath);
if (info == null)
{
  // Файл не входит в немерловые проекты открытые в студии на данный момент.
}
else
{
  // Обращаемся к info.Engine или даже к info.Engine.Project...
    // Например, получает список элементов в файле:
  Decl.Namespace topNsDecl = info.Engine.Project.CompileUnits[filePath];
    ... 
    // Дальнейшую обработку лучше производить в Nemerle, 
    // так как Decl.Namespace - это вариант.
}

Описание Decl содиржится здесь.
Вариант Decl нужен, так как в компиляторе нет АСТ для структуры файлов (едениц компиляции). Компилятор оперирует на уровне типов (классов, например). Каждый файл описывается как минимум одним глобальным (безымянным) пространством имен (тип Decl.Namespace) и нулем или более вложенных вхождений варианта Decl.

Тебе нужно разобрать то на что ссылается topNsDecl и визуализировать его.

Понятно, что если в твоем распоряжении есть Engine или, что еще лучше Project, то можно ориентироваться сразу на них.

Надо понимать, что если исходники были изменены, то поптыка получить значение свойства Project приведет к тому, что дерево проекта будет перестроено. Из этого вытекают два следствия:
1. Нельзя кэшировать значение этого свойства.
2. Надо стараться считывать значение этого свойство как можно реже. Иначе могут появиться тормоза.

Еще раз хочу обратить внимание, что для твоих целей достаточно варианта приведенного в самом начале сообщения. Он наиболее быстр.

В общем, разбирайся. Если что-то не ясто, стучи...
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Nemerle и Source Outliner Power Toy
От: hi_octane Беларусь  
Дата: 17.10.07 11:26
Оценка:
VD>...
VD>Еще раз хочу обратить внимание, что для твоих целей достаточно варианта приведенного в самом начале сообщения. Он наиболее быстр.
VD>В общем, разбирайся. Если что-то не ясто, стучи...

Супер, спасибо, надеюсь скоро получится что-то достойное выкладывания в паблик...
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[7]: Nemerle и Source Outliner Power Toy
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.08 02:25
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>Супер, спасибо, надеюсь скоро получится что-то достойное выкладывания в паблик...


Боюсь, что прикрутить Source Outliner Power Toy будет не просто. Он пользуется EnvDTE.FileCodeModel который:
а) не реализован в Интеграции;
б) основан на CodeDom который никакого понятия о таких фичах как match и вложенных функциях не имеет;
в) является не самым быстрым решением, так как требует генерации дублирующих структур CodeDom для АСТ.

Собственно вариантов у тебя два:
1. Реализовать (как следует) EnvDTE.FileCodeModel (см. файл http://nemerle.org/svn/vs-plugin/trunk/Nemerle.VsIntegration/FileCodeModel/NemerleFileCodeModel.cs). Там как говорится, конь не валялся. Но реализация есть в Питоновской Интеграции. Можно скомуниздить по контексту.
2. Забить на эти Source Outliner Power Toy и реализовать аналог на Немерловом API. Незнаю уж насколько это будет сложно, но зато это будет быстрее и функциональность можно реализовать богаче. Как минимум вложенные функции и match реализуется только этим образом.

В прочем, реализовать EnvDTE.FileCodeModel все равно (гипотетически, правда) было бы полезно, так как через эту фичу можно программно получать унифицированный доступ к коду файла. Плюс он позволяет динамически добавлять типы и методы в файл.

С другой стороны для удобной навигации наверно лучше делать специализированные средства.
Так для навигации по отдельным методам и свойствам имеет смысл реализовать отдельную панельку которая бы показывала список вложенных в метод локальных функций и список вхождений match-а на котором в данный момент находится курсор. Это действительно улучшило бы навигацию по коду и упростило бы его осмысление и модификацию. Сделать это довольно просто, но делать это надо именно на базе API Nemerle. EnvDTE.FileCodeModel тут никак не поможет, так как оперирует CodeDom-ом который является "средней температурой по больнице" и которому такие понятия как match и локальные функции незнакомы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Nemerle и Source Outliner Power Toy
От: hi_octane Беларусь  
Дата: 27.02.08 13:38
Оценка:
VD>Боюсь, что прикрутить Source Outliner Power Toy будет не просто. Он пользуется EnvDTE.FileCodeModel который:
Да было непросто, для VS2005 я переколбасил исходный Outliner, написал общие врапперы для C#/VB.NET модели и для Nemerle и ими заменил исходные врапперы для CodeModel, (но Nemerle поддержал слабо — на уровне классов/методов/и не совсем полноценно variant'ов; внутрь методов и матчей пока не залазил, макросы обошёл стороной). Ещё не закрыл вопрос с красивыми иконками — стандартные из аутлайнера, например не имеют иконки для variant'ов по понятным причинам.

Из плюсов — сохранил полную поддержку C#/VB.NET из оригинала, так что в солюшене где смешанные проекты (как у нас), пользоваться было удобно. С фильтрами и сортировками тоже не заморачивался. Думал закоммитить, но начался переезд на VS2008 а с ним почему-то отвалились все пункты меню, в т.ч. AST Tool Window, и Outliner'а. В итоге я побоялся усложнять жизнь своими коммитами тем кто двигает вперёд куда более приоритетные вещи. В добавок переезд на VS2008 наложился на окончаниее проекта у нас (немного про него есть в топике "Опыт применения Nemerle"), так что все изменения я собрал в архив и решил подождать пока утрясётся хотя-бы переезд на VS2008. Эта неделя, вместе с выходными ещё будет сложной, но со следующего четверга я смогу уделять аутлайнеру часа по 4 в день. Посмотрим, сильно ли меняла MS свою FileCodeModel с VS2005 — может и за один день удастся всё смержить.

Докрутить NemerleFileCodeModel тоже придётся рано или поздно — иначе, похоже, окно ClassView так и будет пустовать (не уверен что оно будет работать и после — возможно там проверка на языки для которых оно работает сделана по GUID языка, тогда всё глухо), ещё надо понять чего хочет Code Definition Window — может тоже FileCodeModel. Наверное, этим я и займусь — за то время пока возился с первоначальным аутлайнером — уже порядком разобрался в модели MS. За ссылку на питон спасибо — без этого я бы на их интеграцию не посмотрел.

Для навигации внутри матча или внутри большого метода хочу попробовать сделать что-то вроде контекстной панельки из Office 2007 — может при наведении мыши на match или на одно из вхождений в матч — чтоб появлялась панель со списком вхождений, и для фигурных скобок — панель со списком локальных функций. Может ещё как (надо ещё найти как в студии перехватить наведение на какой-то кусок кода) — надо думать и пробовать. Отдельной панельки немного опасаюсь — экран и так уже забит этими панельками, может оказаться неудобно и неиспользуемо.
Nemerle — power of advanced functional, object-oriented and imperative features in a single statically-typed NET language
Re[9]: Nemerle и Source Outliner Power Toy
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.02.08 14:39
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>Да было непросто, для VS2005 я переколбасил исходный Outliner, написал общие врапперы для C#/VB.NET модели и для Nemerle и ими заменил исходные врапперы для CodeModel, (но Nemerle поддержал слабо — на уровне классов/методов/и не совсем полноценно variant'ов; внутрь методов и матчей пока не залазил, макросы обошёл стороной).


О чем я и говорил. Outliner просто не мог знать о всех расширениях Немерла, так как он использует FileCodeModel, который сильно ограничен.

_>...на VS2008 а с ним почему-то отвалились все пункты меню, в т.ч. AST Tool Window, и Outliner'а.


Хм. Надо разбираться и фиксить. Я даже не заметил. Меню я не пользовался. А AST Tool Window давно не открывал. Он полезен в основном при отладке АСТ...

_>В итоге я побоялся усложнять жизнь своими коммитами тем кто двигает вперёд куда более приоритетные вещи.


Да, ты прав. При переходе с версии на версию лишние комиты дико усложняют жизнь. Сейчас вроде бы перешли. Так что надо решить вопрос с менюшками и можно комитить.

_>...но со следующего четверга я смогу уделять аутлайнеру часа по 4 в день.


Ого! Не мало...

_> Посмотрим, сильно ли меняла MS свою FileCodeModel с VS2005 — может и за один день удастся всё смержить.


Они в 2008-ой вообще мало что меняли. В основном дорабатывали. В прочем, менялся VS SDK. Но тоже не смертельно. Почти уверен, что такие вещи как FileCodeModel не изменились.

_>Докрутить NemerleFileCodeModel тоже придётся рано или поздно — иначе, похоже, окно ClassView так и будет пустовать


Вопрос, только нужно ли оно при наличии того же Outliner-а?...

_>(не уверен что оно будет работать и после — возможно там проверка на языки для которых оно работает сделана по GUID языка, тогда всё глухо),


Питон работает, значит и Немерле сможет. Хардкодинга там нет.

_>ещё надо понять чего хочет Code Definition Window — может тоже FileCodeModel.


Опять же работает в Питоне. Можно попробовать подглядеть как это сделано. Тоже склоняюсь, что через FileCodeModel.

_> Наверное, этим я и займусь — за то время пока возился с первоначальным аутлайнером — уже порядком разобрался в модели MS. За ссылку на питон спасибо — без этого я бы на их интеграцию не посмотрел.


Ага. Иногда очень полезный проект. Жаль, что только иногда. Многое там просто не реализовано или реализовано халтурно (язык то интерпретируемый и не полностью интегрированный в дотнет, плюс халтуры в коде много).

_>Для навигации внутри матча или внутри большого метода хочу попробовать сделать что-то вроде контекстной панельки из Office 2007 — может при наведении мыши на match или на одно из вхождений в матч — чтоб появлялась панель со списком вхождений, и для фигурных скобок — панель со списком локальных функций. Может ещё как (надо ещё найти как в студии перехватить наведение на какой-то кусок кода) — надо думать и пробовать. Отдельной панельки немного опасаюсь — экран и так уже забит этими панельками, может оказаться неудобно и неиспользуемо.


Я бы не стал это делать. По крайней мере пока не заработает сам функционал. Сделать панельку проще (и главное понятно как) и быстрее. Панелька может крепиться (дочиться) как закладка. Например, ее можно засунуть туда где торчит Solution Explorer и переключаться на нее когда это нужно. Ну, а когда функционал будет готов, то можно и поэксперементировать... если конечно не удовлетворит панелька.

Что касается отслеживания курсора, то как это делать можно подглядеть из функционала хинтов. Поставить точку останова внутри хинта и поглядеть "откуда ноги растут".
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Nemerle и Source Outliner Power Toy
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.02.08 14:41
Оценка:
Здравствуйте, VladD2, Вы писали:

_>>ещё надо понять чего хочет Code Definition Window — может тоже FileCodeModel.


VD>Опять же работает в Питоне. Можно попробовать подглядеть как это сделано. Тоже склоняюсь, что через FileCodeModel.


Ой. Вру! Не работает.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.