Получить метод / код из многих файлов - PullRequest
0 голосов
/ 23 июня 2010

У меня есть много файлов .cs, и я хочу автоматически извлечь из этих файлов метод, стоящий за атрибутом [AcceptVerbs (HttpVerbs.Post)].

, поэтому ввод:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult sample(string msg)
{......}

и вывод:

public ActionResult sample(string msg)
{......}

Моя идея заключается в том, чтобы использовать RegularExpressions и String.IndexOf, чтобы найти местоположение атрибута и сосчитать {и}, чтобы найти начальное и конечное местоположение метода, чтобы получить метод.

Могут ли помочь мне другие способы (библиотеки, инструменты или метод)?

Большое спасибо.

Ответы [ 2 ]

1 голос
/ 23 июня 2010

Не уверен, что это то, что вы хотите, но вы можете использовать отражение

public static IList<MemberInfo> GetMethodsImplementing<T>(Assembly assembly) where T : Attribute
{
    var result = new List<MemberInfo>();

    var types = assembly.GetTypes();
    foreach (var type in types)
    {
        if (!type.IsClass) continue;

        var members = type.GetMembers();
        foreach (var member in members)
        {
            if (member.MemberType != MemberTypes.Method)
                continue;

            var attributes = member.GetCustomAttributes(typeof(T), true /*inherit*/);
            if (attributes.Length > 0)
            {
                // yup. This method implementes MyAttribute
                result.Add(member);
            }
        }
    }

    return result;
}
0 голосов
/ 23 июня 2010

Предполагая, что это всего лишь разовая вещь, и ваш источник "сбалансирован" (равное количество { и } в ваших исходных файлах), вы можете использовать для него балансировку Regex.

Этот фрагмент просто берет файл и проверяет внутри него любые .. class .. { .. } и возвращает их как String[].

Вам нужно изменить его, чтобы он совпадал с AcceptVerbs(HttpVerbs.Post) в запросе linq в конце. Повторно просматривая ваш каталог и делая это для каждого файла .cs, я полагаю, у вас есть код для. наконец, вам также может понадобиться немного изменить его и использовать rx больше / меньше раз, в зависимости от уровня {}, в который вы хотите начать поиск.

Этот тестовый фрагмент был создан в LinqPad . Вы можете загрузить его и проверить его, установив для Language значение C# Program, однако перемещение его в консольное приложение, которое печатает в файл или аналогичный файл, должно быть простым.

void Main()
{
    String data = String.Empty;
    using (StreamReader reader = new StreamReader(@"/path/to/a/file.cs"))
        data = reader.ReadToEnd();

    CheckContents(data, "class").Dump();
}

// Define other methods and classes here
String[] CheckContents(String data, String pattern)
{
    var rx = new Regex(@"{
    (?>
        { (?<DEPTH> )
        |
        } (?<-DEPTH> )
        |
        [^}{]*
    )*
    (?(DEPTH)(?!))
    }", RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline);

    var rx2 = new Regex(@"[^{]*{
    (?>
        { (?<DEPTH> )
        |
        } (?<-DEPTH> )
        |
        [^}{]*
    )*
    (?(DEPTH)(?!))
    }", RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline);

    var nameSpace = rx.Match(data).Value.Substring(1); // Remove { from namespace so we don't match the same thing over and over
    var parts = rx2.Matches(nameSpace);

    return (from Match part in parts where Regex.IsMatch(part.Value, pattern) select part.Value.Trim()).ToArray();
}
...