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