Поиск методов, удовлетворяющих условию
От: Oksana Gimmel http://oksana-gimmel.blogspot.com/
Дата: 23.06.10 11:45
Оценка:
У меня есть .NET сборка. Надо получить список статических методов в типах из этой сборки, в которых есть обращения к статическим полям. Как это быстрее и проще всего сделать?
asato ma sad gamaya
Re: Поиск методов, удовлетворяющих условию
От: Lloyd Россия  
Дата: 23.06.10 12:37
Оценка: 6 (1) +1
Здравствуйте, Oksana Gimmel, Вы писали:

OG>У меня есть .NET сборка. Надо получить список статических методов в типах из этой сборки, в которых есть обращения к статическим полям. Как это быстрее и проще всего сделать?


Можно с помощью Microsoft.Cci. Вот так можно найти записи стат. полей:
static void Main(string[] args) {
    const string LOCATION = @"....";
    var assemblyNode = AssemblyNode.GetAssembly(LOCATION, true, true, false);
    var q = from t in assemblyNode.Types
            from m in t.Members.OfType<Method>()
            where m.IsStatic && HasStaticFieldWrite(m)
            select m;
    foreach (Method method in q) {
        Console.WriteLine(method.FullName);
    }
}

static bool HasStaticFieldWrite(Method method) {
    var q = from st in method.Body.Statements.SelectMany(GetChildStatements).OfType<AssignmentStatement>()
            let mb = st.Target as MemberBinding
            where mb != null
            let f = mb.BoundMember as Field
            where f != null && (f.IsStatic)
            select st;
    return q.Any();
}

static IEnumerable<Statement> GetChildStatements(Statement statement) {
    var block = statement as Block;
    return block != null ? block.Statements : Enumerable.Empty<Statement>();
}
Re: Поиск методов, удовлетворяющих условию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 23.06.10 12:51
Оценка:
Здравствуйте, Oksana Gimmel, Вы писали:

OG>У меня есть .NET сборка. Надо получить список статических методов в типах из этой сборки, в которых есть обращения к статическим полям. Как это быстрее и проще всего сделать?


Быстрее всего написать визитор (унаследовав от BaseCodeTraverser) и проверять ITargetExpression и IBoundExpression на наличие таких обращений.
Re[2]: Поиск методов, удовлетворяющих условию
От: Sinix  
Дата: 23.06.10 12:55
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Можно с помощью Microsoft.Cci. Вот так можно найти записи стат. полей:


Позанудствую. let лучше заменить на select ... into (а ещё лучше цепочку из let where let where превратить в отдельный фильтр-метод).

Помимо спецификации C# (как оказалось, это лучшая шпаргалка по linq expression translation):
раз (какие люди однако );
два.
Re[2]: Поиск методов, удовлетворяющих условию
От: Sinix  
Дата: 23.06.10 12:57
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Быстрее всего написать визитор (унаследовав от BaseCodeTraverser) и проверять ITargetExpression и IBoundExpression на наличие таких обращений.


Будет неудобно получать список.
Re[3]: Поиск методов, удовлетворяющих условию
От: Lloyd Россия  
Дата: 23.06.10 13:07
Оценка:
Здравствуйте, Sinix, Вы писали:

L>>Можно с помощью Microsoft.Cci. Вот так можно найти записи стат. полей:


S>Позанудствую. let лучше заменить на select ... into (а ещё лучше цепочку из let where let where превратить в отдельный фильтр-метод).


Не считаю, что это лучше.
Re[3]: Поиск методов, удовлетворяющих условию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 23.06.10 13:08
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>Быстрее всего написать визитор (унаследовав от BaseCodeTraverser) и проверять ITargetExpression и IBoundExpression на наличие таких обращений.


S>Будет неудобно получать список.


Прогонять визитором каждый метод — очень удобно.
Re[2]: Поиск методов, удовлетворяющих условию
От: Lloyd Россия  
Дата: 23.06.10 13:34
Оценка:
Здравствуйте, gandjustas, Вы писали:

OG>>У меня есть .NET сборка. Надо получить список статических методов в типах из этой сборки, в которых есть обращения к статическим полям. Как это быстрее и проще всего сделать?


