从许多文件中检索方法/代码

发布于 2024-09-07 09:13:30 字数 397 浏览 0 评论 0原文

我有很多 .cs 文件,我想自动从这些文件中检索 [AcceptVerbs(HttpVerbs.Post)] 属性背后的方法。

所以输入是:

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

输出是:

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

我的想法是使用正则表达式和 String.IndexOf 查找属性的位置 并计算 { 和 } 来找到方法的开始和结束位置,以便检索该方法。

还有其他方法可以帮助我(库、工具或方法)吗?

多谢。

I have many .cs files and I want to retrieve the method behind the [AcceptVerbs(HttpVerbs.Post)] attribute from these files automatically.

so input is:

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

and output is:

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

My idea is use the RegularExpressions and String.IndexOf find the attribute's location
and count the { and } to find the method start and end location in order to retrieve the method.

Are there other ways can help me (libraries, tools, or method)?

Thanks a lot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

音栖息无 2024-09-14 09:13:56

假设这只是一次性的事情,并且您的源代码是“平衡的”(源文件中的 {} 数量相等),您可以使用正则表达式平衡。

此代码片段仅获取一个文件并检查其中是否有任何 .. class .. { .. } 并将它们作为 String[] 返回。

您必须修改它以匹配最后的 linq 查询中的 AcceptVerbs(HttpVerbs.Post) 。递归遍历您的目录并对每个 .cs 文件执行此操作,我假设您有代码。最后,您可能还需要对其进行一些修改,并根据您想要开始查看的 {} 级别来增加/减少 rx 的使用次数。

此测试片段是在 LinqPad 您可以下载它并通过将语言设置为 C# 程序 来测试它,将其移动到控制台应用程序不过,打印到文件或类似文件应该很简单。

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();
}

Assuming this is just a one time thing and your source is "balanced" (equal amount of { and } in your sourcefiles) you can use Regex balancing for it.

This snippet just takes a file and checks inside it for any .. class .. { .. } and returns them as String[].

You'll have to modify it to match AcceptVerbs(HttpVerbs.Post) in the linq query at the end. Recursing through your directory and doing this for each .cs file I assume you have code for. finally you might also have to modify it a bit and use rx more/fewer times depending on the level of {} you want to start looking in.

This test snippet was made in LinqPad you can download it and test it by setting Language to C# Program, moving it to a console app that prints into a file or similar instead should be simple though.

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();
}
轻许诺言 2024-09-14 09:13:49

不确定这是否是您想要的,但您可以使用反射

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;
}

Not sure if this is what you want, but you can use reflection

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文