Готов переход к исходнику при наличии pdb.
От: Блудов Павел Россия  
Дата: 10.10.06 05:56
Оценка: 106 (2)
Здравствуйте, IT!

Получите и распишитесь (LanguageService\NemerleAuthoringScope.cs):

        public override string Goto(
            VSConstants.VSStd97CmdID cmd, 
            IVsTextView              textView,
            int                      line,
            int                      col,
            out TextSpan             span)
        {
            span = new TextSpan();

            GotoInfo info = _project.GetGoto(_filePath, line, col, _sourceText);

            if (info == null)
                return null;

            if (info.HasLocation)
            {
                span.iStartLine  = info.LineStart;
                span.iEndLine    = info.LineEnd;
                span.iStartIndex = info.ColStart;
                span.iEndIndex   = info.ColEnd;

                return info.FilePath;
            }

            if (null != info.Member && !string.IsNullOrEmpty(info.FilePath))
            {
                Guid   mdiGuid = new Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44");
                IntPtr mdiPtr  = IntPtr.Zero;
                object mdiUnk;

                if (VSConstants.S_OK == _project.SmartOpenScope.OpenScope(info.FilePath, 0, ref mdiGuid, out mdiUnk))
                {
                    try
                    {
                        mdiPtr                = Marshal.GetIUnknownForObject(mdiUnk);

                        SymbolToken    token  = new SymbolToken(info.Member.GetHandle().MetadataToken);
                        ISymbolBinder1 binder = new SymBinder();
                        ISymbolReader  reader = binder.GetReader(mdiPtr, info.FilePath, null);
                        ISymbolMethod  method = reader.GetMethod(token);

                        if (method.SequencePointCount > 0)
                        {
                            ISymbolDocument[] documents  = new ISymbolDocument[1];
                            int[]             lines      = new int[1];
                            int[]             columns    = new int[1];
                            int[]             endLines   = new int[1];
                            int[]             endColumns = new int[1];

                            method.GetSequencePoints(null, documents, lines, columns, endLines, endColumns);

                            span.iStartLine  = lines[0]      - 1;
                            span.iEndLine    = endLines[0]   - 1;
                            span.iStartIndex = columns[0]    - 1;
                            span.iEndIndex   = endColumns[0] - 1;

                            return documents[0].URL;
                        }
                    }
                    catch (COMException)
                    {
                        // The file was not found or line numbers were stripped from pdb.
                    }
                    finally
                    {
                        if (IntPtr.Zero != mdiPtr)
                            Marshal.Release(mdiPtr);
                    }
                }
            }

            return null;
        }


Полужирным выделено то, чего мне не хватало и я тупо добавил:

GotoInfo.cs:
namespace Nemerle.Completion2
{
  public class GotoInfo
  {
    [Accessor] mutable _filePath  : string;
    [Accessor] mutable _lineStart : int;
    [Accessor] mutable _lineEnd   : int;
    [Accessor] mutable _colStart  : int;
    [Accessor] mutable _colEnd    : int;
    [Accessor] mutable _member    : IMember;

    public this(member : IMember)
    {
      _member = member;
      SetLocation(member.Location);
    }
  }
}


ProjectInfo.cs:
        public  IVsSmartOpenScope SmartOpenScope
        {
             get { return (IVsSmartOpenScope) _site.GetService(typeof (SVsSmartOpenScope)); }
        }


Кроме того, нужно добавить reference на ISymWrapper.DLL из каталога FrameWork'а.

Known issues

Вот тут работает:
m() : Nemerle.TailRecursionTransparentAttribute
{
    def i = Nemerle.TailRecursionTransparentAttribute(true);
    i;
}

А тут нет:
Main() : void
{
    printf("Hi!");
}

потому что Nemerle.IO.printf почему-то распознаётся как System.Console.Write() Причём в QuickTip тоже имеем System.Console.Write. Кто виноват и что делать
... << RSDN@Home 1.2.0 alpha rev. 642>>
Как всё запущено в pdb...
От: Блудов Павел Россия  
Дата: 19.09.06 09:41
Оценка: 75 (2)
Здравствуйте, IT!

Вобщем так. Метода ВотВамТокенДайтеИмяФайлаИСтрокуСтолбец() попросту нет. Дело в том, что метод в dll может быть получен из нескольких исходных файлов.
Во-первых, inlining, во-вторых макросы c++ препроцессора, которых ешё никто не отменял.

Вместо этого есть метод ДайтеВсеКускиМетода(), который возвращает для каждого куска собственно документ, смещение в нем, начальные и конечные строки и столбцы.

Вот сампл по работе с ISymUnmanagedXXXX
    public class TestClass
    {
        public void TestMethod()
        {
        }
    }

    public class PdbTest
    {
        [STAThread]
        public static void Main(string[] args)
        {
            Guid IMetaDataImportGuid = typeof(IMetaDataImport).GUID;

            // Для интергации нужно использовать IVsSmartOpenScope::OpenScope
            // из VisualStudioIntegration\Common\IDL\compsvcspkg80.idl
            //
            IMetaDataDispenser metaDispenser = (IMetaDataDispenser)new CorMetaDataDispenser();
            IMetaDataImport metaDataImport = (IMetaDataImport)metaDispenser.OpenScope(ExecutableLocation, 0, ref IMetaDataImportGuid);

            // Получаем токен нужного метода
            //
            uint classToken = metaDataImport.FindTypeDefByName("dotNetJim.TestClass", 0);
            uint methodToken = metaDataImport.FindMethod(classToken, "TestMethod", null, 0);

            // Вот собственно работа с .pdb
            //
            ISymUnmanagedBinder binder = (ISymUnmanagedBinder)new CorSymBinder();
            ISymUnmanagedReader  reader = binder.GetReaderForFile2(metaDataImport, ExecutableLocation, null, 0x0F);
            ISymUnmanagedMethod  method = reader.GetMethod(methodToken);

            uint seqPoints = method.GetSequencePointCount();
            uint seqPointsReal;

            IntPtr[] documents  = new IntPtr[seqPoints];
            uint[]   lines      = new uint[seqPoints];
            uint[]   columns    = new uint[seqPoints];
            uint[]   endLines   = new uint[seqPoints];
            uint[]   endColumns = new uint[seqPoints];
            uint[]   offsets    = new uint[seqPoints];
            method.GetSequencePoints(seqPoints, out seqPointsReal, offsets, documents, lines, columns, endLines, endColumns);

            for (int i = 0; i < seqPointsReal; i++)
            {
                uint len;
                StringBuilder url = new StringBuilder(2048);
                ISymUnmanagedDocument doc = (ISymUnmanagedDocument)Marshal.GetObjectForIUnknown(documents[i]);
                doc.GetURL(url.Capacity, out len, url);
                Console.WriteLine("file {0}, line {1} col {2}", url, lines[i], columns[i]);
                Marshal.Release(documents[i]);
            }
        }

        public static string ExecutableLocation
        {
            get { return Assembly.GetEntryAssembly().Location; }
        }
    }


Как показало следствие, GetSequencePointCount возвращает для метода как минимум 2 точки: открывающая скобочка и закрывающая.
В принципе, можно всегда спрашивать первую SequencePoint и делать Goto на неё.

Unmanaged интерфейсы в след. сообщении.
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re[3]: Готов переход к исходнику при наличии pdb.
От: IT Россия linq2db.com
Дата: 11.10.06 01:08
Оценка: 12 (1)
Здравствуйте, Блудов Павел, Вы писали:

БП>Понял. Буду копать. QuickTip тоже нужно доработать?


Хорошо бы. С макросами там всё не так шоколадно. Их надо из Parsedtree выщимлять, но потом парсить, что бы показывать как они разворачиваются.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[10]: Есть простая задачка для желающих
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.09.06 13:28
Оценка: :)
Здравствуйте, vdimas, Вы писали:

V>Есть же консольный test-runner, стартует действительно, на пол-секунды быстрее, а во вторых есть удобный аттрибут Explicit, у нас тесты и фикстуры помечены им, кроме тех, которые должны отрабатывать всегда без принудительного запуска. Для твоего сценария надо просто убирать этот аттрибут из теста, который ты намереваешься многократно гонять в дебаге. Как раз получишь минимум движений. Для GUI test-runnera все в силе, когда запускается с опцией автоматического прогона тестов (т.е. телодвижений ничуть не больше), но раздельный вывод информации мне тоже нравится больше.


Ладно. В следующий раз разбирусь. Пока просто в лом дергаться. Все работает...
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Поравочка
От: Блудов Павел Россия  
Дата: 18.10.06 09:01
Оценка: :)
Здравствуйте, VladD2, Вы писали:

VD>А что вот это:

VD>
N>>[code]
N>>set NemerleBin=%~dp0\bin\%Type%
N>>[/code]
VD>


Да ты что! Это же свяшенная корова! См. http://rsdn.ru/article/winshell/batanyca.xml#E6G
Автор(ы): Алексей Александров
Дата: 11.07.2005
Статья рассказывает о малоизвестных возможностях командного языка Windows.
... << RSDN@Home 1.2.0 alpha rev. 642>>
Есть простая задачка для желающих
От: IT Россия linq2db.com
Дата: 06.09.06 04:05
Оценка:
Нужно доделать функцию Go To Definition.

Переход к объектам текущего проекта уже работает, в кишках компилятора сильно копаться не надо. Нужно сделать переход к объектам, которые находятся во внешних модулях. В качестве примера:

"".ToString();

Если в студии в C# нажать F12 на ToString, то студия сгенертрует заглушку для класса System.String и спозиционирует туда курсор.

Такую же функцию нужно сделать и нам. Для этого практически всё готово, сильно долго разбираться не надо, зато есть возможность реально потренироваться на N и посмотреть как работает VS SDK.

Если найдутся желающие, то смотреть файл Nemerle.Compiler.Utils -> Nemerle.Completion2 -> CodeModel -> GotoInfo.n.

В этом файле конструкторы принимают объекты и устанавливают Location, если после этого свойство класса HasLocation == false, то нужно посмотреть что у нас за объект и сгенертровать для него файл как это делает студия для C#.

Налетай
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re: Есть простая задачка для желающих
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.09.06 11:45
Оценка:
Здравствуйте, IT, Вы писали:

IT>В этом файле конструкторы принимают объекты и устанавливают Location, если после этого свойство класса HasLocation == false, то нужно посмотреть что у нас за объект и сгенертровать для него файл как это делает студия для C#.


Если есть .pdb-хи и исходники, то желательно бы позиционироваться на исходники, а не генерировать фэйк-код. Так, например, для исходников компилятора и библиотеки Немерла хотелось бы прыгать на них.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Есть простая задачка для желающих
От: robot01  
Дата: 07.09.06 10:19
Оценка:
Здравствуйте, IT, Вы писали:

IT>Нужно доделать функцию Go To Definition.


IT>Переход к объектам текущего проекта уже работает, в кишках компилятора сильно копаться не надо. Нужно сделать переход к объектам, которые находятся во внешних модулях. В качестве примера:


IT>
IT>"".ToString();
IT>

IT>Если в студии в C# нажать F12 на ToString, то студия сгенертрует заглушку для класса System.String и спозиционирует туда курсор.

IT>Такую же функцию нужно сделать и нам. Для этого практически всё готово, сильно долго разбираться не надо, зато есть возможность реально потренироваться на N и посмотреть как работает VS SDK.


IT>Если найдутся желающие, то смотреть файл Nemerle.Compiler.Utils -> Nemerle.Completion2 -> CodeModel -> GotoInfo.n.


IT>В этом файле конструкторы принимают объекты и устанавливают Location, если после этого свойство класса HasLocation == false, то нужно посмотреть что у нас за объект и сгенертровать для него файл как это делает студия для C#.


IT>Налетай


Потратил несколько часов на знакомство с поставленной вами задачей.
Честно говоря нормального пути решения я не увидил (не нормальный путь это тупо сгенерировать файл с помощью String.Format).
Нормальный путь для решения сей задачи это: использовать NemerleCodeProvider и с помошью него сгенерить файл.
Все бы хорошо но кодпровайдер хочет стандартные классы из CodeDom, а все что я могу получить это Nemerle.Compiler.TypeInfo, что с этим классом делать ума не пролижу, переколбасить в CodeTypeDeclaration? чесно говоря не представляю как такое можно сделать....перелопачивать в лоб? тупо и на долго....
Может быть подскажите в каком направлении копать?
Re[2]: Есть простая задачка для желающих
От: IT Россия linq2db.com
Дата: 07.09.06 12:07
Оценка:
Здравствуйте, robot01, Вы писали:

R>Может быть подскажите в каком направлении копать?


Я бы посмотрел у полученного объекта DeclaringType для начала.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Есть простая задачка для желающих
От: Аноним  
Дата: 07.09.06 12:59
Оценка:
Здравствуйте, IT, Вы писали:

IT>Я бы посмотрел у полученного объекта DeclaringType для начала.


Я на него и смотрю, у него тип Nemerle.Compiler.TypeInfo (на сколько я понял это класс описывающий тип со специфичными для немерле условиям). Ворос вот в чем: что бы с ним можно было работать средствами CodeProvider`а нужно привести его к типу CodeTypeDeclaration (из CodeDom), есть ли для этого какието штатные средства?
Или есть иные средства кодо генераци?
Или предпологаетс тупо в лоб нарубать файл выдергивая значения руками?

Наверное я задаю моного глупых вопросов, но документации ни по компилятору ни по плагину нет, так что единственный способ что то узнать это либо пытать более опытных товарищей либо биться об стену самому.... Надеюсь я не слишком парю
Re[3]: Есть простая задачка для желающих
От: robot01  
Дата: 07.09.06 13:03
Оценка:
Упс предыдущее сообщение от меня....
Re[2]: Есть простая задачка для желающих
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.09.06 16:53
Оценка:
Здравствуйте, robot01, Вы писали:

R>Потратил несколько часов на знакомство с поставленной вами задачей.

R>Честно говоря нормального пути решения я не увидил (не нормальный путь это тупо сгенерировать файл с помощью String.Format).

R>Нормальный путь для решения сей задачи это: использовать NemerleCodeProvider и с помошью него сгенерить файл.


Будут проблемы. CodeDomProvider рассчитан на усредненный язык. В этом языке как минимум нет таких понятий как variant-ы. К тому же нет путей посторить CodeDom по сборке. Это прийдется делать вручную. А раз так, то не вижу особого смысла в промежеточном коде.

string.Format тоже не лучший инструмент. Нут нужно генерировать текст. Для этого лучше всего подходят нековые строковые шаблонные движки. Например, StringTemplate или XSLT. В принципе немерловые сплайсет-строки очень похожи на эти движки, но я бы их немного доработал. Так нужна поддержка вложенности (отступы).

R>Все бы хорошо но кодпровайдер хочет стандартные классы из CodeDom, а все что я могу получить это Nemerle.Compiler.TypeInfo, что с этим классом делать ума не пролижу, переколбасить в CodeTypeDeclaration? чесно говоря не представляю как такое можно сделать....перелопачивать в лоб? тупо и на долго....

R>Может быть подскажите в каком направлении копать?

Мне кажется нужно используя TypeInfo генерировать код на базе строковых шаблонов. В общем-то это не сложно если делать с гловой. Надо создать по шаблону жля каждого элемнта (класса, структуры, метода, свойства...) и вызвать их рекурсивно. Например, шаблон для класса может выглядить так:
Class:
$(Split(customAttributs, modifiers, " "))class $(typeInfo.Name) $(Super(typeInfo))
{
    $(Memebers(typeInfo))
}

далее точно так же насписываются все подшаблоны (Super и Memebers в данном случае).
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Есть простая задачка для желающих
От: IT Россия linq2db.com
Дата: 07.09.06 19:45
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Я на него и смотрю, у него тип Nemerle.Compiler.TypeInfo (на сколько я понял это класс описывающий тип со специфичными для немерле условиям). Ворос вот в чем: что бы с ним можно было работать средствами CodeProvider`а нужно привести его к типу CodeTypeDeclaration (из CodeDom), есть ли для этого какието штатные средства?


С CodeProvider не слишком сложно получится?

А>Или есть иные средства кодо генераци?


TypeInfo сам уже умеет кое что показывать. Может быть его ToString вполне подойдёт.

А>Или предпологаетс тупо в лоб нарубать файл выдергивая значения руками?


Можно и нарубать. Ты попробуй, а там видно будет. За последующий рефакторинг/переделки ругать никто не будет

А>Наверное я задаю моного глупых вопросов, но документации ни по компилятору ни по плагину нет, так что единственный способ что то узнать это либо пытать более опытных товарищей либо биться об стену самому.... Надеюсь я не слишком парю


Не слишком. Я прежде чем начать что-то делать Влада по телефону часа четыре парил.
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Есть простая задачка для желающих
От: IT Россия linq2db.com
Дата: 07.09.06 19:52
Оценка:
Здравствуйте, robot01, Вы писали:

Ещё хорошо бы не обновлять файлы на диске в случае ненадобности. А то студия может начать задавать глупые вопросы про файл изменился, бла-бла-бла. Так же студия умеет писать рядом с именем таких файлов [from metadata]. Тоже не понятно как это сделать. Хотя может они по имени каталога как-то вычисляют. У меня оно такое — C:\Temp\4040$CommonLanguageRuntimeLibrary$v2.0.50727

В общем, надо разбираться.
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Есть простая задачка для желающих
От: robot01  
Дата: 08.09.06 11:38
Оценка:
Спасибо за совет.

Возник еще вопрос: захотелось мне написать тесты ко всему этому добру но напоролся на проблему, самому создать объект типа TypeInfo почти не реально (куча гемора с зависимыми объектами и прочее), мокать тоже как то грустно, какие есть варианты?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Есть простая задачка для желающих
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.09.06 11:55
Оценка:
Здравствуйте, robot01, Вы писали:

R>Возник еще вопрос: захотелось мне написать тесты ко всему этому добру но напоролся на проблему, самому создать объект типа TypeInfo почти не реально (куча гемора с зависимыми объектами и прочее), мокать тоже как то грустно, какие есть варианты?


Смотри файлы:
Nemerle.VSIP\Nemerle.Compiler.Utils\Nemerle.Completion2\Tests\Content\Class1.n
Nemerle.VSIP\Nemerle.Compiler.Utils\Nemerle.Completion2\Tests\Content\Class1-2.n

это тестовый код (не код тестов, а код используемый тестами).

Далее, это:
Nemerle.VSIP\Nemerle.Compiler.Utils\Nemerle.Completion2\Tests\Tests.n
Nemerle.VSIP\Nemerle.Compiler.Utils\Nemerle.Completion2\Tests\Tests.Init.n

Код самих тестов.
Вызывать их можно или через NUnit (про версию тут рядом ветка есть):
Nemerle.VSIP\VSIntegartion.nunit

Или через специальный консольный проект Nemerle.VSIP\ConsoleTest\ConsoleTest.csproj (входит в основной солюшен). Этот проект удобен для отладки.

В файле Tests.Init.n находится небольшой фрэйворк для тесто. Думаю, что из его исходников и самого теста будет явно как что применять.

Далее тебе останется только найти какой-нибудь тип и писать тесты.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Есть простая задачка для желающих
От: robot01  
Дата: 08.09.06 12:17
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Далее, это:

VD>Nemerle.VSIP\Nemerle.Compiler.Utils\Nemerle.Completion2\Tests\Tests.n
VD>Nemerle.VSIP\Nemerle.Compiler.Utils\Nemerle.Completion2\Tests\Tests.Init.n

Я собственно смотрел их раньше, там тестируются функции полностью (т.е. это функиональные тесты) это не совсем то что мне нужно, мне бы хотелось взять какую нибудь штуку ( ) натравить ее на файл и что бы она его распарсила и выдала мне список TypeInfo (ну или дерево или не важно чего главное что бы я мог извлечь от туда информацию о типах описанных мною в файле) а я потом мог с помошью этого прогнать юнит тесты.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Есть простая задачка для желающих
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.09.06 16:55
Оценка:
Здравствуйте, robot01, Вы писали:

R>мне бы хотелось взять какую нибудь штуку ( ) натравить ее на файл и что бы она его распарсила и выдала мне список TypeInfo (ну или дерево или не важно чего главное что бы я мог извлечь от туда информацию о типах описанных мною в файле) а я потом мог с помошью этого прогнать юнит тесты.


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

Получить список типов довольно просто. Вот тест который это делает:
[Test]
public PrintTypes() : void
{
    def tree = _project.NamespaceTree;
    Assert.IsNotNull(tree, "result is null");
}

В tree будет дерево теипов. Из него правда еще нужно достать типы, но этот код легко найти. Там просто дерево.

То как выцепить сами классы можно подсмотреть в _project.GetActiveDecl(file, line, col).
Эта функция выдает типы полученные путем парсинга, но не трудно сделать ее клон и кострировать до нужного состояния.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Есть простая задачка для желающих
От: Nuald Россия http://nuald.blogspot.com
Дата: 09.09.06 02:16
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Или через специальный консольный проект Nemerle.VSIP\ConsoleTest\ConsoleTest.csproj (входит в основной солюшен). Этот проект удобен для отладки.