G>Быстрее всего написать визитор (унаследовав от BaseCodeTraverser) и проверять ITargetExpression и IBoundExpression на наличие таких обращений.


Мне интересно, чем ты руководствовался, когда писал такой ответ? Ничего же непонятно. Непонятно даже, какое отношение имеют твое сообщение к вопросу.
Re[3]: Поиск методов, удовлетворяющих условию
От: Тролль зеленый и толстый  
Дата: 23.06.10 14:13
Оценка:
Почитал твои ссылки и не понял, почему это лучше.
Re[4]: Поиск методов, удовлетворяющих условию
От: Sinix  
Дата: 23.06.10 15:44
Оценка:
Здравствуйте, Lloyd, Вы писали:

S>>Позанудствую. let лучше заменить на select ... into (а ещё лучше цепочку из let where let where превратить в отдельный фильтр-метод).


L>Не считаю, что это лучше.


Каковы ваши доказатьельства?(с)
Мои:
1) let заводит новый анонимный тип, что оочень хорошо просаживает нанотесты (в реальном коде, конечно, найдётся чему тормозить и без них). В общем случае лучше обойтись без let.

2) Вынесение цепочки let where в отдельный метод позволяет превратить нагромождение итераторов в пару if'ов.
Re[4]: Поиск методов, удовлетворяющих условию
От: Sinix  
Дата: 23.06.10 15:46
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Прогонять визитором каждый метод — очень удобно.

Как это поможет решить исходную задачу?
Re[4]: Поиск методов, удовлетворяющих условию
От: Sinix  
Дата: 23.06.10 15:49
Оценка: :)
Здравствуйте, Тролль зеленый и толстый, Вы писали:

ТЗИ>Почитал твои ссылки и не понял, почему это лучше.

Не лучше. let имеет неприятные side-эффекты (неявное создание анонимных типов) и повсевместно использоваться не должен.
Re[3]: Поиск методов, удовлетворяющих условию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 23.06.10 16:01
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, gandjustas, Вы писали:


OG>>>У меня есть .NET сборка. Надо получить список статических методов в типах из этой сборки, в которых есть обращения к статическим полям. Как это быстрее и проще всего сделать?


G>>Быстрее всего написать визитор (унаследовав от BaseCodeTraverser) и проверять ITargetExpression и IBoundExpression на наличие таких обращений.


L>Мне интересно, чем ты руководствовался, когда писал такой ответ? Ничего же непонятно. Непонятно даже, какое отношение имеют твое сообщение к вопросу.


Чтобы получить любое обращение к статическому полю надо писать визитор. Соответственно визитор можно натравливать на каждый статический метода каждого типа.

Задача получения всех методов всех типов решается тривиально с помощью CCI, а поиск обращения к статическому полю — как написал выше.
Re[5]: Поиск методов, удовлетворяющих условию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 23.06.10 16:02
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>Прогонять визитором каждый метод — очень удобно.

S>Как это поможет решить исходную задачу?

Именно это и поможет. Есть другие варианты?
Re[5]: Поиск методов, удовлетворяющих условию
От: Lloyd Россия  
Дата: 23.06.10 16:10
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Каковы ваши доказатьельства?(с)

S>Мои:
S>1) let заводит новый анонимный тип, что оочень хорошо просаживает нанотесты (в реальном коде, конечно, найдётся чему тормозить и без них). В общем случае лучше обойтись без let.

Это детали реализации. Для меня лучшая читаемость имеет более высокий приоритет, тем более, что в реале ты разницу и в микроскоп не заметишь.

S>2) Вынесение цепочки let where в отдельный метод позволяет превратить нагромождение итераторов в пару if'ов.


Вынесение позволяет позволяет превратить пару let-ов в нагромождение методов.
Re[4]: Поиск методов, удовлетворяющих условию
От: Lloyd Россия  
Дата: 23.06.10 16:13
Оценка:
Здравствуйте, gandjustas, Вы писали:

L>>Мне интересно, чем ты руководствовался, когда писал такой ответ? Ничего же непонятно. Непонятно даже, какое отношение имеют твое сообщение к вопросу.


