Переход к объектам текущего проекта уже работает, в кишках компилятора сильно копаться не надо. Нужно сделать переход к объектам, которые находятся во внешних модулях. В качестве примера:
"".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>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>В этом файле конструкторы принимают объекты и устанавливают Location, если после этого свойство класса HasLocation == false, то нужно посмотреть что у нас за объект и сгенертровать для него файл как это делает студия для C#.
Если есть .pdb-хи и исходники, то желательно бы позиционироваться на исходники, а не генерировать фэйк-код. Так, например, для исходников компилятора и библиотеки Немерла хотелось бы прыгать на них.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, 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? чесно говоря не представляю как такое можно сделать....перелопачивать в лоб? тупо и на долго....
Может быть подскажите в каком направлении копать?
Здравствуйте, 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), есть ли для этого какието штатные средства?
Или есть иные средства кодо генераци?
Или предпологаетс тупо в лоб нарубать файл выдергивая значения руками?
Наверное я задаю моного глупых вопросов, но документации ни по компилятору ни по плагину нет, так что единственный способ что то узнать это либо пытать более опытных товарищей либо биться об стену самому.... Надеюсь я не слишком парю
Здравствуйте, robot01, Вы писали:
R>Потратил несколько часов на знакомство с поставленной вами задачей. R>Честно говоря нормального пути решения я не увидил (не нормальный путь это тупо сгенерировать файл с помощью String.Format).
R>Нормальный путь для решения сей задачи это: использовать NemerleCodeProvider и с помошью него сгенерить файл.
Будут проблемы. CodeDomProvider рассчитан на усредненный язык. В этом языке как минимум нет таких понятий как variant-ы. К тому же нет путей посторить CodeDom по сборке. Это прийдется делать вручную. А раз так, то не вижу особого смысла в промежеточном коде.
string.Format тоже не лучший инструмент. Нут нужно генерировать текст. Для этого лучше всего подходят нековые строковые шаблонные движки. Например, StringTemplate или XSLT. В принципе немерловые сплайсет-строки очень похожи на эти движки, но я бы их немного доработал. Так нужна поддержка вложенности (отступы).
R>Все бы хорошо но кодпровайдер хочет стандартные классы из CodeDom, а все что я могу получить это Nemerle.Compiler.TypeInfo, что с этим классом делать ума не пролижу, переколбасить в CodeTypeDeclaration? чесно говоря не представляю как такое можно сделать....перелопачивать в лоб? тупо и на долго.... R>Может быть подскажите в каком направлении копать?
Мне кажется нужно используя TypeInfo генерировать код на базе строковых шаблонов. В общем-то это не сложно если делать с гловой. Надо создать по шаблону жля каждого элемнта (класса, структуры, метода, свойства...) и вызвать их рекурсивно. Например, шаблон для класса может выглядить так:
Class:
Здравствуйте, Аноним, Вы писали:
А>Я на него и смотрю, у него тип Nemerle.Compiler.TypeInfo (на сколько я понял это класс описывающий тип со специфичными для немерле условиям). Ворос вот в чем: что бы с ним можно было работать средствами CodeProvider`а нужно привести его к типу CodeTypeDeclaration (из CodeDom), есть ли для этого какието штатные средства?
С CodeProvider не слишком сложно получится?
А>Или есть иные средства кодо генераци?
TypeInfo сам уже умеет кое что показывать. Может быть его ToString вполне подойдёт.
А>Или предпологаетс тупо в лоб нарубать файл выдергивая значения руками?
Можно и нарубать. Ты попробуй, а там видно будет. За последующий рефакторинг/переделки ругать никто не будет
А>Наверное я задаю моного глупых вопросов, но документации ни по компилятору ни по плагину нет, так что единственный способ что то узнать это либо пытать более опытных товарищей либо биться об стену самому.... Надеюсь я не слишком парю
Не слишком. Я прежде чем начать что-то делать Влада по телефону часа четыре парил.
Если нам не помогут, то мы тоже никого не пощадим.
Ещё хорошо бы не обновлять файлы на диске в случае ненадобности. А то студия может начать задавать глупые вопросы про файл изменился, бла-бла-бла. Так же студия умеет писать рядом с именем таких файлов [from metadata]. Тоже не понятно как это сделать. Хотя может они по имени каталога как-то вычисляют. У меня оно такое — C:\Temp\4040$CommonLanguageRuntimeLibrary$v2.0.50727
В общем, надо разбираться.
Если нам не помогут, то мы тоже никого не пощадим.
Возник еще вопрос: захотелось мне написать тесты ко всему этому добру но напоролся на проблему, самому создать объект типа TypeInfo почти не реально (куча гемора с зависимыми объектами и прочее), мокать тоже как то грустно, какие есть варианты?
Здравствуйте, robot01, Вы писали:
R>Возник еще вопрос: захотелось мне написать тесты ко всему этому добру но напоролся на проблему, самому создать объект типа TypeInfo почти не реально (куча гемора с зависимыми объектами и прочее), мокать тоже как то грустно, какие есть варианты?
Здравствуйте, 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 (ну или дерево или не важно чего главное что бы я мог извлечь от туда информацию о типах описанных мною в файле) а я потом мог с помошью этого прогнать юнит тесты.
Здравствуйте, 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>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, 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
WTF? С NUnit-ом еще более или менее понятно (хотя тесты из Nemerle.VsIntegration.Tests почему-то все Failed), то с ConsoleTest хотелось бы поближе разобраться, учитывая что он "удобен для отладки".
Здравствуйте, 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 укажи путь:
естествнно начальная часть будет твоя.
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>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Что касается NUnit, то он прекрасен для быстрой проверки, но отладку из него не сделашь. Именно по этому появился ConsoleTest.
VD>Идея его очень проста. Он позволяет запустить юнит-тесты из под отладчика (как обычные методы) и поглядеть что не ладно в датском королевстве. Он тупо загружает сборку Nemerle.Compiler.Utils.dll, создает класс Tests.Test1 и дергает его методы.
Сорри, что встреваю, а что не так с NUnit при запуске тестов на отладку?
Здравствуйте, VladD2, Вы писали:
VD>Само сообщение говорит о том, что нужно делать.
Хм, сообшение об этом ничего не говорит, по-крайней мере, для непосвященного. В мире всеобщей рефлексии и эмита какой бы не был текст ошибки, нельзя сделать никакие выводы, предварительно не отладив тонны кода
VD>Зайди в настройке проекта и на закладке Debug, в поле Working Directory укажи путь: VD>
Думаю, проще было бы добавить такую проверку (или даже автоматическую настройку), чтобы люди не пугались, и не задавали глупые вопросы. Потом сделаю, но как только разберусь со следующей ошибкой — я запускаю ConsoleTest и у меня вылетает assert в Nemerle.Compiler.Utils\Nemerle.Completion2\Tests\Tests.n, line 55, "result is null", т.е. строчка
выдает 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;}
}
}
}
Здравствуйте, <Аноним>, Вы писали:
А>Есть простой класс (листинг ниже) строю по мему 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>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, VladD2, Вы писали:
V>>Сорри, что встреваю, а что не так с NUnit при запуске тестов на отладку?
VD>GUI которое на фиг не упало.
Есть же консольный test-runner, стартует действительно, на пол-секунды быстрее, а во вторых есть удобный аттрибут Explicit, у нас тесты и фикстуры помечены им, кроме тех, которые должны отрабатывать всегда без принудительного запуска. Для твоего сценария надо просто убирать этот аттрибут из теста, который ты намереваешься многократно гонять в дебаге. Как раз получишь минимум движений. Для GUI test-runnera все в силе, когда запускается с опцией автоматического прогона тестов (т.е. телодвижений ничуть не больше), но раздельный вывод информации мне тоже нравится больше.
Здравствуйте, IT, Вы писали:
IT>Я имею ввиду чтр если побраузить объект в Quick Watch? Может у него данные в каком-нибудь другом месте лежать.
хммм в принципе объект с которым я работаю это FieldBuilder и у него есть внутреннее поле ty, где лежит все что нужно, НО я не уверен что приводить IField к FieldBuilder корректно... и еще я не уверен что ty будет заполняться если мы будем рабоать через рефликсию и не напряму парсить файл.... вообще очень много но....
Здравствуйте, robot01, Вы писали:
R>хммм в принципе объект с которым я работаю это FieldBuilder и у него есть внутреннее поле ty, где лежит все что нужно, НО я не уверен что приводить IField к FieldBuilder корректно... и еще я не уверен что ty будет заполняться если мы будем рабоать через рефликсию и не напряму парсить файл.... вообще очень много но....
Корректно. IField, как и другие интерфейсы наследники IMember, это общая информация о члене независящая от того является ли он членом класса импортированного из другой сборки или членом класса распознанным из кода. Но реализуются они разыми типами. Для распозного из кода члена всегда выступает какй-то Builder (для поля FieldBuilder, для метода MethodBuilder, и т.п.).
Вот только нужно не "приводить", а пользоваться паттерн-матчингом. Чтобы не грохнуло, если все же член импортирован из другой сборки.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, vdimas, Вы писали:
V>Есть же консольный test-runner, стартует действительно, на пол-секунды быстрее, а во вторых есть удобный аттрибут Explicit, у нас тесты и фикстуры помечены им, кроме тех, которые должны отрабатывать всегда без принудительного запуска. Для твоего сценария надо просто убирать этот аттрибут из теста, который ты намереваешься многократно гонять в дебаге. Как раз получишь минимум движений. Для GUI test-runnera все в силе, когда запускается с опцией автоматического прогона тестов (т.е. телодвижений ничуть не больше), но раздельный вывод информации мне тоже нравится больше.
Ладно. В следующий раз разбирусь. Пока просто в лом дергаться. Все работает...
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Корректно. IField, как и другие интерфейсы наследники IMember, это общая информация о члене независящая от того является ли он членом класса импортированного из другой сборки или членом класса распознанным из кода. Но реализуются они разыми типами. Для распозного из кода члена всегда выступает какй-то Builder (для поля FieldBuilder, для метода MethodBuilder, и т.п.).
VD>Вот только нужно не "приводить", а пользоваться паттерн-матчингом. Чтобы не грохнуло, если все же член импортирован из другой сборки.
Я собственно догадался об это, вопрос заключался не в том какой тип за что отвечает первичный вопрос:Баг или еще не реализовано
Здравствуйте, robot01, Вы писали:
R>Я собственно догадался об это, вопрос заключался не в том какой тип за что отвечает первичный вопрос:Баг или еще не реализовано
Здравствуйте, VladD2, Вы писали:
VD>Ладно. В следующий раз разбирусь. Пока просто в лом дергаться. Все работает...
[Test, Explicit]
public void SomeTest() {}
[TestFixture, Explicit]
public class SomeTestFixture : OurBaseTestFixture {
}
Фикстуры и тесты, помеченные Explicit не запускаются автоматом, поэтому для многократного автоматического захода в некий тест мы убираем/комментируем Explicit и попадаем в тест автоматом при запуске.
Здравствуйте, Nuald, Вы писали:
N>Думаю, проще было бы добавить такую проверку (или даже автоматическую настройку), чтобы люди не пугались, и не задавали глупые вопросы. Потом сделаю, но как только разберусь со следующей ошибкой — я запускаю ConsoleTest и у меня вылетает assert в Nemerle.Compiler.Utils\Nemerle.Completion2\Tests\Tests.n, line 55, "result is null", т.е. строчка 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>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, robot01, Вы писали:
R>Нет вопрос не снят баг никуда не делся, а то что я описал (внутреннее поле ty) работет только для типов которые получаются разбором исходников.
Незнаю, поглядел код и не вижу проблемы.
IField унаследован от IMember. IMember имеет метод GetMemType(). Так что делаем так:
def tyInfo = member.GetMemType().TypeInfo;
и получаем универсальное описание для любого поля.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
N>>Хм, а чьи? Может тогда проще их удалить, если никто не поддерживает. В принципе, могу привести в работоспособное состояние, если нужно. VD>Относятся к работе с дизайнером формам. Я туда не лазил. Формы у меня тоже не работают. Но удалять ничего не надо. Пусть автор разбираетя или те кто потом будут заниматься дизайнером форм.
Я ничего удалять и не собираюсь, а наоборот, привести в работоспособное состояние. Посмотрю на досуге, как только разберусь с ConsoleTest.
N>>Мы как-то делали обработку графики, и там был такой стресс-тест — надо было загрузить большую-большую картинку и ее обработать без вылетов о нехватке памяти и уложиться в определенный интервал времени. Это было частью NUnit-теста и занимало около 4-5 минут VD>Это ваши проблемы. Я такой тест сразу грохну. Мне минуты компиляции компилятора уже выше крыши.
Ну понятно дело — тесты должны быть короткими. Хотя как вспомню CCNET от Фаулера и Ко, у них тесты-то маленькие, но их такая куча Впрочем, я не фанатик TDD, так что мне наверное не понять.
Здравствуйте, Nuald, Вы писали:
N>Я ничего удалять и не собираюсь, а наоборот, привести в работоспособное состояние. Посмотрю на досуге, как только разберусь с ConsoleTest.
Это пожалуйса. Главное чтобы не наоборот. Тут есть смысл с их автором пообщаться.
N>Ну понятно дело — тесты должны быть короткими. Хотя как вспомню CCNET от Фаулера и Ко, у них тесты-то маленькие, но их такая куча
Кучу можно отключить. А вот ждать когда закончится 1 длинный прийдется по любому.
N>Впрочем, я не фанатик TDD, так что мне наверное не понять.
Я тоже. И вообще разум рулит.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
N>выдает null (хотя все NUnit-тесты проходят нормально). По идее file должен находится и открываться (Working Dir в опциях проекта указан правильно). С чем это может быть связано?
Здравствуйте, Блудов Павел, Вы писали:
БП>Пробелов, случайно, нет в этом самом Working Dir?
Нет. Вообще, проблему я решил — слишком много было Nemerle.Compiler.dll по системе разбросано. По ходу, пока я разбирался со сборкой Немерле, NGen понаделал делов
Вобщем так. Метода ВотВамТокенДайтеИмяФайлаИСтрокуСтолбец() попросту нет. Дело в том, что метод в 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 на неё.
Если добавить 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; }
}
}
Здравствуйте, Блудов Павел, Вы писали:
БП>Если добавить reference на %SystemRoot%\Microsoft.Net\Framework\v2.0.50727\isymwrapper.dll, то можно ISymUnmanagedXXXX не использовать, там вполне нормальные врапперы на c#:
Лишних референсов плодить не желательно.
Я не нашёл как получить местонахождение класса и не понятно что делать, если имеется несколько методов с одним названием. Выдается толи первый, толи последний попавшийся.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Я не нашёл как получить местонахождение класса и не понятно что делать, если имеется несколько методов с одним названием. Выдается толи первый, толи последний попавшийся.
Я так понял, если есть сигнатура метода и известно, в какой сборке он живёт, то нет проблем получить его metadata token. Хоть через рефлексию, хоть через IMetaDataImport (первое явно сделано через второе). Ну а имея конкретный токен, его pdb-потроха получить не проблема.
Здравствуйте, IT, Вы писали:
IT>Лишних референсов плодить не желательно.
От тут я не согласен. Ссылку на сборку из фрэймворка можно давать без каких либо проблем. Это лучше чем копипэст. Вот если это левая сборка или ради одного интерфейса, то другое дело.
IT>Я не нашёл как получить местонахождение класса и не понятно что делать, если имеется несколько методов с одним названием. Выдается толи первый, толи последний попавшийся.
Кстати, переходы к коду проекта тоже работают не верно в случае если клас partial. Переход осуществляется к первой сканированной части, а это не верно. В таких случаях надо выдавать диалок со списком файлов в которых распологаются части класса.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
IT>>Лишних референсов плодить не желательно.
VD>От тут я не согласен. Ссылку на сборку из фрэймворка можно давать без каких либо проблем. Это лучше чем копипэст. Вот если это левая сборка или ради одного интерфейса, то другое дело.
Это я чего-то тормознул. Мне показалось, что это сборка из SDK, которая может быть, а может и не может.
VD>Кстати, переходы к коду проекта тоже работают не верно в случае если клас partial. Переход осуществляется к первой сканированной части, а это не верно. В таких случаях надо выдавать диалок со списком файлов в которых распологаются части класса.
Переход осуществляется без затей по location. Так что править надо именно location для partial классов.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, VladD2, Вы писали:
IT>>Переход осуществляется без затей по location. Так что править надо именно location для partial классов.
VD>Ты не те локейшоны берешь. И править там ничего не надо. Я же правильно нахожу функцию? VD>Там (в классе TypeBuilder) есть список локейшонов (PartsLocation) для разных файлов. Вот из них и нужно делать список если их более одной штуки.
Подожди. Каждый IMember имеет location в котором он определён. Что тут не правильно?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Подожди. Каждый IMember имеет location в котором он определён. Что тут не правильно?
Полагаю, Влад имеет ввиду, что если есть partial class MyClass, то при нажатии F12 вот в таком месте
MyClass a = new MyClass();
// ^= курсор тут.
Нужно уведомить пользователя, что MyClass состоит из n кусков и предложить выбрать. Интересная тема — исключить из списка генерируемые файлы типа MyClass.designer.cs
Здравствуйте, Блудов Павел, Вы писали:
IT>>Подожди. Каждый IMember имеет location в котором он определён. Что тут не правильно? БП>Полагаю, Влад имеет ввиду, что если есть partial class MyClass, то при нажатии F12 вот в таком месте
А как студия поступает в данном случае?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>А как студия поступает в данном случае?
ReSharper вываливает DropDown "Choose Declaration" с полным списком .cs файлов, в которых имеется этот класс.
Сама студия кажет окошко "Find Symbol Results". Тоже со всеми файлами включая .designer.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. Кто виноват и что делать
Здравствуйте, Блудов Павел, Вы писали:
БП>А тут нет: БП>
Main() : void
БП>{
БП> printf("Hi!");
БП>}
БП>потому что Nemerle.IO.printf почему-то распознаётся как System.Console.Write() Причём в QuickTip тоже имеем System.Console.Write. Кто виноват и что делать
Дык, printf — макрос. Он в итоге раскрывается в System.Console.Write(). Так что тут надо как-то колдовать с тем, что мы имеем до расскрытия макроса, а не с финальным кодом.
Здравствуйте, ie, Вы писали:
ie>Прислал бы svn-овский патч и делов
Не, у меня куча LF поменялись на CR-LF, пока я разобрался что к чему. Так что лучше так. Потом сделаю Revert всего и заберу новую версию.
БП>потому что Nemerle.IO.printf почему-то распознаётся как System.Console.Write() Причём в QuickTip тоже имеем System.Console.Write. Кто виноват и что делать
Все верно. Nemerle.IO.printf — это макрос который на самом деле может раскрыть намного более сложным образом. Тут нужно более сложный анализ производить. Если удастся получить хотя бы ссылу на сборку где объявлен Nemerle.IO.printf, то дальше все что нужно можно будет вытащить из метаданных.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Блудов Павел, Вы писали:
ie>>Прислал бы svn-овский патч и делов БП>Не, у меня куча LF поменялись на CR-LF, пока я разобрался что к чему. Так что лучше так. Потом сделаю Revert всего и заберу новую версию.
А не проще ли просто подключиться к проекту?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Надо устранять этот недостаток .
Да не стесьняюсь я. Просто тормоз. Не могу въехать в эту полу-юинксовую полу-виндовую систему.
Половина файлов (немерловые) в одних LF'ах, другая половина CR/LF. Одни с пробелами другие с табами. Третьи вперемешку
Вавилон короче. В таких условиях лучше применять модерируемые коммиты.
Разводить флейм на тему "давайте обсудим стиль" я тем более не хочу. Точить некогда — копать нада.
Вобщем меня пока текущее положение устраивает. Вот если вам с Игорем обременительно с патчами возиться так и говорите. Буду подключаться.
Здравствуйте, VladD2, Вы писали:
VD>Все верно. Nemerle.IO.printf — это макрос который на самом деле может раскрыть намного более сложным образом. Тут нужно более сложный анализ производить. Если удастся получить хотя бы ссылу на сборку где объявлен Nemerle.IO.printf, то дальше все что нужно можно будет вытащить из метаданных.
Понял. Буду копать. QuickTip тоже нужно доработать?
Здравствуйте, Блудов Павел, Вы писали:
БП>Здравствуйте, VladD2, Вы писали:
VD>>Надо устранять этот недостаток . БП>Да не стесьняюсь я. Просто тормоз. Не могу въехать в эту полу-юинксовую полу-виндовую систему.
А можно просто MSBuild-ом пользоваться. Могу прислать улучшенные cmd-хт. Хотя что там слать. Вот сейчас и выложу:
Build.cmd (двух-проходная компиляция. Позволяет компилировать и проверять макросы в компиляторе)
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>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>>Все верно. Nemerle.IO.printf — это макрос который на самом деле может раскрыть намного более сложным образом. Тут нужно более сложный анализ производить. Если удастся получить хотя бы ссылу на сборку где объявлен Nemerle.IO.printf, то дальше все что нужно можно будет вытащить из метаданных.
БП>Понял. Буду копать. QuickTip тоже нужно доработать?
А он макросы как раз умеет раскрывать. Он их в развернутом виде показывает. То есть то что будет после их раскрытия.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>А можно просто MSBuild-ом пользоваться. Могу прислать улучшенные cmd-хт. Хотя что там слать. Вот сейчас и выложу: VD>Build.cmd (двух-проходная компиляция. Позволяет компилировать и проверять макросы в компиляторе)
Может выложить его в SVN? А чтобы пути не менять, в начале коммандного файла сделать проверки, и выдавать соответствующее предупреждение?
Ты можешь просто залить, а остальные проверки я могу уже сам дописать, если у тебя времени нет
P.S. Правда у меня и самого сейчас времени нифига нет, но может на следующей неделе ситуация поменяется.
Здравствуйте, VladD2, Вы писали:
VD>А он макросы как раз умеет раскрывать. Он их в развернутом виде показывает. То есть то что будет после их раскрытия.
Угу. После раскрытия IO.Printf получается Console.Write. Соответственно переход будет к Console.Write, а не к нужному исходнику.
Здравствуйте, VladD2, Вы писали:
VD>Если есть .pdb-хи и исходники, то желательно бы позиционироваться на исходники, а не генерировать фэйк-код. Так, например, для исходников компилятора и библиотеки Немерла хотелось бы прыгать на них.
А если пользователь на этом не успокоится? Вот открылся исходник класса из ncc, а пользователь опять F12 давит.
Проблема в том, что открывшийся файл будет сам по себе, без ансамбля, т.е. без проекта. И в pdb о проекте ни слова.
Можно, как вариант, ассоциировать такие фалйы с проектом, из которого в них попадаешь.
Тогда если имеется програмка, использующая SomeAssembly, то при попадании в исходник SomeAssembly можно будет осуществлять переходы внутри SomeAssembly.
Другой вариант: для таких файлов-изгоев можно заводить виртуальный проект, у которого нет исходников вообще, но зато есть нетовая сборка и следовательно все нужные метаданные. Тогда можно будет даже осуществлять переходы на исходники сборок, на которые ссылается та сборка. До бесконечости.
Здравствуйте, Блудов Павел, Вы писали:
БП>Другой вариант: для таких файлов-изгоев можно заводить виртуальный проект, у которого нет исходников вообще, но зато есть нетовая сборка и следовательно все нужные метаданные. Тогда можно будет даже осуществлять переходы на исходники сборок, на которые ссылается та сборка. До бесконечости.
Почему же до бесконечности? VS поступает довольно-таки просто — если в текущем solution есть сборка с исходниками, то она показывает их, а иначе — только метаинформацию (обычно публичный интерфейс). Не писать же аналог рефлектора
Здравствуйте, Nuald, Вы писали:
N>Почему же до бесконечности? VS поступает довольно-таки просто — если в текущем solution есть сборка с исходниками, то она показывает их, а иначе — только метаинформацию (обычно публичный интерфейс). Не писать же аналог рефлектора
Читай ветку чуть выше. Влад предложил идею по-лучше: показывать реальный исходник если есть pdb и исходник в наличии.
Здравствуйте, Блудов Павел, Вы писали:
БП>Читай ветку чуть выше. Влад предложил идею по-лучше: показывать реальный исходник если есть pdb и исходник в наличии.
На самом деле одна идея другую не отменяет. Исходники в проекте одного солюшена надо обрабатывать особо. Нито переходы будут работать корректно только после компиляции солюшена.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Блудов Павел, Вы писали:
БП>Угу. После раскрытия IO.Printf получается Console.Write. Соответственно переход будет к Console.Write, а не к нужному исходнику.
Ну, так надо не тупо раскрывать, а смотреть что там. IT для хинтов в локальных проектах это делает и получается то что нужно.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Nuald, Вы писали:
N>Может выложить его в SVN? А чтобы пути не менять, в начале коммандного файла сделать проверки, и выдавать соответствующее предупреждение?
Класть в SVN что-то с фиксированными путями нельзя. Файл для компиляции конечно можно положить, но для регистрации прийдется что-то придумывать.
N>Ты можешь просто залить, а остальные проверки я могу уже сам дописать, если у тебя времени нет
Давай лучше наоборот. Правь и присылай. Я оценю и решу можно ли его заливать в таком виде.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, 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
Здравствуйте, 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 ручками.
В принципе, у меня все заработало, и завязок на какие-то абсолютные пути вроде бы не наблюдается.
Пойдет? Коммитить?
N>Знаю, что завязываться на %VS80COMNTOOLS% не очень хорошо, однако ИМХО это единственное решение, не заставляющее пользователя вводить путь к .NET 2 SDK ручками.
Согласен.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
~dp0 возвращает рабочий каталог исполняемого командного файла.
N>>Знаю, что завязываться на %VS80COMNTOOLS% не очень хорошо, однако ИМХО это единственное решение, не заставляющее пользователя вводить путь к .NET 2 SDK ручками.
VD>Согласен.
Ну еще, конечно, можно потребовать у конечного пользователя прописать Path или какую-то другую переменную окружения и ее использовать. Тогда в начале надо будет проверить путь, и предупредить пользователя. Ну либо вообще сделать что-то типа грязного хака — извлечь из реестра всю нужную информацию (например, путь к devenv.exe или считывать внутренние переменные студии) и плясать от них.
Как бы то не было, более или менее командные файлы готовы, можно коммитить. Скажешь, сделаю, либо уже ты сам. Ну а если не надо, то не надо, мое дело предложить
Здравствуйте, Nuald, Вы писали:
N>~dp0 возвращает рабочий каталог исполняемого командного файла.
N>Как бы то не было, более или менее командные файлы готовы, можно коммитить. Скажешь, сделаю, либо уже ты сам. Ну а если не надо, то не надо, мое дело предложить
У меня уже немного доработанный файл. Сейчас просто проблем по работе много. На днях закомичу.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Ну, так надо не тупо раскрывать, а смотреть что там. IT для хинтов в локальных проектах это делает и получается то что нужно.
А ничего там. CallExpr с именем "printf" и Body = "System.Console.Write"
Вот такой расклад я сделал:
when(true)
printf("Hi!");
При нажатии F12 на when осуществляется переход на Nemerle\macros\core.n
но для этого пришлось притянуть за уши System.Reflection, т.к. IMacro не наследуется от IMember и вообще не имеет чего-либо похожего на Location.
Я закинул как есть, кто знает как сделать правильно пусть меня поправит.
Здравствуйте, Блудов Павел, Вы писали:
БП>А ничего там. 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>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.