Reputation: 1
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.
Upvotes: 0
Views: 115
Reputation: 9661
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();
}
Upvotes: 0
Reputation: 4749
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;
}
Upvotes: 1