G>Чтобы получить любое обращение к статическому полю надо писать визитор. Соответственно визитор можно натравливать на каждый статический метода каждого типа.


Зачем так сложно? Где в моем примере визитор?

G>Задача получения всех методов всех типов решается тривиально с помощью CCI,


Ты действительно думаешь, что топикстартер знал о существовании Cci и при этом не знает как выдрать нужные методы?

G>а поиск обращения к статическому полю — как написал выше.


Вот и написал бы код, если все так просто.
Re[5]: Поиск методов, удовлетворяющих условию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 23.06.10 16:23
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, gandjustas, Вы писали:


L>>>Мне интересно, чем ты руководствовался, когда писал такой ответ? Ничего же непонятно. Непонятно даже, какое отношение имеют твое сообщение к вопросу.


G>>Чтобы получить любое обращение к статическому полю надо писать визитор. Соответственно визитор можно натравливать на каждый статический метода каждого типа.

L>Зачем так сложно? Где в моем примере визитор?

Твой пример далеко не все случаи покрывает, только в левой части оператора присваивания.

G>>Задача получения всех методов всех типов решается тривиально с помощью CCI,

L>Ты действительно думаешь, что топикстартер знал о существовании Cci и при этом не знает как выдрать нужные методы?
Я думаю теперь уже знает.

G>>а поиск обращения к статическому полю — как написал выше.

L>Вот и написал бы код, если все так просто.
Чуть позже, некогда было.
Re[6]: Поиск методов, удовлетворяющих условию
От: Lloyd Россия  
Дата: 23.06.10 16:28
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>Чтобы получить любое обращение к статическому полю надо писать визитор. Соответственно визитор можно натравливать на каждый статический метода каждого типа.

L>>Зачем так сложно? Где в моем примере визитор?

G>Твой пример далеко не все случаи покрывает, только в левой части оператора присваивания.


Неужели?

Вот так можно найти записи стат. полей


Да и как этот ответ связан с использованием визитора?
Re[7]: Поиск методов, удовлетворяющих условию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 23.06.10 16:32
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, gandjustas, Вы писали:


G>>>>Чтобы получить любое обращение к статическому полю надо писать визитор. Соответственно визитор можно натравливать на каждый статический метода каждого типа.

L>>>Зачем так сложно? Где в моем примере визитор?

G>>Твой пример далеко не все случаи покрывает, только в левой части оператора присваивания.


L>Неужели?

L>

L>Вот так можно найти записи стат. полей


Исходная то задача была:

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


А твой пример не расширяется до поиска любого обращения.
Re[8]: Поиск методов, удовлетворяющих условию
От: Lloyd Россия  
Дата: 23.06.10 16:35
Оценка:
Здравствуйте, gandjustas, Вы писали:

L>>Неужели?

L>>

L>>Вот так можно найти записи стат. полей


G>Исходная то задача была:

G>

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


Именно поэтому я и уточнил, что пример — для поиска записей полей.

G>А твой пример не расширяется до поиска любого обращения.


Почему не расширяется? Допиши нужную логику в HasStaticFieldWrite и всех делов-то.

Кстати, ты попустил вопрос:

Да и как этот ответ связан с использованием визитора?

Re[9]: Поиск методов, удовлетворяющих условию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 23.06.10 16:45
Оценка: -1
Здравствуйте, Lloyd, Вы писали:

G>>А твой пример не расширяется до поиска любого обращения.


L>Почему не расширяется? Допиши нужную логику в HasStaticFieldWrite и всех делов-то.

Ну допиши

L>Кстати, ты попустил вопрос:

L>

L>Да и как этот ответ связан с использованием визитора?

Как допишешь — так узнаешь
Re[10]: Поиск методов, удовлетворяющих условию
От: Lloyd Россия  
Дата: 23.06.10 19:12
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>А твой пример не расширяется до поиска любого обращения.


L>>Почему не расширяется? Допиши нужную логику в HasStaticFieldWrite и всех делов-то.

G> Ну допиши

Ну допишу. Ты в это время свой вариант не забудь подготовить.

L>>Кстати, ты попустил вопрос:

L>>