А как им пользоваться?
Если запускать из-под Visual Studio, то он просто падает с DirectoryNotFoundException "Could not find a part of the path 'D:\\Work\\Nemerle\\vs-plugin\\bin\\Debug\\Nemerle.Completion2\\Tests\\Content\\Class1.n'."
Если же его скопировать в Nemerle.Compiler.Utils и запустить, то он просто выводит:
===================================
public static method ClassExtension.Foo(s : string) : int

Nemerle.Completion2\Tests\Content\Class1.n:146:3:149:4:
public static method ClassExtension.Foo(s : string) : int

Nemerle.Completion2\Tests\Content\Class1.n:146:3:149:4:
public static method ClassExtension.Foo(s : string) : int

Nemerle.Completion2\Tests\Content\Class1.n:146:3:149:4:
public static method ClassExtension.Foo(s : string) : int

Nemerle.Completion2\Tests\Content\Class1.n:146:3:149:4:
public static method ClassExtension.Foo(s : string) : int

Nemerle.Completion2\Tests\Content\Class1.n:146:3:149:4:
===================================

WTF? С NUnit-ом еще более или менее понятно (хотя тесты из Nemerle.VsIntegration.Tests почему-то все Failed), то с ConsoleTest хотелось бы поближе разобраться, учитывая что он "удобен для отладки".
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Есть простая задачка для желающих
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.09.06 08:55
Оценка:
Здравствуйте, Nuald, Вы писали:

N>А как им пользоваться?

N>Если запускать из-под Visual Studio, то он просто падает с DirectoryNotFoundException "Could not find a part of the path 'D:\\Work\\Nemerle\\vs-plugin\\bin\\Debug\\Nemerle.Completion2\\Tests\\Content\\Class1.n'."

Ну, это элементано, Ватсон!

Само сообщение говорит о том, что нужно делать.
Зайди в настройке проекта и на закладке Debug, в поле Working Directory укажи путь:
D:\MyProjects\RSDN\Nemerle\Nemerle.VSIP\Nemerle.Compiler.Utils\

естествнно начальная часть будет твоя.

N>Если же его скопировать в Nemerle.Compiler.Utils и запустить, то он просто выводит:

N>===================================
N>public static method ClassExtension.Foo(s : string) : int
N>...

А что бы ты хотел чтобы он выводил? Да и какое дело что он там выводит. Это тесты. Они вообще могут ничего не выводить.

Если тебе что-то надо, то пиши свой тест и из под отладчика с ним возись. За одно в будущем все твои тесты будут автоматом проверяться и если что-то где-то испортится, то это будет сразу видно.

N>WTF? С NUnit-ом еще более или менее понятно (хотя тесты из Nemerle.VsIntegration.Tests почему-то все Failed), то с ConsoleTest хотелось бы поближе разобраться, учитывая что он "удобен для отладки".


В Nemerle.VsIntegration.Tests я не суюсь. Это не мои тесты. Мои на сегодня все зеленинькие.

Что касается NUnit, то он прекрасен для быстрой проверки, но отладку из него не сделашь. Именно по этому появился ConsoleTest.

Идея его очень проста. Он позволяет запустить юнит-тесты из под отладчика (как обычные методы) и поглядеть что не ладно в датском королевстве. Он тупо загружает сборку Nemerle.Compiler.Utils.dll, создает класс Tests.Test1 и дергает его методы.

В Tests.Test1 есть мелкий фрэймворк по подему компиляторных функций. В методе Init() этого класса создается и инициализируется двумя файлами движок интелисенса (класс Nemerle.Completion2.Engine).
У него получается так называемый "проект". Через поля _engine и _project класа Test1 можно получить доступ к любой информации о коде и воспользоваться функциями интелисенса или компилятора.

Так что добавляй новый тест и делай в нем все что душе угодно. Есть только два условия. Ты не должен очень сильно занимать процессорное время и много выводить на консоль (все же тесты часто гоняются как напрямую так и через НЮнит).
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Есть простая задачка для желающих
От: vdimas Россия  
Дата: 09.09.06 08:59
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Что касается NUnit, то он прекрасен для быстрой проверки, но отладку из него не сделашь. Именно по этому появился ConsoleTest.


VD>Идея его очень проста. Он позволяет запустить юнит-тесты из под отладчика (как обычные методы) и поглядеть что не ладно в датском королевстве. Он тупо загружает сборку Nemerle.Compiler.Utils.dll, создает класс Tests.Test1 и дергает его методы.


Сорри, что встреваю, а что не так с NUnit при запуске тестов на отладку?
Re[8]: Есть простая задачка для желающих
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.09.06 10:57
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Сорри, что встреваю, а что не так с NUnit при запуске тестов на отладку?


GUI которое на фиг не упало.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Есть простая задачка для желающих
От: IT Россия linq2db.com
Дата: 09.09.06 15:55
Оценка:
Здравствуйте, VladD2, Вы писали:

V>>Сорри, что встреваю, а что не так с NUnit при запуске тестов на отладку?


VD>GUI которое на фиг не упало.


А мне нравится
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[10]: Есть простая задачка для желающих
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.09.06 19:06
Оценка:
Здравствуйте, IT, Вы писали:

VD>>GUI которое на фиг не упало.


IT>А мне нравится


А нафига оно при отладке? Лишние телодвижения при отладке вредны. Они вообще только для похудения нужны.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Есть простая задачка для желающих
От: Nuald Россия http://nuald.blogspot.com
Дата: 11.09.06 04:58
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Само сообщение говорит о том, что нужно делать.


Хм, сообшение об этом ничего не говорит, по-крайней мере, для непосвященного. В мире всеобщей рефлексии и эмита какой бы не был текст ошибки, нельзя сделать никакие выводы, предварительно не отладив тонны кода

VD>Зайди в настройке проекта и на закладке Debug, в поле Working Directory укажи путь:

VD>
VD>D:\MyProjects\RSDN\Nemerle\Nemerle.VSIP\Nemerle.Compiler.Utils\
VD>

VD>естествнно начальная часть будет твоя.

Думаю, проще было бы добавить такую проверку (или даже автоматическую настройку), чтобы люди не пугались, и не задавали глупые вопросы. Потом сделаю, но как только разберусь со следующей ошибкой — я запускаю ConsoleTest и у меня вылетает assert в Nemerle.Compiler.Utils\Nemerle.Completion2\Tests\Tests.n, line 55, "result is null", т.е. строчка
def result = _project.GetQuickTipInfo(file, line, col, GetTextFromFile(file, _, _, _, _));

выдает null (хотя все NUnit-тесты проходят нормально). По идее file должен находится и открываться (Working Dir в опциях проекта указан правильно). С чем это может быть связано?

VD>Если тебе что-то надо, то пиши свой тест и из под отладчика с ним возись. За одно в будущем все твои тесты будут автоматом проверяться и если что-то где-то испортится, то это будет сразу видно.


Мне проще это делать из под Решарпера — он умеет как просто запускать тесты, так их и отлаживать.

VD>В Nemerle.VsIntegration.Tests я не суюсь. Это не мои тесты. Мои на сегодня все зеленинькие.


Хм, а чьи? Может тогда проще их удалить, если никто не поддерживает. В принципе, могу привести в работоспособное состояние, если нужно.

VD>Так что добавляй новый тест и делай в нем все что душе угодно. Есть только два условия. Ты не должен очень сильно занимать процессорное время и много выводить на консоль (все же тесты часто гоняются как напрямую так и через НЮнит).


Мы как-то делали обработку графики, и там был такой стресс-тест — надо было загрузить большую-большую картинку и ее обработать без вылетов о нехватке памяти и уложиться в определенный интервал времени. Это было частью NUnit-теста и занимало около 4-5 минут
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Баг или еще не реализовано?
От: Аноним  
Дата: 11.09.06 14:44
Оценка:
Здравствуйте, VladD2, Вы писали:

Есть простой класс (листинг ниже) строю по мему TypeInfo, нахожу с помощью LookupMember Field1, пытаюсь по этому полю получить информацию GetFieldInfo и вылазит эксепшен:Nemerle.Completion2.Tests.SingatureGenerator.TestField : Nemerle.Core.AssertionException : assertion ``field_builder != null'' failed in file ncc\hierarchy\ClassMembers.n, line 442:
Стек трейс:
в Nemerle.Compiler.FieldBuilder.GetFieldInfo() в D:\Projects\Nemerle\ncc\hierarchy\ClassMembers.n:строка 442
в Nemerle.Compiler.FieldBuilder.Nemerle.Compiler.IField.GetFieldInfo() в D:\Projects\Nemerle\ncc\hierarchy\ClassMembers.n:строка 440
в Nemerle.Completion2.SingatureGenerator.GetFieldSingature(IField fieldInfo) в D:\Projects\Nemerle.VSIP\Nemerle.Compiler.Utils\Nemerle.Completion2\CodeModel\SinпatureGenerator.n:строка 86
в Nemerle.Completion2.Tests.SingatureGenerator.TestField() в D:\Projects\Nemerle.VSIP\Nemerle.Compiler.Utils\Nemerle.Completion2\CodeModel\Tests\SinпatureGenerator.n:строка 93

Field1
using System;
namespace Nemerle.Compiler.Utils.Nemerle.Completion2.CodeModel.Tests.Content
{
    public class Content
    {
        public Method1() : void
        {
            3;
        }

        public Method2(i: int) : double
        {
            2;
        }

        public mutable Field1 : string;

        public PropertyFull : string
        {
            get {"1";}
            set {def i = 1;}
        }

        public PropertyGet : double
        {
            get {1;}
        }

    }
}
Re[7]: Есть простая задачка для желающих
От: robot01  
Дата: 11.09.06 14:46
Оценка:
Предыдущее сообщение от меня? старого склеротика
Re[8]: Баг или еще не реализовано?
От: IT Россия linq2db.com
Дата: 11.09.06 23:14
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Есть простой класс (листинг ниже) строю по мему TypeInfo, нахожу с помощью LookupMember Field1, пытаюсь по этому полю получить информацию GetFieldInfo и вылазит эксепшен:Nemerle.Completion2.Tests.SingatureGenerator.TestField : Nemerle.Core.AssertionException : assertion ``field_builder != null'' failed in file ncc\hierarchy\ClassMembers.n, line 442:


А что в отладчике видать?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[9]: Баг или еще не реализовано?
От: robot01  
Дата: 12.09.06 07:02
Оценка:
Здравствуйте, IT, Вы писали:

IT>А что в отладчике видать?


Не очень понял вопрос? в отладчике то и видать эксепшен..
Re[9]: Есть простая задачка для желающих
От: vdimas Россия  
Дата: 12.09.06 11:50
Оценка:
Здравствуйте, VladD2, Вы писали:

V>>Сорри, что встреваю, а что не так с NUnit при запуске тестов на отладку?


VD>GUI которое на фиг не упало.


