/// <summary> /// Recursively search if this project reference guid is in cycle. /// </summary> private bool IsReferenceInCycle(Guid projectGuid) { // TODO: This has got to be wrong, it doesn't work w/ other project types. IVsHierarchy hierarchy = VsShellUtilities.GetHierarchy(this.ProjectMgr.Site, projectGuid); IReferenceContainerProvider provider = hierarchy.GetProject()?.GetCommonProject() as IReferenceContainerProvider; if (provider != null) { IReferenceContainer referenceContainer = provider.GetReferenceContainer(); Utilities.CheckNotNull(referenceContainer, "Could not found the References virtual node"); foreach (ReferenceNode refNode in referenceContainer.EnumReferences()) { ProjectReferenceNode projRefNode = refNode as ProjectReferenceNode; if (projRefNode != null) { if (projRefNode.ReferencedProjectGuid == this.ProjectMgr.ProjectIDGuid) { return(true); } if (this.IsReferenceInCycle(projRefNode.ReferencedProjectGuid)) { return(true); } } } } return(false); }
protected override ProjectReferenceNode CreateProjectReferenceNode(VSCOMPONENTSELECTORDATA selectorData) { ProjectReferenceNode node = new XSharpProjectReferenceNode(this.ProjectMgr, selectorData.bstrTitle, selectorData.bstrFile, selectorData.bstrProjRef); ReferenceNode existing = null; if (isDuplicateNode(node, ref existing)) { ProjectReferenceNode existingNode = existing as ProjectReferenceNode; return(existingNode); } return(node); }
protected override ProjectReferenceNode CreateProjectReferenceNode(ProjectElement element) { ProjectReferenceNode node = new XSharpProjectReferenceNode(this.ProjectMgr, element); ReferenceNode existing = null; if (isDuplicateNode(node, ref existing)) { ProjectReferenceNode existingNode = existing as ProjectReferenceNode; return(existingNode); } return(node); }
private Assembly GetAssemblyFromProjectRef(ProjectReferenceNode projectReference) { var project = projectReference.ReferencedProjectObject; var groups = project.ConfigurationManager.ActiveConfiguration.OutputGroups; var group = groups.OfType <EnvDTE.OutputGroup>().Single(g => g.CanonicalName == "Built"); var filenames = ((object[])group.FileURLs).Cast <string>().ToArray(); var filename = filenames.Single(f => f.EndsWith(".dll") || f.EndsWith(".exe")); var lastSlash = filename.LastIndexOf('/'); if (lastSlash >= 0) { filename = filename.Substring(lastSlash + 1); } return(Assembly.LoadFile(filename)); }
public DependencyGraph Analyze(string projectPath, string framework = null) { if (string.IsNullOrWhiteSpace(projectPath)) { throw new ArgumentException(nameof(projectPath)); } if (!File.Exists(projectPath)) { throw new ArgumentException("Project path does not exist.", nameof(projectPath)); } var analyzerManager = new AnalyzerManager(new AnalyzerManagerOptions { LoggerFactory = _loggerFactory }); var projectAnalyzer = analyzerManager.GetProject(projectPath); var analyzeResults = string.IsNullOrEmpty(framework) ? projectAnalyzer.Build() : projectAnalyzer.Build(framework); var analyzerResult = string.IsNullOrEmpty(framework) ? analyzeResults.FirstOrDefault() : analyzeResults[framework]; if (analyzerResult == null) { // Todo: Something went wrong, log and return better exception. throw new InvalidOperationException("Unable to load project."); } if (!analyzerResult.IsNetSdkProject()) { // Todo: Support "legacy" projects in the future. throw new InvalidOperationException("Unable to load project."); } var projectAssetsFilePath = analyzerResult.GetProjectAssetsFilePath(); if (!File.Exists(projectAssetsFilePath)) { // Todo: Make sure this exists in future throw new InvalidOperationException($"{projectAssetsFilePath} not found. Please run 'dotnet restore'"); } var lockFile = new LockFileFormat().Read(projectAssetsFilePath); var targetFramework = analyzerResult.GetTargetFramework(); var libraries = lockFile.Targets.Single(x => x.TargetFramework == targetFramework) .Libraries.Where(x => x.IsPackage()).ToList(); var projectNode = new ProjectReferenceNode(projectPath); var builder = new DependencyGraph.Builder(projectNode); var libraryNodes = new Dictionary <string, PackageReferenceNode>(StringComparer.OrdinalIgnoreCase); foreach (var library in libraries) { var libraryNode = library.ToNode(); builder.WithNode(libraryNode); libraryNodes.Add(libraryNode.PackageId, libraryNode); if (library.FrameworkAssemblies.Count > 0) { var assemblyNodes = library.FrameworkAssemblies .Select(x => new AssemblyReferenceNode($"{x}.dll")); builder.WithNodes(assemblyNodes); builder.WithEdges(assemblyNodes .Select(x => new Edge(libraryNode, x))); } if (library.RuntimeAssemblies.Count > 0) { var assemblyNodes = library.RuntimeAssemblies .Select(x => new AssemblyReferenceNode(Path.GetFileName(x.Path))) .Where(x => x.Id != "_._"); if (assemblyNodes.Any()) { builder.WithNodes(assemblyNodes); builder.WithEdges(assemblyNodes .Select(x => new Edge(libraryNode, x))); } } //if (library.CompileTimeAssemblies.Count > 0) //{ // var assemblyNodes = library.CompileTimeAssemblies // .Select(x => new AssemblyReferenceNode(Path.GetFileName(x.Path))); // builder.WithNodes(assemblyNodes); // builder.WithEdges(assemblyNodes // .Select(x => new Edge(libraryNode, x))); //} } foreach (var library in libraries) { var libraryNode = library.ToNode(); if (library.Dependencies.Count > 0) { builder.WithEdges(library.Dependencies .Select(x => new Edge(libraryNode, libraryNodes[x.Id], x.VersionRange.ToString()))); } } builder.WithEdges(analyzerResult.GetItems("PackageReference") .Select(x => new Edge(projectNode, libraryNodes[x.ItemSpec], x.Metadata["Version"]))); var references = analyzerResult.References//GetItems("Reference") .Select(x => new AssemblyReferenceNode(Path.GetFileName(x))); builder.WithNodes(references); builder.WithEdges(references.Select(x => new Edge(projectNode, x))); return(builder.Build()); }
internal OAProjectReference(ProjectReferenceNode projectReference) : base(projectReference) { }
private DependencyGraph.Builder CreateBuilder(IProjectAnalyzer projectAnalyzer, string projectPath, DependencyGraph.Builder builder = null, string framework = null) { var analyzeResults = string.IsNullOrEmpty(framework) ? projectAnalyzer.Build() : projectAnalyzer.Build(framework); var analyzerResult = string.IsNullOrEmpty(framework) ? analyzeResults.FirstOrDefault() : analyzeResults[framework]; if (analyzerResult == null) { // Todo: Something went wrong, log and return better exception. throw new InvalidOperationException("Unable to load project."); } var projectNode = new ProjectReferenceNode(projectPath); if (builder == null) { builder = new DependencyGraph.Builder(projectNode); } else { builder.WithNode(projectNode); builder.WithEdge(new Edge(builder.Root, projectNode)); } var projectAssetsFilePath = analyzerResult.GetProjectAssetsFilePath(); if (!File.Exists(projectAssetsFilePath)) { if (analyzerResult.IsNetSdkProject()) { // a new project doesn't have an asset file throw new InvalidOperationException($"{projectAssetsFilePath} not found. Please run 'dotnet restore'"); } // Old csproj var oldStylePackageReferences = analyzerResult.GetItems("Reference").Where(x => x.ItemSpec.Contains("Version=")); foreach (var reference in oldStylePackageReferences) { var split = reference.ItemSpec.Split(','); var version = split.Single(s => s.Contains("Version="))?.Split('=')[1]; var name = reference.ItemSpec.Split(',')[0]; var node = new PackageReferenceNode(name, version); builder.WithNode(node); builder.WithEdge(new Edge(projectNode, node, version)); } } else { // New csproj var lockFile = new LockFileFormat().Read(projectAssetsFilePath); var targetFramework = analyzerResult.GetTargetFramework(); var runtimeIdentifier = analyzerResult.GetRuntimeIdentifier(); var libraries = lockFile.Targets.Single( x => x.TargetFramework == targetFramework && x.RuntimeIdentifier == runtimeIdentifier) .Libraries.Where(x => x.IsPackage()).ToList(); var libraryNodes = new Dictionary <string, PackageReferenceNode>(StringComparer.OrdinalIgnoreCase); foreach (var library in libraries) { var libraryNode = library.ToNode(); builder.WithNode(libraryNode); // Overwrite any previous additions that may have been added by the loop below. libraryNodes[libraryNode.PackageId] = libraryNode; // Not all dependencies are necessarily included in the list of libraries // for the current target framework and runtime identifier. Add these to libraryNodes // so we can still record these dependencies. foreach (var dependency in library.Dependencies) { // Add min version in version range if this dependency doesn't exist libraryNodes.TryAdd( dependency.Id, new PackageReferenceNode(dependency.Id, dependency.VersionRange.MinVersion.ToString())); } if (library.FrameworkAssemblies.Count > 0) { var assemblyNodes = library.FrameworkAssemblies .Select(x => new AssemblyReferenceNode($"{x}.dll")); builder.WithNodes(assemblyNodes); builder.WithEdges(assemblyNodes .Select(x => new Edge(libraryNode, x))); } if (library.RuntimeAssemblies.Count > 0) { var assemblyNodes = library.RuntimeAssemblies .Select(x => new AssemblyReferenceNode(Path.GetFileName(x.Path))) .Where(x => x.Id != "_._"); if (assemblyNodes.Any()) { builder.WithNodes(assemblyNodes); builder.WithEdges(assemblyNodes .Select(x => new Edge(libraryNode, x))); } } //if (library.CompileTimeAssemblies.Count > 0) //{ // var assemblyNodes = library.CompileTimeAssemblies // .Select(x => new AssemblyReferenceNode(Path.GetFileName(x.Path))); // builder.WithNodes(assemblyNodes); // builder.WithEdges(assemblyNodes // .Select(x => new Edge(libraryNode, x))); //} } foreach (var library in libraries) { var libraryNode = library.ToNode(); if (library.Dependencies.Count > 0) { builder.WithEdges(library.Dependencies .Select(x => new Edge(libraryNode, libraryNodes[x.Id], x.VersionRange.ToString()))); } } // Ignore unversioned references like implicit SDK packages builder.WithEdges(analyzerResult.GetItems("PackageReference") .Where(x => x.Metadata.ContainsKey("Version")) .Select(x => new Edge(projectNode, libraryNodes[x.ItemSpec], x.Metadata["Version"]))); } var references = analyzerResult.References.Select(x => new AssemblyReferenceNode(Path.GetFileName(x))); builder.WithNodes(references); builder.WithEdges(references.Select(x => new Edge(projectNode, x))); return(builder); }