L>>Да и как этот ответ связан с использованием визитора?

G>Как допишешь — так узнаешь

Да уж сообщи мне, если знаешь. Вдруг ты действительно прав.
Re[11]: Поиск методов, удовлетворяющих условию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.06.10 08:54
Оценка: +1
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, gandjustas, Вы писали:


G>>>>А твой пример не расширяется до поиска любого обращения.


L>>>Почему не расширяется? Допиши нужную логику в HasStaticFieldWrite и всех делов-то.

G>> Ну допиши

L>Ну допишу. Ты в это время свой вариант не забудь подготовить.


public class FindStaticReferencesVisitor: BaseCodeTraverser
{
    public static bool HasStaticReferences(IMethodDefinition method)
    {
        var visitor = new FindStaticReferencesVisitor();
        visitor.Visit(method);
        return visitor.staticReferences.Any();

    }
    List<ITypeDefinitionMember> staticReferences = new List<ITypeDefinitionMember>();

    public override void Visit(ITargetExpression targetExpression)
    {
        CollectStaticReferences(targetExpression.Definition);
        base.Visit(targetExpression);
    }

    public override void Visit(IBoundExpression boundExpression)
    {
        CollectStaticReferences(boundExpression.Definition);
        base.Visit(boundExpression);
    }

    private void CollectStaticReferences(object definition)
    {
        if (definition is IFieldDefinition)
        {
            var fieldDef = definition as IFieldDefinition;
            if (fieldDef.IsStatic)
            {
                staticReferences.Add(fieldDef);
            }
        }

        if (definition is IPropertyDefinition)
        {
            var propertyDef = definition as IPropertyDefinition;
            if (propertyDef.Accessors.Select(a => a.ResolvedMethod).All(m => m.IsStatic))
            {
                staticReferences.Add(propertyDef);
            }
        }
    }
}

class Program
{
    static string assemblyName;

    static void Main(string[] args)
    {
        assemblyName = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;

        var host = new CodeContractAwareHostEnvironment();

        IAssembly assembly = host.LoadUnitFrom(assemblyName) as IAssembly;
        if (assembly == null || assembly == Dummy.Assembly)
        {
            Console.WriteLine("Error");
        }
        else
        {
            var codeAssembly = Decompiler.GetCodeModelFromMetadataModel(host, assembly, null);
            var q = from t in codeAssembly.AllTypes
                    from m in t.Methods
                    where FindStaticReferencesVisitor.HasStaticReferences(m)
                    select m;
            var method = q.First();
            Console.WriteLine(method.Name);
            
        }

    }
}


Вот как-то так.
Re[12]: Поиск методов, удовлетворяющих условию
От: Lloyd Россия  
Дата: 24.06.10 09:48
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Вот как-то так.


Да, действительно, самому читать — чрезчур много писанины получается.
Re[13]: Поиск методов, удовлетворяющих условию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.06.10 11:11
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, gandjustas, Вы писали:


G>>Вот как-то так.


L>Да, действительно, самому читать — чрезчур много писанины получается.


Это "чрезчур много писанины" называется визитором.

Вот и ответ на твой вопрос.
Re[14]: Поиск методов, удовлетворяющих условию
От: Lloyd Россия  
Дата: 24.06.10 11:16
Оценка:
Здравствуйте, gandjustas, Вы писали:

L>>Да, действительно, самому читать — чрезчур много писанины получается.


G>Это "чрезчур много писанины" называется визитором.


G>Вот и ответ на твой вопрос.


Нет, визитор тут не причем.
Re[15]: Поиск методов, удовлетворяющих условию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.06.10 11:21
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, gandjustas, Вы писали:


L>>>Да, действительно, самому читать — чрезчур много писанины получается.


G>>Это "чрезчур много писанины" называется визитором.


G>>Вот и ответ на твой вопрос.


L>Нет, визитор тут не причем.



Может все таки напишешь а там посмотрим?
Re[16]: Поиск методов, удовлетворяющих условию
От: Lloyd Россия  
Дата: 24.06.10 11:25
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>Это "чрезчур много писанины" называется визитором.


G>>>Вот и ответ на твой вопрос.