Есть же консольный test-runner, стартует действительно, на пол-секунды быстрее, а во вторых есть удобный аттрибут Explicit, у нас тесты и фикстуры помечены им, кроме тех, которые должны отрабатывать всегда без принудительного запуска. Для твоего сценария надо просто убирать этот аттрибут из теста, который ты намереваешься многократно гонять в дебаге. Как раз получишь минимум движений. Для GUI test-runnera все в силе, когда запускается с опцией автоматического прогона тестов (т.е. телодвижений ничуть не больше), но раздельный вывод информации мне тоже нравится больше.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Баг или еще не реализовано?
От: IT Россия linq2db.com
Дата: 12.09.06 12:20
Оценка:
Здравствуйте, robot01, Вы писали:

IT>>А что в отладчике видать?


R>Не очень понял вопрос? в отладчике то и видать эксепшен..


Я имею ввиду чтр если побраузить объект в Quick Watch? Может у него данные в каком-нибудь другом месте лежать.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[11]: Баг или еще не реализовано?
От: robot01  
Дата: 12.09.06 12:53
Оценка:
Здравствуйте, IT, Вы писали:

IT>Я имею ввиду чтр если побраузить объект в Quick Watch? Может у него данные в каком-нибудь другом месте лежать.

хммм в принципе объект с которым я работаю это FieldBuilder и у него есть внутреннее поле ty, где лежит все что нужно, НО я не уверен что приводить IField к FieldBuilder корректно... и еще я не уверен что ty будет заполняться если мы будем рабоать через рефликсию и не напряму парсить файл.... вообще очень много но....
Re[12]: Баг или еще не реализовано?
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.09.06 13:28
Оценка:
Здравствуйте, robot01, Вы писали:

R>хммм в принципе объект с которым я работаю это FieldBuilder и у него есть внутреннее поле ty, где лежит все что нужно, НО я не уверен что приводить IField к FieldBuilder корректно... и еще я не уверен что ty будет заполняться если мы будем рабоать через рефликсию и не напряму парсить файл.... вообще очень много но....


Корректно. IField, как и другие интерфейсы наследники IMember, это общая информация о члене независящая от того является ли он членом класса импортированного из другой сборки или членом класса распознанным из кода. Но реализуются они разыми типами. Для распозного из кода члена всегда выступает какй-то Builder (для поля FieldBuilder, для метода MethodBuilder, и т.п.).

Вот только нужно не "приводить", а пользоваться паттерн-матчингом. Чтобы не грохнуло, если все же член импортирован из другой сборки.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Баг или еще не реализовано?
От: robot01  
Дата: 12.09.06 14:08
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Корректно. IField, как и другие интерфейсы наследники IMember, это общая информация о члене независящая от того является ли он членом класса импортированного из другой сборки или членом класса распознанным из кода. Но реализуются они разыми типами. Для распозного из кода члена всегда выступает какй-то Builder (для поля FieldBuilder, для метода MethodBuilder, и т.п.).


VD>Вот только нужно не "приводить", а пользоваться паттерн-матчингом. Чтобы не грохнуло, если все же член импортирован из другой сборки.


Я собственно догадался об это, вопрос заключался не в том какой тип за что отвечает первичный вопрос:Баг или еще не реализовано
Автор:
Дата: 11.09.06
.
Re[14]: Баг или еще не реализовано?
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.09.06 14:30
Оценка:
Здравствуйте, robot01, Вы писали:

R>Я собственно догадался об это, вопрос заключался не в том какой тип за что отвечает первичный вопрос:Баг или еще не реализовано
Автор:
Дата: 11.09.06
.


Так вопрос снят?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Есть простая задачка для желающих
От: vdimas Россия  
Дата: 12.09.06 14:51
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ладно. В следующий раз разбирусь. Пока просто в лом дергаться. Все работает...


[Test, Explicit]
public void SomeTest() {}

[TestFixture, Explicit]
public class SomeTestFixture : OurBaseTestFixture {

}


Фикстуры и тесты, помеченные Explicit не запускаются автоматом, поэтому для многократного автоматического захода в некий тест мы убираем/комментируем Explicit и попадаем в тест автоматом при запуске.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[15]: Баг или еще не реализовано?
От: robot01  
Дата: 13.09.06 07:28
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Так вопрос снят?


Нет вопрос не снят баг никуда не делся, а то что я описал (внутреннее поле ty) работет только для типов которые получаются разбором исходников.
Re[8]: Есть простая задачка для желающих
От: VladD2 Российская Империя www.nemerle.org
Дата: 13.09.06 12:57
Оценка:
Здравствуйте, Nuald, Вы писали:

N>Думаю, проще было бы добавить такую проверку (или даже автоматическую настройку), чтобы люди не пугались, и не задавали глупые вопросы. Потом сделаю, но как только разберусь со следующей ошибкой — я запускаю ConsoleTest и у меня вылетает assert в Nemerle.Compiler.Utils\Nemerle.Completion2\Tests\Tests.n, line 55, "result is null", т.е. строчка

N>
N>def result = _project.GetQuickTipInfo(file, line, col, GetTextFromFile(file, _, _, _, _));
N>

N>выдает null (хотя все NUnit-тесты проходят нормально). По идее file должен находится и открываться (Working Dir в опциях проекта указан правильно). С чем это может быть связано?

Незнаю. У меня все работает нормально. Проверь еще раз "Working Dir". У меня он таков:
D:\MyProjects\RSDN\Nemerle\Nemerle.VSIP\Nemerle.Compiler.Utils\

Так же обнови и перекомпилируй исходники компилятора и интеграции. Возможно у тебя рассинхронизация версий. Так же стоит почистить все старые версии бинарников. Может где зацепляется старье.

VD>>Если тебе что-то надо, то пиши свой тест и из под отладчика с ним возись. За одно в будущем все твои тесты будут автоматом проверяться и если что-то где-то испортится, то это будет сразу видно.


N>Мне проще это делать из под Решарпера — он умеет как просто запускать тесты, так их и отлаживать.


С решарпером другого гимора моного. Ну, да хочешь делай через него. Но тут я тебе не помошник. Я его просто не стал ставить когда выинт переставлял на ноуте.

VD>>В Nemerle.VsIntegration.Tests я не суюсь. Это не мои тесты. Мои на сегодня все зеленинькие.


N>Хм, а чьи? Может тогда проще их удалить, если никто не поддерживает. В принципе, могу привести в работоспособное состояние, если нужно.


Относятся к работе с дизайнером формам. Я туда не лазил. Формы у меня тоже не работают. Но удалять ничего не надо. Пусть автор разбираетя или те кто потом будут заниматься дизайнером форм.

VD>>Так что добавляй новый тест и делай в нем все что душе угодно. Есть только два условия. Ты не должен очень сильно занимать процессорное время и много выводить на консоль (все же тесты часто гоняются как напрямую так и через НЮнит).


N>Мы как-то делали обработку графики, и там был такой стресс-тест — надо было загрузить большую-большую картинку и ее обработать без вылетов о нехватке памяти и уложиться в определенный интервал времени. Это было частью NUnit-теста и занимало около 4-5 минут


Это ваши проблемы. Я такой тест сразу грохну. Мне минуты компиляции компилятора уже выше крыши.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: Баг или еще не реализовано?
От: VladD2 Российская Империя www.nemerle.org
Дата: 13.09.06 12:57
Оценка:
Здравствуйте, robot01, Вы писали:

R>Нет вопрос не снят баг никуда не делся, а то что я описал (внутреннее поле ty) работет только для типов которые получаются разбором исходников.


Незнаю, поглядел код и не вижу проблемы.
IField унаследован от IMember. IMember имеет метод GetMemType(). Так что делаем так:
def tyInfo = member.GetMemType().TypeInfo;

и получаем универсальное описание для любого поля.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Есть простая задачка для желающих
От: Nuald Россия http://nuald.blogspot.com
Дата: 14.09.06 23:15
Оценка:
Здравствуйте, VladD2, Вы писали:

N>>Хм, а чьи? Может тогда проще их удалить, если никто не поддерживает. В принципе, могу привести в работоспособное состояние, если нужно.

VD>Относятся к работе с дизайнером формам. Я туда не лазил. Формы у меня тоже не работают. Но удалять ничего не надо. Пусть автор разбираетя или те кто потом будут заниматься дизайнером форм.

Я ничего удалять и не собираюсь, а наоборот, привести в работоспособное состояние. Посмотрю на досуге, как только разберусь с ConsoleTest.

N>>Мы как-то делали обработку графики, и там был такой стресс-тест — надо было загрузить большую-большую картинку и ее обработать без вылетов о нехватке памяти и уложиться в определенный интервал времени. Это было частью NUnit-теста и занимало около 4-5 минут

VD>Это ваши проблемы. Я такой тест сразу грохну. Мне минуты компиляции компилятора уже выше крыши.

Ну понятно дело — тесты должны быть короткими. Хотя как вспомню CCNET от Фаулера и Ко, у них тесты-то маленькие, но их такая куча Впрочем, я не фанатик TDD, так что мне наверное не понять.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Есть простая задачка для желающих
От: VladD2 Российская Империя www.nemerle.org
Дата: 15.09.06 00:12
Оценка:
Здравствуйте, Nuald, Вы писали:

N>Я ничего удалять и не собираюсь, а наоборот, привести в работоспособное состояние. Посмотрю на досуге, как только разберусь с ConsoleTest.


Это пожалуйса. Главное чтобы не наоборот. Тут есть смысл с их автором пообщаться.

N>Ну понятно дело — тесты должны быть короткими. Хотя как вспомню CCNET от Фаулера и Ко, у них тесты-то маленькие, но их такая куча


Кучу можно отключить. А вот ждать когда закончится 1 длинный прийдется по любому.

N>Впрочем, я не фанатик TDD, так что мне наверное не понять.


Я тоже. И вообще разум рулит.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Есть простая задачка для желающих
От: Блудов Павел Россия  
Дата: 19.09.06 03:43
Оценка:
Здравствуйте, Nuald, Вы писали:

N>
N>def result = _project.GetQuickTipInfo(file, line, col, GetTextFromFile(file, _, _, _, _));
N>

N>выдает null (хотя все NUnit-тесты проходят нормально). По идее file должен находится и открываться (Working Dir в опциях проекта указан правильно). С чем это может быть связано?

Пробелов, случайно, нет в этом самом Working Dir?
Re[9]: Есть простая задачка для желающих
От: Nuald Россия http://nuald.blogspot.com
Дата: 19.09.06 04:03
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Пробелов, случайно, нет в этом самом Working Dir?


