using System.Collections.Generic; using System.IO; using System.Linq; using Codelyzer.Analysis.Model; namespace CTA.FeatureDetection.Common.Extensions { public static class ProjectWorkspaceQueries { /// /// Determines if a ProjectWorkspace has a specified Nuget Dependency /// /// ProjectWorkspace to search /// Nuget reference to search for /// Whether or not the nuget reference exists in the project public static bool ContainsNugetDependency(this ProjectWorkspace project, string nugetReferenceIdentifier) => project.ExternalReferences?.NugetReferences .Any(r => r.Identity == nugetReferenceIdentifier) == true; /// /// Determines if a ProjectWorkspace has a specified Dependency /// /// ProjectWorkspace to search /// Reference to search for /// Whether or not the reference exists in the project public static bool ContainsDependency(this ProjectWorkspace project, string referenceIdentifier) => project.ExternalReferences?.NugetReferences .Union(project.ExternalReferences?.NugetDependencies) .Union(project.ExternalReferences?.SdkReferences) .Any(r => r.Identity == referenceIdentifier) == true; /// /// Determines if a ProjectWorkspace declares a class with a specified base type /// /// ProjectWorkspace to search /// Original Definition of the base type being searched for /// Whether or not a class with the specified base type is declared in the project public static bool DeclaresClassWithBaseType(this ProjectWorkspace project, string typeOriginalDefinition) => project.SourceFileResults .SelectMany(n => n.AllClasses()) .Any(c => c.BaseTypeOriginalDefinition == typeOriginalDefinition); /// /// Determines if a ProjectWorkspace declares a class with a specified base type for vb sln /// /// ProjectWorkspace to search /// Original Definition of the base type being searched for /// Whether or not a class with the specified base type is declared in the project public static bool DeclaresClassBlocksWithBaseType(this ProjectWorkspace project, string typeOriginalDefinition) => project.SourceFileResults .SelectMany(n => n.AllClassBlocks()) .Any(c => c.BaseTypeOriginalDefinition == typeOriginalDefinition); /// /// Gets all class declaration nodes in a ProjectWorkspace /// /// ProjectWorkspace to search /// Collection of class declaration nodes in the project with the specified base type public static IEnumerable GetAllClassDeclarations(this ProjectWorkspace project) => project.SourceFileResults.SelectMany(r => r.AllClasses()); /// /// Determines if a specified directory exists in the project directory and is non-empty /// /// ProjectWorkspace to search /// Name of directory to search for /// Whether or not to search recursively through directories /// Whether or not the specified directory exists in the project directory and is not empty public static bool ContainsNonEmptyDirectory(this ProjectWorkspace project, string directoryName, bool searchSubdirectories = true) { var projectDirectory = project.ProjectRootPath; var searchOption = searchSubdirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; var directories = Directory.EnumerateDirectories(projectDirectory, directoryName, searchOption); return directories.Any(d => Directory.EnumerateFiles(d, "*", searchOption).Any()); } /// /// Gets all class declaration nodes in a ProjectWorkspace derived from a specified base type /// /// ProjectWorkspace to search /// Base type to search against /// Collection of class declaration nodes in the project with the specified base type public static IEnumerable GetClassDeclarationsByBaseType(this ProjectWorkspace project, string baseTypeOriginalDefinition) => project.GetAllClassDeclarations().Where(c => c.HasBaseType(baseTypeOriginalDefinition)); /// /// Gets all interface declaration nodes in a ProjectWorkspace /// /// ProjectWorkspace to search /// Collection of interface declaration nodes in the project public static IEnumerable GetAllInterfaceDeclarations(this ProjectWorkspace project) => project.SourceFileResults.SelectMany(r => r.AllInterfaces()); /// /// Gets all Invocation Expressions with the given method name. /// /// ProjectWorkspace to search /// Method name to search for /// Collection of invocation expressions with given method name public static IEnumerable GetInvocationExpressionsByMethodName(this ProjectWorkspace project, string methodName) => project.SourceFileResults.SelectMany(r => r.AllInvocationExpressions().Where(i => i.MethodName == methodName)); /// /// Get all object creation expressions in project with the given Semantic Class Type /// /// ProjectWorkspace to search /// Semantic Class Type to search for /// public static IEnumerable GetObjectCreationExpressionBySemanticClassType(this ProjectWorkspace project, string semanticClassType) => project.SourceFileResults.SelectMany(r => r.AllObjectCreationExpressions().Where(o => o.SemanticClassType == semanticClassType)); /// /// Determines if the project contains a file with the given extension. /// /// ProjectWorkspace to search /// Extension name to search for without '.' /// Whether or not to search recursively through directories /// Whether or not a file with extesnion exists in the project directory /// public static bool ContainsFileWithExtension(this ProjectWorkspace project, string extension, bool searchSubdirectories = true) { var projectDirectory = project.ProjectRootPath; var searchOption = searchSubdirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; var searchPattern = string.Join(".", "*", extension); return Directory.EnumerateFiles(projectDirectory, searchPattern, searchOption).Any(); } } }