L>>Нет, визитор тут не причем.


G>

G>Может все таки напишешь а там посмотрим?

Я уже написал, что в моем варианте писанины будет много. У тебя получилось компактнее. Но это не далает мое решение "визитором".
Re[17]: Поиск методов, удовлетворяющих условию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.06.10 11:37
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, gandjustas, Вы писали:


G>>>>Это "чрезчур много писанины" называется визитором.


G>>>>Вот и ответ на твой вопрос.


L>>>Нет, визитор тут не причем.


G>>

G>>Может все таки напишешь а там посмотрим?

L>Я уже написал, что в моем варианте писанины будет много. У тебя получилось компактнее. Но это не далает мое решение "визитором".


Ок, напиши свое решение и посмотрим.
Re[18]: Поиск методов, удовлетворяющих условию
От: Lloyd Россия  
Дата: 24.06.10 11:47
Оценка:
Здравствуйте, gandjustas, Вы писали:

L>>>>Нет, визитор тут не причем.


G>>>

G>>>Может все таки напишешь а там посмотрим?

L>>Я уже написал, что в моем варианте писанины будет много. У тебя получилось компактнее. Но это не далает мое решение "визитором".


G>Ок, напиши свое решение и посмотрим.


Ты читаешь сообщения, на которые отвечаешь? Я же написал, что писанины много и писать его я не хочу.
Re[19]: Поиск методов, удовлетворяющих условию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.06.10 12:20
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, gandjustas, Вы писали:


L>>>>>Нет, визитор тут не причем.


G>>>>

G>>>>Может все таки напишешь а там посмотрим?

L>>>Я уже написал, что в моем варианте писанины будет много. У тебя получилось компактнее. Но это не далает мое решение "визитором".


G>>Ок, напиши свое решение и посмотрим.


L>Ты читаешь сообщения, на которые отвечаешь? Я же написал, что писанины много и писать его я не хочу.


Ну тогда ты не можешь сказать какого вида получится конструкция.
А я такие конструкции писал, и уверен что у тебя будет визитор.
Re[20]: Поиск методов, удовлетворяющих условию
От: Lloyd Россия  
Дата: 24.06.10 12:37
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>Ок, напиши свое решение и посмотрим.


L>>Ты читаешь сообщения, на которые отвечаешь? Я же написал, что писанины много и писать его я не хочу.


G>Ну тогда ты не можешь сказать какого вида получится конструкция.

G>А я такие конструкции писал, и уверен что у тебя будет визитор.

Будет банальный FlattenTree, уплощающий дерево в плоский список. Это типа SelectMany, но который идет не на один уровень, а вглубь.
Re[21]: Поиск методов, удовлетворяющих условию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.06.10 12:44
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, gandjustas, Вы писали:


G>>>>Ок, напиши свое решение и посмотрим.


L>>>Ты читаешь сообщения, на которые отвечаешь? Я же написал, что писанины много и писать его я не хочу.


G>>Ну тогда ты не можешь сказать какого вида получится конструкция.

G>>А я такие конструкции писал, и уверен что у тебя будет визитор.

L>Будет банальный FlattenTree, уплощающий дерево в плоский список. Это типа SelectMany, но который идет не на один уровень, а вглубь.


А если в этом "банальном FlattenTree" изолировать сам обход от алгоритма обработки, чтобы обход дерева можно было переиспользовать, то получится визитор.
Re[22]: Поиск методов, удовлетворяющих условию
От: Lloyd Россия  
Дата: 24.06.10 12:51
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

L>>Будет банальный FlattenTree, уплощающий дерево в плоский список. Это типа SelectMany, но который идет не на один уровень, а вглубь.


G>А если в этом "банальном FlattenTree" изолировать сам обход от алгоритма обработки, чтобы обход дерева можно было переиспользовать, то получится визитор.


Не получится: алгоритм обхода и так изолирован в FlattenTree.
Единственное преимущество visitor-а — это то, что он сам будет выбирать нужный метод обработки, но в этом случае, имхо, удобнее вынести алгоритм диспетчеризации в отдельный класс. Так что никаких преимуществ у визитора в данном случае не просматривается.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.