Нет. Вообще, проблему я решил — слишком много было Nemerle.Compiler.dll по системе разбросано. По ходу, пока я разбирался со сборкой Немерле, NGen понаделал делов
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Unmanaged interfaces
От: Блудов Павел Россия  
Дата: 19.09.06 09:45
Оценка:
    #region MetaDataImport

    [StructLayout(LayoutKind.Sequential)]
    public struct COR_FIELD_OFFSET
    {
        public uint ridOfField;
        public uint ulOffset;
    }

    [ComImport, Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IMetaDataImport
    {
        [PreserveSig]
        void CloseEnum(uint hEnum);
        uint CountEnum(uint hEnum);
        void ResetEnum(uint hEnum, uint ulPos);
        uint EnumTypeDefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeDefs, uint cMax);
        uint EnumInterfaceImpls(ref uint phEnum, uint td, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rImpls, uint cMax);
        uint EnumTypeRefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeRefs, uint cMax);
        uint FindTypeDefByName(string szTypeDef, uint tkEnclosingClass);
        Guid GetScopeProps(StringBuilder szName, uint cchName, out uint pchName);
        uint GetModuleFromScope();
        uint GetTypeDefProps(uint td, IntPtr szTypeDef, uint cchTypeDef, out uint pchTypeDef, IntPtr pdwTypeDefFlags);
        uint GetInterfaceImplProps(uint iiImpl, out uint pClass);
        uint GetTypeRefProps(uint tr, out uint ptkResolutionScope, StringBuilder szName, uint cchName);
        uint ResolveTypeRef(uint tr, [In] ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppIScope);
        uint EnumMembers(ref uint phEnum, uint cl, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rMembers, uint cMax);
        uint EnumMembersWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMembers, uint cMax);
        //uint EnumMethods(ref uint phEnum, uint cl, uint* rMethods, uint cMax);
        uint EnumMethods();
        uint EnumMethodsWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethods, uint cMax);
        //uint EnumFields(ref uint phEnum, uint cl, uint* rFields, uint cMax);
        uint EnumFields();
        uint EnumFieldsWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rFields, uint cMax);
        uint EnumParams(ref uint phEnum, uint mb, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rParams, uint cMax);
        uint EnumMemberRefs(ref uint phEnum, uint tkParent, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rMemberRefs, uint cMax);
        uint EnumMethodImpls(ref uint phEnum, uint td, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethodBody, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethodDecl, uint cMax);
        uint EnumPermissionSets(ref uint phEnum, uint tk, uint dwActions, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rPermission, uint cMax);
        uint FindMember(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob);
        uint FindMethod(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob);
        uint FindField(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob);
        uint FindMemberRef(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob);
        uint GetMethodProps(uint mb, out uint pClass, IntPtr szMethod, uint cchMethod, out uint pchMethod, IntPtr pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, IntPtr pulCodeRVA);
        //uint GetMemberRefProps(uint mr, ref uint ptk, StringBuilder szMember, uint cchMember, out uint pchMember, out byte* ppvSigBlob);
        uint GetMemberRefProps();
        //uint EnumProperties(ref uint phEnum, uint td, uint* rProperties, uint cMax);
        uint EnumProperties();
        //uint EnumEvents(ref uint phEnum, uint td, uint* rEvents, uint cMax);
        uint EnumEvents();
        uint GetEventProps(uint ev, out uint pClass, StringBuilder szEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags, out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 11)] uint[] rmdOtherMethod, uint cMax);
        uint EnumMethodSemantics(ref uint phEnum, uint mb, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rEventProp, uint cMax);
        uint GetMethodSemantics(uint mb, uint tkEventProp);
        uint GetClassLayout(uint td, out uint pdwPackSize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] COR_FIELD_OFFSET[] rFieldOffset, uint cMax, out uint pcFieldOffset);
        //uint GetFieldMarshal(uint tk, out byte* ppvNativeType);
        uint GetFieldMarshal();
        uint GetRVA(uint tk, out uint pulCodeRVA);
        //uint GetPermissionSetProps(uint pm, out uint pdwAction, out void* ppvPermission);
        uint GetPermissionSetProps();
        //uint GetSigFromToken(uint mdSig, out byte* ppvSig);
        uint GetSigFromToken();
        uint GetModuleRefProps(uint mur, StringBuilder szName, uint cchName);
        uint EnumModuleRefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rModuleRefs, uint cmax);
        //uint GetTypeSpecFromToken(uint typespec, out byte* ppvSig);
        uint GetTypeSpecFromToken();
        uint GetNameFromToken(uint tk);
        uint EnumUnresolvedMethods(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rMethods, uint cMax);
        uint GetUserString(uint stk, StringBuilder szString, uint cchString);
        uint GetPinvokeMap(uint tk, out uint pdwMappingFlags, StringBuilder szImportName, uint cchImportName, out uint pchImportName);
        uint EnumSignatures(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rSignatures, uint cmax);
        uint EnumTypeSpecs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeSpecs, uint cmax);
        uint EnumUserStrings(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rStrings, uint cmax);
        [PreserveSig]
        int GetParamForMethodIndex(uint md, uint ulParamSeq, out uint pParam);
        uint EnumCustomAttributes(ref uint phEnum, uint tk, uint tkType, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rCustomAttributes, uint cMax);
        //uint GetCustomAttributeProps(uint cv, out uint ptkObj, out uint ptkType, out void* ppBlob);
        uint GetCustomAttributeProps();
        uint FindTypeRef(uint tkResolutionScope, string szName);
        //uint GetMemberProps(uint mb, out uint pClass, StringBuilder szMember, uint cchMember, out uint pchMember, out uint pdwAttr, out byte* ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out void* ppValue);
        uint GetMemberProps();
        //uint GetFieldProps(uint mb, out uint pClass, StringBuilder szField, uint cchField, out uint pchField, out uint pdwAttr, out byte* ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out void* ppValue);
        uint GetFieldProps();
        //uint GetPropertyProps(uint prop, out uint pClass, StringBuilder szProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags, out byte* ppvSig, out uint pbSig, out uint pdwCPlusTypeFlag, out void* ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter, out uint pmdGetter, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=14)] uint[] rmdOtherMethod, uint cMax);
        uint GetPropertyProps();
        //uint GetParamProps(uint tk, out uint pmd, out uint pulSequence, StringBuilder szName, uint cchName, out uint pchName, out uint pdwAttr, out uint pdwCPlusTypeFlag, out void* ppValue);
        uint GetParamProps();
        //uint GetCustomAttributeByName(uint tkObj, string szName, out void* ppData);
        uint GetCustomAttributeByName();
        [return: MarshalAs(UnmanagedType.Bool)]
        [PreserveSig]
        bool IsValidToken(uint tk);
        uint GetNestedClassProps(uint tdNestedClass);
        //uint GetNativeCallConvFromSig(void* pvSig, uint cbSig);
        uint GetNativeCallConvFromSig();
        int IsGlobal(uint pd);
    }

    [ComImport, Guid("809c652e-7396-11d2-9771-00a0c9b4d50c"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), TypeLibType(TypeLibTypeFlags.FRestricted)]
    internal interface IMetaDataDispenser
    {
        [return: MarshalAs(UnmanagedType.Interface)]
        object DefineScope([In] ref Guid rclsid, [In] uint dwCreateFlags, [In] ref Guid riid);
        [return: MarshalAs(UnmanagedType.Interface)]
        object OpenScope([In, MarshalAs(UnmanagedType.LPWStr)] string szScope, [In] uint dwOpenFlags, [In] ref Guid riid);
        [return: MarshalAs(UnmanagedType.Interface)]
        object OpenScopeOnMemory([In] IntPtr pData, [In] uint cbData, [In] uint dwOpenFlags, [In] ref Guid riid);
    }

    [ComImport, Guid("E5CB7A31-7512-11d2-89CE-0080C792E5D8"), ClassInterface(ClassInterfaceType.None), TypeLibType(TypeLibTypeFlags.FCanCreate)]
    internal class CorMetaDataDispenser
    {
    }

    #endregion MetaDataImport

    #region SymUnmanaged

    [ComImport, Guid("40DE4037-7C81-3E1E-B022-AE1ABFF2CA08"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface ISymUnmanagedDocument
    {
        void GetURL(int size, out uint length, [MarshalAs(UnmanagedType.LPWStr, SizeParamIndex = 0)] StringBuilder url);
        void GetDocumentType(out Guid retval);
        void GetLanguage(out Guid retval);
        void GetLanguageVendor(out Guid retval);
        void GetCheckSumAlgorithmId(out Guid retval);
        void GetCheckSum(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] byte[] data);
        uint FindClosestLine(uint line);
        bool HasEmbeddedSource();
        uint GetSourceLength();
        void GetSourceRange(uint startLine, uint startColumn, uint endLine, uint endColumn, uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] byte[] source);
    }

    [ComImport, Guid("B62B923C-B500-3158-A543-24F307A8B7E1"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface ISymUnmanagedMethod
    {
        uint GetToken();
        uint GetSequencePointCount();
        ISymUnmanagedScope GetRootScope();
        ISymUnmanagedScope GetScopeFromOffset(uint offset);
        uint Getoffset(ISymUnmanagedDocument document, uint line, uint column);
        void GetRanges(ISymUnmanagedDocument document, uint line, uint column, uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] ranges);
        void GetParameters(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedVariable[] parms);
        IntPtr GetNamespace();
        bool GetSourceStartEnd([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0, SizeConst = 2)] ISymUnmanagedDocument[] docs, [MarshalAs(UnmanagedType.LPArray)] uint[] lines, [MarshalAs(UnmanagedType.LPArray)] uint[] columns);
        void GetSequencePoints(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] offsets, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.IUnknown, SizeParamIndex = 0)] IntPtr[] documents, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] lines, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] columns, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] endLines, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] endColumns);
    }

    [ComImport, Guid("B4CE6286-2A6B-3712-A3B7-1EE1DAD467B5"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface ISymUnmanagedReader
    {
        ISymUnmanagedDocument GetDocument(string url, ref Guid language, ref Guid languageVendor, ref Guid documentType);
        void GetDocuments(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedDocument[] docs);
        uint GetUserEntryPoint();
        ISymUnmanagedMethod GetMethod(uint token);
        ISymUnmanagedMethod GetMethodByVersion(uint token, int version);
        void GetVariables(uint parent, uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ISymUnmanagedVariable[] vars);
        void GetGlobalVariables(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedVariable[] vars);
        ISymUnmanagedMethod GetMethodFromDocumentPosition(ISymUnmanagedDocument document, uint line, uint column);
        void GetSymAttribute(uint parent, string name, ulong size, ref uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] buffer);
        void GetNamespaces(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] namespaces);
        void Initialize([MarshalAs(UnmanagedType.IUnknown)] object importer, string filename, string searchPath, [MarshalAs(UnmanagedType.IUnknown)] object stream);
        void UpdateSymbolStore(string filename, [MarshalAs(UnmanagedType.IUnknown)] object stream);
        void ReplaceSymbolStore(string filename, [MarshalAs(UnmanagedType.IUnknown)] object stream);
        void GetSymbolStoreFileName(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] char[] name);
        void GetMethodsFromDocumentPosition(ISymUnmanagedDocument document, uint line, uint column, uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] ISymUnmanagedMethod[] retval);
        void GetDocumentVersion(ISymUnmanagedDocument doc, out int version, out bool isLatest);
        void GetMethodVersion(ISymUnmanagedMethod method, out int version);
    }

    [ComImport, Guid("68005D0F-B8E0-3B01-84D5-A11A94154942"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface ISymUnmanagedScope
    {
        ISymUnmanagedMethod GetMethod();
        ISymUnmanagedScope GetParent();
        void GetChildren(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] children);
        uint GetStartOffset();
        uint GetEndOffset();
        uint GetLocalCount();
        void GetLocals(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] locals);
        void GetNamespaces(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] namespaces);
    }

    [ComImport, Guid("9F60EEBE-2D9A-3F7C-BF58-80BC991C60BB"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface ISymUnmanagedVariable
    {
        void GetName(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] char[] name);
        uint GetAttributes();
        void GetSignature(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] byte[] name);
        uint GetAddressKind();
        uint GetAddressField1();
        uint GetAddressField2();
        uint GetAddressField3();
        uint GetStartOffset();
        uint GetEndOffset();
    }

    [ComImport, Guid("ACCEE350-89AF-4ccb-8B40-1C2C4C6F9434"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComVisible(false)]
    internal interface ISymUnmanagedBinder
    {
        ISymUnmanagedReader GetReaderForFile([MarshalAs(UnmanagedType.IUnknown)] object importer, string filename, string searchPath);
        ISymUnmanagedReader GetReaderForStream([MarshalAs(UnmanagedType.IUnknown)] object importer, [MarshalAs(UnmanagedType.IUnknown)] object stream);
        ISymUnmanagedReader GetReaderForFile2([MarshalAs(UnmanagedType.IUnknown)] object importer, [MarshalAs(UnmanagedType.LPWStr)] string fileName, [MarshalAs(UnmanagedType.LPWStr)] string searchPath, int searchPolicy);
    }

    [ComImport, Guid("0A29FF9E-7F9C-4437-8B11-F424491E3931")]
    internal class CorSymBinder
    {
    }

    #endregion SymUnmanaged
... << RSDN@Home 1.2.0 alpha rev. 642>>
И ещё в догонку: isymwrapper.dll
От: Блудов Павел Россия  
Дата: 19.09.06 09:57
Оценка:
Если добавить reference на %SystemRoot%\Microsoft.Net\Framework\v2.0.50727\isymwrapper.dll, то можно ISymUnmanagedXXXX не использовать, там вполне нормальные врапперы на c#:
    public class TestClass
    {
        public void TestMethod()
        {
        }
    }

    public class PdbTest
    {
        [STAThread]
        public static void Main(string[] args)
        {
            Guid IMetaDataImportGuid = typeof(IMetaDataImport).GUID;

            // Для интергации нужно использовать IVsSmartOpenScope::OpenScope
            // из VisualStudioIntegration\Common\IDL\compsvcspkg80.idl
            //
            IMetaDataDispenser metaDispenser = (IMetaDataDispenser)new CorMetaDataDispenser();
            IMetaDataImport metaDataImport = (IMetaDataImport)metaDispenser.OpenScope(ExecutableLocation, 0, ref IMetaDataImportGuid);

            // Получаем токен нужного метода
            //
            uint classToken = metaDataImport.FindTypeDefByName("dotNetJim.TestClass", 0);
            uint methodToken = metaDataImport.FindMethod(classToken, "TestMethod", null, 0);

            // Вот собственно работа с .pdb
            //
            ISymbolBinder1 binder = new SymBinder();
            ISymbolReader  reader = binder.GetReader(Marshal.GetIUnknownForObject(metaDataImport), ExecutableLocation, null);
            ISymbolMethod  method = reader.GetMethod(new SymbolToken((int)methodToken));

            int seqPoints = method.SequencePointCount;

            ISymbolDocument[] documents  = new ISymbolDocument[seqPoints];
            int[]   lines      = new int[seqPoints];
            int[]   columns    = new int[seqPoints];
            int[]   endLines   = new int[seqPoints];
            int[]   endColumns = new int[seqPoints];
            int[]   offsets    = new int[seqPoints];
            method.GetSequencePoints(offsets, documents, lines, columns, endLines, endColumns);

            for (int i = 0; i < seqPoints; i++)
                Console.WriteLine("file {0}, line {1} col {2}", documents[i].URL, lines[i], columns[i]);
        }

        public static string ExecutableLocation
        {
            get { return Assembly.GetEntryAssembly().Location; }
        }
    }
... << RSDN@Home 1.2.0 alpha rev. 642>>
И напоследок полезная ссылочка
От: Блудов Павел Россия  
Дата: 19.09.06 10:30
Оценка:
http://blogs.msdn.com/jmstall/archive/2005/10/08/symbol_apis.aspx
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re: И ещё в догонку: isymwrapper.dll
От: IT Россия linq2db.com
Дата: 19.09.06 18:14
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Если добавить reference на %SystemRoot%\Microsoft.Net\Framework\v2.0.50727\isymwrapper.dll, то можно ISymUnmanagedXXXX не использовать, там вполне нормальные врапперы на c#:


Лишних референсов плодить не желательно.

Я не нашёл как получить местонахождение класса и не понятно что делать, если имеется несколько методов с одним названием. Выдается толи первый, толи последний попавшийся.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: И ещё в догонку: isymwrapper.dll
От: Блудов Павел Россия  
Дата: 20.09.06 00:08
Оценка:
Здравствуйте, IT, Вы писали:

IT>Я не нашёл как получить местонахождение класса и не понятно что делать, если имеется несколько методов с одним названием. Выдается толи первый, толи последний попавшийся.


Я так понял, если есть сигнатура метода и известно, в какой сборке он живёт, то нет проблем получить его metadata token. Хоть через рефлексию, хоть через IMetaDataImport (первое явно сделано через второе). Ну а имея конкретный токен, его pdb-потроха получить не проблема.
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re[2]: И ещё в догонку: isymwrapper.dll
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.09.06 00:15
Оценка:
Здравствуйте, IT, Вы писали:

IT>Лишних референсов плодить не желательно.


От тут я не согласен. Ссылку на сборку из фрэймворка можно давать без каких либо проблем. Это лучше чем копипэст. Вот если это левая сборка или ради одного интерфейса, то другое дело.

IT>Я не нашёл как получить местонахождение класса и не понятно что делать, если имеется несколько методов с одним названием. Выдается толи первый, толи последний попавшийся.


Кстати, переходы к коду проекта тоже работают не верно в случае если клас partial. Переход осуществляется к первой сканированной части, а это не верно. В таких случаях надо выдавать диалок со списком файлов в которых распологаются части класса.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: И ещё в догонку: isymwrapper.dll
От: IT Россия linq2db.com
Дата: 20.09.06 00:56
Оценка:
Здравствуйте, VladD2, Вы писали:

IT>>Лишних референсов плодить не желательно.


VD>От тут я не согласен. Ссылку на сборку из фрэймворка можно давать без каких либо проблем. Это лучше чем копипэст. Вот если это левая сборка или ради одного интерфейса, то другое дело.


Это я чего-то тормознул. Мне показалось, что это сборка из SDK, которая может быть, а может и не может.

VD>Кстати, переходы к коду проекта тоже работают не верно в случае если клас partial. Переход осуществляется к первой сканированной части, а это не верно. В таких случаях надо выдавать диалок со списком файлов в которых распологаются части класса.


Переход осуществляется без затей по location. Так что править надо именно location для partial классов.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: И ещё в догонку: isymwrapper.dll
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.09.06 01:37
Оценка:
Здравствуйте, IT, Вы писали:

IT>Переход осуществляется без затей по location. Так что править надо именно location для partial классов.


Ты не те локейшоны берешь. И править там ничего не надо. Я же правильно нахожу функцию?

Там (в классе TypeBuilder) есть список локейшонов (PartsLocation) для разных файлов. Вот из них и нужно делать список если их более одной штуки.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: И ещё в догонку: isymwrapper.dll
От: IT Россия linq2db.com
Дата: 20.09.06 01:43
Оценка:
Здравствуйте, VladD2, Вы писали:

IT>>Переход осуществляется без затей по location. Так что править надо именно location для partial классов.


VD>Ты не те локейшоны берешь. И править там ничего не надо. Я же правильно нахожу функцию?

VD>Там (в классе TypeBuilder) есть список локейшонов (PartsLocation) для разных файлов. Вот из них и нужно делать список если их более одной штуки.

Подожди. Каждый IMember имеет location в котором он определён. Что тут не правильно?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: И ещё в догонку: isymwrapper.dll
От: Блудов Павел Россия  
Дата: 20.09.06 02:32
Оценка:
Здравствуйте, IT, Вы писали:

IT>Подожди. Каждый IMember имеет location в котором он определён. Что тут не правильно?

Полагаю, Влад имеет ввиду, что если есть partial class MyClass, то при нажатии F12 вот в таком месте
MyClass a = new MyClass();
// ^= курсор тут.


Нужно уведомить пользователя, что MyClass состоит из n кусков и предложить выбрать. Интересная тема — исключить из списка генерируемые файлы типа MyClass.designer.cs
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re[7]: И ещё в догонку: isymwrapper.dll
От: IT Россия linq2db.com
Дата: 20.09.06 03:16
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

IT>>Подожди. Каждый IMember имеет location в котором он определён. Что тут не правильно?

БП>Полагаю, Влад имеет ввиду, что если есть partial class MyClass, то при нажатии F12 вот в таком месте

А как студия поступает в данном случае?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[8]: И ещё в догонку: isymwrapper.dll
От: Блудов Павел Россия  
Дата: 20.09.06 03:46
Оценка:
Здравствуйте, IT, Вы писали:

IT>А как студия поступает в данном случае?

ReSharper вываливает DropDown "Choose Declaration" с полным списком .cs файлов, в которых имеется этот класс.

Сама студия кажет окошко "Find Symbol Results". Тоже со всеми файлами включая .designer.cs
... << RSDN@Home 1.2.0 alpha rev. 642>>
Поравочка
От: Блудов Павел Россия  
Дата: 10.10.06 06:10
Оценка:
Вместо
                            ISymbolDocument[] documents  = new ISymbolDocument[1];
                            int[]             lines      = new int[1];
                            int[]             columns    = new int[1];
                            int[]             endLines   = new int[1];
                            int[]             endColumns = new int[1];

                            method.GetSequencePoints(null, documents, lines, columns, endLines, endColumns);

следует читать
                            ISymbolDocument[] documents  = new ISymbolDocument[1];
                            int[]             offsets    = new int[1];
                            int[]             lines      = new int[1];
                            int[]             columns    = new int[1];
                            int[]             endLines   = new int[1];
                            int[]             endColumns = new int[1];

                            method.GetSequencePoints(offsets, documents, lines, columns, endLines, endColumns);


Иначе студия тупо стреляется.
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re: Готов переход к исходнику при наличии pdb.
От: ie Россия http://ziez.blogspot.com/
Дата: 10.10.06 06:16
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>А тут нет:

БП>
Main() : void
БП>{
БП>    printf("Hi!");
БП>}

БП>потому что Nemerle.IO.printf почему-то распознаётся как System.Console.Write() Причём в QuickTip тоже имеем System.Console.Write. Кто виноват и что делать

Дык, printf — макрос. Он в итоге раскрывается в System.Console.Write(). Так что тут надо как-то колдовать с тем, что мы имеем до расскрытия макроса, а не с финальным кодом.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Превратим окружающую нас среду в воскресенье.
Re: Поравочка
От: ie Россия http://ziez.blogspot.com/
Дата: 10.10.06 06:17
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Вместо

...
БП>Иначе студия тупо стреляется.

Прислал бы svn-овский патч и делов
... << RSDN@Home 1.2.0 alpha rev. 0>>
Превратим окружающую нас среду в воскресенье.
Re[2]: Поравочка
От: Блудов Павел Россия  
Дата: 10.10.06 07:12
Оценка:
Здравствуйте, ie, Вы писали:

ie>Прислал бы svn-овский патч и делов

Не, у меня куча LF поменялись на CR-LF, пока я разобрался что к чему. Так что лучше так. Потом сделаю Revert всего и заберу новую версию.
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re: Готов переход к исходнику при наличии pdb.
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.06 17:24
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>

Known issues

БП>Вот тут работает:
БП>
БП>m() : Nemerle.TailRecursionTransparentAttribute
БП>{
БП>    def i = Nemerle.TailRecursionTransparentAttribute(true);
БП>    i;
БП>}
БП>

БП>А тут нет:
БП>
Main() : void
БП>{
БП>    printf("Hi!");
БП>}

БП>потому что Nemerle.IO.printf почему-то распознаётся как System.Console.Write() Причём в QuickTip тоже имеем System.Console.Write. Кто виноват и что делать

Все верно. Nemerle.IO.printf — это макрос который на самом деле может раскрыть намного более сложным образом. Тут нужно более сложный анализ производить. Если удастся получить хотя бы ссылу на сборку где объявлен Nemerle.IO.printf, то дальше все что нужно можно будет вытащить из метаданных.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Поравочка
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.06 17:24
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

ie>>Прислал бы svn-овский патч и делов

БП>Не, у меня куча LF поменялись на CR-LF, пока я разобрался что к чему. Так что лучше так. Потом сделаю Revert всего и заберу новую версию.

А не проще ли просто подключиться к проекту?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Поравочка
От: IT Россия linq2db.com
Дата: 10.10.06 21:40
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А не проще ли просто подключиться к проекту?


Он стеснятеся.
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Поравочка
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.06 21:44
Оценка:
Здравствуйте, IT, Вы писали:

IT>Он стеснятеся.


Надо устранять этот недостаток .
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Поравочка
От: Блудов Павел Россия  
Дата: 11.10.06 00:22
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Надо устранять этот недостаток .

Да не стесьняюсь я. Просто тормоз. Не могу въехать в эту полу-юинксовую полу-виндовую систему.

Половина файлов (немерловые) в одних LF'ах, другая половина CR/LF. Одни с пробелами другие с табами. Третьи вперемешку
Вавилон короче. В таких условиях лучше применять модерируемые коммиты.

Разводить флейм на тему "давайте обсудим стиль" я тем более не хочу. Точить некогда — копать нада.
Вобщем меня пока текущее положение устраивает. Вот если вам с Игорем обременительно с патчами возиться так и говорите. Буду подключаться.
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re[2]: Готов переход к исходнику при наличии pdb.
От: Блудов Павел Россия  
Дата: 11.10.06 00:24
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Все верно. Nemerle.IO.printf — это макрос который на самом деле может раскрыть намного более сложным образом. Тут нужно более сложный анализ производить. Если удастся получить хотя бы ссылу на сборку где объявлен Nemerle.IO.printf, то дальше все что нужно можно будет вытащить из метаданных.


Понял. Буду копать. QuickTip тоже нужно доработать?
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re[7]: Поравочка
От: IT Россия linq2db.com
Дата: 11.10.06 01:08
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Вот если вам с Игорем обременительно с патчами возиться так и говорите. Буду подключаться.


Не так чтобы сильно обременительно, но лучше подключайся.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[7]: Поравочка
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.10.06 01:59
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Здравствуйте, VladD2, Вы писали:


VD>>Надо устранять этот недостаток .

БП>Да не стесьняюсь я. Просто тормоз. Не могу въехать в эту полу-юинксовую полу-виндовую систему.

А можно просто MSBuild-ом пользоваться. Могу прислать улучшенные cmd-хт. Хотя что там слать. Вот сейчас и выложу:
Build.cmd (двух-проходная компиляция. Позволяет компилировать и проверять макросы в компиляторе)
@echo on

IF "%Type%"=="" set Type=Debug

@echo ### Backup initials boot files #########################
IF EXIST boot\old\ RMDIR /S /Q boot\old

MKDIR boot\old\

IF errorlevel 1 goto Error
copy /Y boot\*.dll boot\old
IF errorlevel 1 goto Error
copy /Y boot\*.exe boot\old
IF errorlevel 1 goto Error
copy /Y boot\*.pdb boot\old

@echo !!! Backup success !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

@echo ### Phase 1 ############################################
MSBuild Nemerle.sln /p:Configuration=%Type%

IF errorlevel 1 goto Error
@echo !!! Phase 1 success !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

@echo ### Phase 2 ############################################
@echo ### Copy new binaries to boot
copy /Y bin\%Type%\*.dll boot
IF errorlevel 1 goto Error
copy /Y bin\%Type%\*.exe boot
IF errorlevel 1 goto Error
copy /Y bin\%Type%\*.pdb boot
@echo !!! Copy success!

@echo ### Build solution (phase 2)
MSBuild Nemerle.sln /p:Configuration=%Type%
IF errorlevel 1 goto Error
@echo !!! Build solution (phase 2) success!

copy /Y bin\%Type%\*.dll boot
IF errorlevel 1 goto Error
copy /Y bin\%Type%\*.exe boot
IF errorlevel 1 goto Error
copy /Y bin\%Type%\*.pdb boot

@echo !!! Phase 2 success !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
goto Success

@echo Phase 1 failed!
goto Error

:Error
@echo !!! Build FAILED !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
copy /Y boot\old\*.dll boot
copy /Y boot\old\*.exe boot
copy /Y boot\old\*.pdb boot
pause
exit /b 1

:Success


Reg.cmd (копирование в инсталляционную директорию и пре-джит)
rem @echo off

IF "%Type%"=="" set Type=Debug

set NemerleBin=D:\MyProjects\Nemerle\nemerle\bin\%Type%
set GacUtil=C:\VS\VS2005\SDK\v2.0\Bin\gacutil.exe
set NemerleInstall=%ProgramFiles%\Nemerle
set NGen=%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\ngen.exe

@echo NemerleInstall=%NemerleInstall%
@echo GacUtil=%GacUtil%
@echo NGen=%GacUtil%
@echo NemerleBin=%GacUtil%

@echo GacUtil=%GacUtil%
@echo NGen=%GacUtil%
@echo NemerleBin=%GacUtil%

cd /D %NemerleInstall%

%GacUtil% /u Nemerle
%GacUtil% /u Nemerle.Compiler
%GacUtil% /u Nemerle.MSBuild.Tasks
%GacUtil% /u Nemerle.Macros

%NGen% uninstall "%NemerleInstall%\Nemerle.dll"
%NGen% uninstall "%NemerleInstall%\Nemerle.Compiler.dll"
%NGen% uninstall "%NemerleInstall%\Nemerle.Macros.dll"
%NGen% uninstall "%NemerleInstall%\Nemerle.MSBuild.Tasks.dll"
%NGen% uninstall "%NemerleInstall%\ncc.exe"

@echo errorlevel=%errorlevel%
set errorlevel=0
@echo errorlevel=%errorlevel%

copy /Y "%NemerleBin%\*.dll" "%NemerleInstall%\*.dll"

if not errorlevel 0 (
@echo errorlevel=%errorlevel%
@echo !!! ERORR: copy files !!!
pause
exit /b 1
)

copy /Y "%NemerleBin%\*.exe" "%NemerleInstall%\*.exe"

if not errorlevel 0 (
@echo !!! ERORR: copy files !!!
pause
exit /b 1
)

copy /Y "%NemerleBin%\*.pdb" "%NemerleInstall%\*.pdb"

%NGen% install "%NemerleInstall%\Nemerle.dll"
%NGen% install "%NemerleInstall%\Nemerle.Compiler.dll"
%NGen% install "%NemerleInstall%\Nemerle.Macros.dll"
%NGen% install "%NemerleInstall%\Nemerle.MSBuild.Tasks.dll"
%NGen% install "%NemerleInstall%\ncc.exe"

pause


BuildAndReg.cmd (вызывает оба файла за раз)
@echo on

IF "%Type%"=="" set Type=Debug

call Build.cmd

@echo ERRORLEVEL

IF NOT ERRORLEVEL 1 call Reg.cmd


БП>Половина файлов (немерловые) в одних LF'ах, другая половина CR/LF. Одни с пробелами другие с табами. Третьи вперемешку


На самом деле в проекте компилятора (в SVN-е) стоит опция конвертации всего к LF. А в проекте интеграции просто ничего не задано. Можно в приципе тоже что-то задать.

БП>Вавилон короче. В таких условиях лучше применять модерируемые коммиты.


Ну, тебя. На то SVN и существует, чтобы можно было работать вместе. Если что всегда можно откатить что-нибудь.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Готов переход к исходнику при наличии pdb.
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.10.06 01:59
Оценка:
Здравствуйте, Блудов Павел, Вы писали:


VD>>Все верно. Nemerle.IO.printf — это макрос который на самом деле может раскрыть намного более сложным образом. Тут нужно более сложный анализ производить. Если удастся получить хотя бы ссылу на сборку где объявлен Nemerle.IO.printf, то дальше все что нужно можно будет вытащить из метаданных.


БП>Понял. Буду копать. QuickTip тоже нужно доработать?


А он макросы как раз умеет раскрывать. Он их в развернутом виде показывает. То есть то что будет после их раскрытия.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Поравочка
От: Nuald Россия http://nuald.blogspot.com
Дата: 11.10.06 02:28
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А можно просто MSBuild-ом пользоваться. Могу прислать улучшенные cmd-хт. Хотя что там слать. Вот сейчас и выложу:

VD>Build.cmd (двух-проходная компиляция. Позволяет компилировать и проверять макросы в компиляторе)

Может выложить его в SVN? А чтобы пути не менять, в начале коммандного файла сделать проверки, и выдавать соответствующее предупреждение?
Ты можешь просто залить, а остальные проверки я могу уже сам дописать, если у тебя времени нет
P.S. Правда у меня и самого сейчас времени нифига нет, но может на следующей неделе ситуация поменяется.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Готов переход к исходнику при наличии pdb.
От: Блудов Павел Россия  
Дата: 11.10.06 04:19
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А он макросы как раз умеет раскрывать. Он их в развернутом виде показывает. То есть то что будет после их раскрытия.


Угу. После раскрытия IO.Printf получается Console.Write. Соответственно переход будет к Console.Write, а не к нужному исходнику.
... << RSDN@Home 1.2.0 alpha rev. 642>>
А дальше?
От: Блудов Павел Россия  
Дата: 13.10.06 01:21
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Если есть .pdb-хи и исходники, то желательно бы позиционироваться на исходники, а не генерировать фэйк-код. Так, например, для исходников компилятора и библиотеки Немерла хотелось бы прыгать на них.


А если пользователь на этом не успокоится? Вот открылся исходник класса из ncc, а пользователь опять F12 давит.
Проблема в том, что открывшийся файл будет сам по себе, без ансамбля, т.е. без проекта. И в pdb о проекте ни слова.

Можно, как вариант, ассоциировать такие фалйы с проектом, из которого в них попадаешь.
Тогда если имеется програмка, использующая SomeAssembly, то при попадании в исходник SomeAssembly можно будет осуществлять переходы внутри SomeAssembly.

Другой вариант: для таких файлов-изгоев можно заводить виртуальный проект, у которого нет исходников вообще, но зато есть нетовая сборка и следовательно все нужные метаданные. Тогда можно будет даже осуществлять переходы на исходники сборок, на которые ссылается та сборка. До бесконечости.
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re: А дальше?
От: Nuald Россия http://nuald.blogspot.com
Дата: 13.10.06 01:39
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Другой вариант: для таких файлов-изгоев можно заводить виртуальный проект, у которого нет исходников вообще, но зато есть нетовая сборка и следовательно все нужные метаданные. Тогда можно будет даже осуществлять переходы на исходники сборок, на которые ссылается та сборка. До бесконечости.


Почему же до бесконечности? VS поступает довольно-таки просто — если в текущем solution есть сборка с исходниками, то она показывает их, а иначе — только метаинформацию (обычно публичный интерфейс). Не писать же аналог рефлектора
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: А дальше?
От: Блудов Павел Россия  
Дата: 13.10.06 07:24
Оценка:
Здравствуйте, Nuald, Вы писали:

N>Почему же до бесконечности? VS поступает довольно-таки просто — если в текущем solution есть сборка с исходниками, то она показывает их, а иначе — только метаинформацию (обычно публичный интерфейс). Не писать же аналог рефлектора

Читай ветку чуть выше. Влад предложил идею по-лучше: показывать реальный исходник если есть pdb и исходник в наличии.
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re[3]: А дальше?
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.10.06 01:27
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Читай ветку чуть выше. Влад предложил идею по-лучше: показывать реальный исходник если есть pdb и исходник в наличии.


На самом деле одна идея другую не отменяет. Исходники в проекте одного солюшена надо обрабатывать особо. Нито переходы будут работать корректно только после компиляции солюшена.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Готов переход к исходнику при наличии pdb.
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.10.06 15:26
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Угу. После раскрытия IO.Printf получается Console.Write. Соответственно переход будет к Console.Write, а не к нужному исходнику.


Ну, так надо не тупо раскрывать, а смотреть что там. IT для хинтов в локальных проектах это делает и получается то что нужно.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Поравочка
От: VladD2 Российская Империя www.nemerle.org
Дата: 15.10.06 22:20
Оценка:
Здравствуйте, Nuald, Вы писали:

N>Может выложить его в SVN? А чтобы пути не менять, в начале коммандного файла сделать проверки, и выдавать соответствующее предупреждение?


Класть в SVN что-то с фиксированными путями нельзя. Файл для компиляции конечно можно положить, но для регистрации прийдется что-то придумывать.

N>Ты можешь просто залить, а остальные проверки я могу уже сам дописать, если у тебя времени нет


Давай лучше наоборот. Правь и присылай. Я оценю и решу можно ли его заливать в таком виде.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Поравочка
От: Блудов Павел Россия  
Дата: 16.10.06 04:35
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Класть в SVN что-то с фиксированными путями нельзя.

если ты про это:
set NemerleBin=D:\MyProjects\Nemerle\nemerle\bin\%Type%
set NemerleInstall=%ProgramFiles%\Nemerle
set GacUtil=C:\VS\VS2005\SDK\v2.0\Bin\gacutil.exe
set NGen=%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\ngen.exe


То можно первый можно сделать относительным, просто положив Build.cmd в нужное место. Для остальных требовать наличия переменных окружения.
В итоге должно получиться:
set NemerleBin=%~dp0\bin\%Type%
set NemerleInstall=%ProgramFiles%\Nemerle
set GacUtil=gacutil.exe
set NGen=ngen.exe


Ниличие пути до gacutil.exe и ngen.exe можно вычислить:
%GacUtil% > nul
if errorlevel 2 echo gacutil.exe not found && exit
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re[10]: Поравочка
От: Nuald Россия http://nuald.blogspot.com
Дата: 18.10.06 00:38
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Давай лучше наоборот. Правь и присылай. Я оценю и решу можно ли его заливать в таком виде.


Положив три файла (BuildAndReg.cmd, build.cmd, reg.cmd) в корень каталога Nemerle (у меня D:\Work\Nemerle) и подправив reg.cmd следующим образом:
set NemerleBin=%~dp0\bin\%Type%
set GacUtil="%VS80COMNTOOLS%\..\..\SDK\v2.0\Bin\gacutil.exe"
set NemerleInstall=%ProgramFiles%\Nemerle
set NGen=%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\ngen.exe

@echo NemerleInstall=%NemerleInstall%
@echo GacUtil=%GacUtil%
@echo NGen=%NGen%
@echo NemerleBin=%NemerleBin%

%GacUtil% > nul
if errorlevel 2 echo gacutil.exe not found. && pause && exit

Знаю, что завязываться на %VS80COMNTOOLS% не очень хорошо, однако ИМХО это единственное решение, не заставляющее пользователя вводить путь к .NET 2 SDK ручками.

В принципе, у меня все заработало, и завязок на какие-то абсолютные пути вроде бы не наблюдается.
Пойдет? Коммитить?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[11]: Поравочка
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.10.06 00:48
Оценка:
Здравствуйте, Nuald, Вы писали:

До этого:
N>
N>set GacUtil="%VS80COMNTOOLS%\..\..\SDK\v2.0\Bin\gacutil.exe"
N>

я уже и сам додумался.

А что вот это:
N>[code]
N>set NemerleBin=%~dp0\bin\%Type%
N>[/code]


N>Знаю, что завязываться на %VS80COMNTOOLS% не очень хорошо, однако ИМХО это единственное решение, не заставляющее пользователя вводить путь к .NET 2 SDK ручками.


Согласен.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Поравочка
От: Nuald Россия http://nuald.blogspot.com
Дата: 18.10.06 23:32
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А что вот это:

VD>
N>>[code]
N>>set NemerleBin=%~dp0\bin\%Type%
N>>[/code]
VD>


~dp0 возвращает рабочий каталог исполняемого командного файла.

N>>Знаю, что завязываться на %VS80COMNTOOLS% не очень хорошо, однако ИМХО это единственное решение, не заставляющее пользователя вводить путь к .NET 2 SDK ручками.


VD>Согласен.


Ну еще, конечно, можно потребовать у конечного пользователя прописать Path или какую-то другую переменную окружения и ее использовать. Тогда в начале надо будет проверить путь, и предупредить пользователя. Ну либо вообще сделать что-то типа грязного хака — извлечь из реестра всю нужную информацию (например, путь к devenv.exe или считывать внутренние переменные студии) и плясать от них.

Как бы то не было, более или менее командные файлы готовы, можно коммитить. Скажешь, сделаю, либо уже ты сам. Ну а если не надо, то не надо, мое дело предложить
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[13]: Поравочка
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.10.06 01:14
Оценка:
Здравствуйте, Nuald, Вы писали:

N>~dp0 возвращает рабочий каталог исполняемого командного файла.


N>Как бы то не было, более или менее командные файлы готовы, можно коммитить. Скажешь, сделаю, либо уже ты сам. Ну а если не надо, то не надо, мое дело предложить


У меня уже немного доработанный файл. Сейчас просто проблем по работе много. На днях закомичу.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Готов переход к исходнику при наличии pdb.
От: Блудов Павел Россия  
Дата: 19.10.06 08:03
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ну, так надо не тупо раскрывать, а смотреть что там. IT для хинтов в локальных проектах это делает и получается то что нужно.

А ничего там. CallExpr с именем "printf" и Body = "System.Console.Write"
Вот такой расклад я сделал:

when(true)
  printf("Hi!");


При нажатии F12 на when осуществляется переход на Nemerle\macros\core.n
но для этого пришлось притянуть за уши System.Reflection, т.к. IMacro не наследуется от IMember и вообще не имеет чего-либо похожего на Location.
Я закинул как есть, кто знает как сделать правильно пусть меня поправит.
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re[7]: Готов переход к исходнику при наличии pdb.
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.10.06 14:36
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>А ничего там. CallExpr с именем "printf" и Body = "System.Console.Write"

БП>Вот такой расклад я сделал:

БП>
БП>when(true)
БП>  printf("Hi!");
БП>


БП>При нажатии F12 на when осуществляется переход на Nemerle\macros\core.n

БП>но для этого пришлось притянуть за уши System.Reflection, т.к. IMacro не наследуется от IMember и вообще не имеет чего-либо похожего на Location.
БП>Я закинул как есть, кто знает как сделать правильно пусть меня поправит.

Еще раз повторяю. Погляди то как IT сделал вывод хинтов для макросов. Посоветуйся с ним. Он там все что нужно вынимает. Процесс это не простой, но вполне осуществимый.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.