Click or drag to resize

Finding Code Objects

Examples of finding specific C# code objects.

Finding code objects in a particular scope:
C#
// Various 'Find' methods are provided on various CodeDOM types to find immediate child code objects at a particular
// point in a code tree, examples of which are shown below.  Global finds or searches are addressed in later examples.

Solution solution = Solution.Load("Nova.Examples.sln");
if (solution != null)
{
    // Find a Project in a Solution by name
    Project project = solution.FindProject("Nova.Examples");
    Log.WriteLine(project != null ? "Found " + project : "ERROR - Project not found");
    if (project != null)
    {
        // Find a CodeUnit in a Project by name
        CodeUnit codeUnit = project.FindCodeUnit("Program.cs");
        Log.WriteLine(codeUnit != null ? "Found " + codeUnit : "ERROR - CodeUnit not found");

        // Find a Namespace in a Project by full name
        Namespace namespace_Examples = project.FindNamespace("Nova.Examples");
        Log.WriteLine(namespace_Examples != null ? "Found " + namespace_Examples : "ERROR - Namespace not found");
        if (namespace_Examples != null)
        {
            // Find a type in a Project as a TypeRef (to a TypeDecl or TypeDefinition or Type) when
            // you don't know if the type is external or not.
            var typeRef_Console = project.FindRef("System.Console") as TypeRef;  // Treat UnresolvedRef as null
            Log.WriteLine(typeRef_Console != null ? "Found " + typeRef_Console : "ERROR - TypeRef not found");

            // Find a TypeDecl in a Project when you know the type is local (as opposed to external).
            var typeDecl_Program1 = project.Find("Nova.Examples.Program") as TypeDecl;
            Log.WriteLine(typeDecl_Program1 != null ? "Found " + typeDecl_Program1 : "ERROR - TypeDecl not found");

            // Find a TypeDefinition (if using Mono Cecil - the default) or a Type (if using Reflection) in a Project
            // when you know the type is external.
            if (ApplicationContext.UseMonoCecilLoads)
            {
                var typeDefinition = project.Find("System.Console") as TypeDefinition;
                Log.WriteLine(typeDefinition != null ? "Found TypeDefinition: " + typeDefinition : "ERROR - TypeDefinition not found");
            }
            else
            {
                var type = project.Find("System.Console") as Type;
                Log.WriteLine(type != null ? "Found Type: " + type : "ERROR - Type not found");
            }

            // Find a type in a Namespace as a TypeRef
            var typeRef_Program = TypeRef.Find(namespace_Examples, "Program") as TypeRef;
            Log.WriteLine(typeRef_Program != null ? "Found " + typeRef_Program : "ERROR - TypeRef not found");

            // Find a TypeDecl in a Namespace
            var typeDecl_Program = namespace_Examples.Find("Program") as TypeDecl;
            Log.WriteLine(typeDecl_Program != null ? "Found " + typeDecl_Program : "ERROR - TypeDecl not found");
            if (typeDecl_Program != null)
            {
                // Find a MethodDecl in a TypeDecl by name
                var methodDecl = typeDecl_Program.FindFirst<MethodDecl>("FindCodeObjects");
                Log.WriteLine(methodDecl != null ? "Found " + methodDecl : "ERROR - MethodDecl not found");
                if (methodDecl != null)
                {
                    // Find a LocalDecl in a MethodDecl by name
                    var localDecl = methodDecl.FindFirst<LocalDecl>("solution");
                    Log.WriteLine(localDecl != null ? "Found " + localDecl : "ERROR - LocalDecl not found");
                    if (localDecl != null)
                    {
                        // Find the Parent MethodDecl of a code object
                        var parentMethod = localDecl.FindParentMethod();
                        Log.WriteLine(parentMethod != null ? "Found " + parentMethod : "ERROR - parent Method not found");

                        // Find the Parent NamespaceDecl of a code object
                        var parentNamespaceDecl = localDecl.FindParent<NamespaceDecl>();
                        Log.WriteLine(parentNamespaceDecl != null ? "Found " + parentNamespaceDecl : "ERROR - parent NamespaceDecl not found");
                    }

                    // Find the first 'if' statement in a MethodDecl
                    var @if = methodDecl.FindFirst<If>();
                    Log.WriteLine(@if != null ? "Found " + @if : "ERROR - If statement not found");
                    if (@if != null)
                    {
                        // Find all child 'if' statements in the body of a parent 'if' statement
                        foreach (var statement in @if.Body)
                        {
                            if (statement is If)
                                Log.WriteLine("Found child " + statement);
                        }
                    }
                }
            }
        }
    }
}

