/// <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);
        }
Exemple #4
0
            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());
        }
Exemple #6
0
 internal OAProjectReference(ProjectReferenceNode projectReference) :
     base(projectReference)
 {
 }
 internal OAProjectReference(ProjectReferenceNode projectReference) :
     base(projectReference)
 {
 }
Exemple #8
0
        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);
        }