// Helper methods are provided on various SymbolicRef types to find types when manually generating code
// which conveniently return an UnresolvedRef instead of null if the item isn't found.  They can also
// be passed an UnresolvedRef as input, so the output of one call can be passed as the input of another
// without any checks for errors.  For examples, see ManualTests.GenerateFullTest().
// These methods include the following signature patterns:
// 
// Get a reference to a type or namespace in the current project instance:
//     SymbolicRef Project.FindRef(string name)
// 
// Find a type in a namespace or parent type, where NorT is a Namespace or Type/TypeDecl, or an Alias to one
//     SymbolicRef TypeRef.Find(NorT type, string name)
// 
// Find a member of a type, where TYPE is a Type, TypeDecl, TypeRefBase, or type Alias:
//     SymbolicRef MethodRef.Find(TYPE type, string name)
//     SymbolicRef ConstructorRef.Find(TYPE type, params TypeRefBase[] parameterTypes)
//     SymbolicRef PropertyRef.Find(TYPE type, string name)
//     SymbolicRef FieldRef.Find(TYPE type, string name)
// 
// Find a parameter of a method, where METHOD is a MethodInfo or MethodDeclBase
//     SymbolicRef ParameterRef.Find(METHOD method, string name)
Find all references to a named code object:
C#
Solution solution = Solution.Load("Nova.Examples.sln");
if (solution != null)
{
    Project project = solution.FindProject("Nova.Examples");
    if (project != null)
    {
        // Find the MyVisitor ClassDecl and a method on it, so we can search for uses of it
        var myVisitor = project.Find("Nova.Examples.MyVisitor") as TypeDecl;
        if (myVisitor != null)
        {
            var method_VisitObject = myVisitor.FindFirst<MethodDecl>("VisitObject");
            if (method_VisitObject != null)
            {
                // Find all references to the MyVisitor.VisitObject() method in the entire solution
                var findMethodReferences = new FindReferences(method_VisitObject, solution);
                findMethodReferences.Find();
                Log.WriteLine("Found " + findMethodReferences.Results.Count + " references to MyVisitor.VisitObject() in the solution");
            }
        }

        // Find all references to the type 'Log' in the Program.cs file
        var logTypeRef = project.FindRef("Nova.Log") as TypeRef;
        if (logTypeRef != null)
        {
            CodeUnit programFile = project.FindCodeUnit("Program.cs");
            var findLogReferences = new FindReferences(logTypeRef.Reference, programFile);
            findLogReferences.Find();
            Log.WriteLine("Found " + findLogReferences.Results.Count + " references to the Log class in the project");
        }

        // Note that when searching for a type, FindReferences has options to IncludeMemberReferences and/or IncludeDerivedTypes.
        // When searching for methods or properties you can IncludeOverrides, or when searching for methods you can IncludeOverloads.
    }
}
Find all code objects of a certain type:
C#
Solution solution = Solution.Load("Nova.Examples.sln");
if (solution != null)
{
    // Find all MethodDecls in the solution
    var findMethodDecls = new FindByType(typeof(MethodDecl), solution);
    findMethodDecls.Find();
    Log.WriteLine("Found " + findMethodDecls.Results.Count + " MethodDecls in the solution");

    Project project = solution.FindProject("Nova.Examples");
    if (project != null)
    {
        // Find all ClassDecls in the project
        var findClassDecls = new FindByType(typeof(ClassDecl), project);
        findClassDecls.Find();
        Log.WriteLine("Found " + findClassDecls.Results.Count + " ClassDecls in the project");

        // Find all If statements in Program.cs
        CodeUnit programFile = project.FindCodeUnit("Program.cs");
        var findIfs = new FindByType(typeof(If), programFile);
        findIfs.Find();
        Log.WriteLine("Found " + findIfs.Results.Count + " 'if' statements in " + programFile.Name);
    }
}
Find code objects by text string or regular expression:
C#
Solution solution = Solution.Load("Nova.Examples.sln");
if (solution != null)
{
    // Find all code objects in the solution with the text 'Find' in their name or content
    // (match case, but don't require it to be a whole word).
    var findText1 = new FindByText("Find", solution, true, false);
    findText1.Find();
    Log.WriteLine("Found " + findText1.Results.Count + " objects containing the text 'Find' in the solution");

    // Find all code objects in the solution that have a name of 'findText1' OR 'findText2', or contain
    // such a name in their text content (using regular expressions).  Match case and whole words only.
    var findText2 = new FindByText("findText1|findText2", solution, true, true, true);
    findText2.Find();
    Log.WriteLine("Found " + findText2.Results.Count + " objects containing the text 'findText1' or 'findText2' in the solution");

    // Note that the scope of FindByText can be any sub-tree, and in addition to the options to MatchCase, MatchWholeWord,
    // and UseRegularExpressions, there are result filtering options to MatchDeclarations, MatchReferences, MatchLiterals,
    // MatchComments, and MatchMessages.
}