| Index: experimental/visual_studio_plugin/third_party/Microsoft.VisualStudio.Project/ProjectReferenceNode.cs
|
| diff --git a/experimental/visual_studio_plugin/third_party/Microsoft.VisualStudio.Project/ProjectReferenceNode.cs b/experimental/visual_studio_plugin/third_party/Microsoft.VisualStudio.Project/ProjectReferenceNode.cs
|
| deleted file mode 100644
|
| index eb416273312dbb95840a2a9b23a0741edd9434e2..0000000000000000000000000000000000000000
|
| --- a/experimental/visual_studio_plugin/third_party/Microsoft.VisualStudio.Project/ProjectReferenceNode.cs
|
| +++ /dev/null
|
| @@ -1,518 +0,0 @@
|
| -/// Copyright (c) Microsoft Corporation. All rights reserved.
|
| -
|
| -using System;
|
| -using System.Diagnostics;
|
| -using System.Globalization;
|
| -using System.IO;
|
| -using System.Runtime.InteropServices;
|
| -using Microsoft.VisualStudio;
|
| -using Microsoft.VisualStudio.Shell;
|
| -using Microsoft.VisualStudio.Shell.Interop;
|
| -
|
| -namespace Microsoft.VisualStudio.Project
|
| -{
|
| - [CLSCompliant(false), ComVisible(true)]
|
| - public class ProjectReferenceNode : ReferenceNode
|
| - {
|
| - #region fieds
|
| - /// <summary>
|
| - /// The name of the assembly this refernce represents
|
| - /// </summary>
|
| - private Guid referencedProjectGuid;
|
| -
|
| - private string referencedProjectName = String.Empty;
|
| -
|
| - private string referencedProjectRelativePath = String.Empty;
|
| -
|
| - private string referencedProjectFullPath = String.Empty;
|
| -
|
| - private BuildDependency buildDependency;
|
| -
|
| - /// <summary>
|
| - /// This is a reference to the automation object for the referenced project.
|
| - /// </summary>
|
| - private EnvDTE.Project referencedProject;
|
| -
|
| - /// <summary>
|
| - /// This state is controlled by the solution events.
|
| - /// The state is set to false by OnBeforeUnloadProject.
|
| - /// The state is set to true by OnBeforeCloseProject event.
|
| - /// </summary>
|
| - private bool canRemoveReference = true;
|
| -
|
| - /// <summary>
|
| - /// Possibility for solution listener to update the state on the dangling reference.
|
| - /// It will be set in OnBeforeUnloadProject then the nopde is invalidated then it is reset to false.
|
| - /// </summary>
|
| - private bool isNodeValid;
|
| -
|
| - #endregion
|
| -
|
| - #region properties
|
| -
|
| - public override string Url
|
| - {
|
| - get
|
| - {
|
| - return this.referencedProjectFullPath;
|
| - }
|
| - }
|
| -
|
| - public override string Caption
|
| - {
|
| - get
|
| - {
|
| - return this.referencedProjectName;
|
| - }
|
| - }
|
| -
|
| - internal Guid ReferencedProjectGuid
|
| - {
|
| - get
|
| - {
|
| - return this.referencedProjectGuid;
|
| - }
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Possiblity to shortcut and set the dangling project reference icon.
|
| - /// It is ussually manipulated by solution listsneres who handle reference updates.
|
| - /// </summary>
|
| - internal protected bool IsNodeValid
|
| - {
|
| - get
|
| - {
|
| - return this.isNodeValid;
|
| - }
|
| - set
|
| - {
|
| - this.isNodeValid = value;
|
| - }
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Controls the state whether this reference can be removed or not. Think of the project unload scenario where the project reference should not be deleted.
|
| - /// </summary>
|
| - internal bool CanRemoveReference
|
| - {
|
| - get
|
| - {
|
| - return this.canRemoveReference;
|
| - }
|
| - set
|
| - {
|
| - this.canRemoveReference = value;
|
| - }
|
| - }
|
| -
|
| - internal string ReferencedProjectName
|
| - {
|
| - get { return this.referencedProjectName; }
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Gets the automation object for the referenced project.
|
| - /// </summary>
|
| - internal EnvDTE.Project ReferencedProjectObject
|
| - {
|
| - get
|
| - {
|
| - // If the referenced project is null then re-read.
|
| - if(this.referencedProject == null)
|
| - {
|
| -
|
| - // Search for the project in the collection of the projects in the
|
| - // current solution.
|
| - EnvDTE.DTE dte = (EnvDTE.DTE)this.ProjectMgr.GetService(typeof(EnvDTE.DTE));
|
| - if((null == dte) || (null == dte.Solution))
|
| - {
|
| - return null;
|
| - }
|
| - foreach(EnvDTE.Project prj in dte.Solution.Projects)
|
| - {
|
| - //Skip this project if it is an umodeled project (unloaded)
|
| - if(string.Compare(EnvDTE.Constants.vsProjectKindUnmodeled, prj.Kind, StringComparison.OrdinalIgnoreCase) == 0)
|
| - {
|
| - continue;
|
| - }
|
| -
|
| - // Get the full path of the current project.
|
| - EnvDTE.Property pathProperty = null;
|
| - try
|
| - {
|
| - pathProperty = prj.Properties.Item("FullPath");
|
| - if(null == pathProperty)
|
| - {
|
| - // The full path should alway be availabe, but if this is not the
|
| - // case then we have to skip it.
|
| - continue;
|
| - }
|
| - }
|
| - catch(ArgumentException)
|
| - {
|
| - continue;
|
| - }
|
| - string prjPath = pathProperty.Value.ToString();
|
| - EnvDTE.Property fileNameProperty = null;
|
| - // Get the name of the project file.
|
| - try
|
| - {
|
| - fileNameProperty = prj.Properties.Item("FileName");
|
| - if(null == fileNameProperty)
|
| - {
|
| - // Again, this should never be the case, but we handle it anyway.
|
| - continue;
|
| - }
|
| - }
|
| - catch(ArgumentException)
|
| - {
|
| - continue;
|
| - }
|
| - prjPath = System.IO.Path.Combine(prjPath, fileNameProperty.Value.ToString());
|
| -
|
| - // If the full path of this project is the same as the one of this
|
| - // reference, then we have found the right project.
|
| - if(NativeMethods.IsSamePath(prjPath, referencedProjectFullPath))
|
| - {
|
| - this.referencedProject = prj;
|
| - break;
|
| - }
|
| - }
|
| - }
|
| -
|
| - return this.referencedProject;
|
| - }
|
| - set
|
| - {
|
| - this.referencedProject = value;
|
| - }
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Gets the full path to the assembly generated by this project.
|
| - /// </summary>
|
| - internal string ReferencedProjectOutputPath
|
| - {
|
| - get
|
| - {
|
| - // Make sure that the referenced project implements the automation object.
|
| - if(null == this.ReferencedProjectObject)
|
| - {
|
| - return null;
|
| - }
|
| -
|
| - // Get the configuration manager from the project.
|
| - EnvDTE.ConfigurationManager confManager = this.ReferencedProjectObject.ConfigurationManager;
|
| - if(null == confManager)
|
| - {
|
| - return null;
|
| - }
|
| -
|
| - // Get the active configuration.
|
| - EnvDTE.Configuration config = confManager.ActiveConfiguration;
|
| - if(null == config)
|
| - {
|
| - return null;
|
| - }
|
| -
|
| - // Get the output path for the current configuration.
|
| - EnvDTE.Property outputPathProperty = config.Properties.Item("OutputPath");
|
| - if(null == outputPathProperty)
|
| - {
|
| - return null;
|
| - }
|
| -
|
| - string outputPath = outputPathProperty.Value.ToString();
|
| -
|
| - // Ususally the output path is relative to the project path, but it is possible
|
| - // to set it as an absolute path. If it is not absolute, then evaluate its value
|
| - // based on the project directory.
|
| - if(!System.IO.Path.IsPathRooted(outputPath))
|
| - {
|
| - string projectDir = System.IO.Path.GetDirectoryName(referencedProjectFullPath);
|
| - outputPath = System.IO.Path.Combine(projectDir, outputPath);
|
| - }
|
| -
|
| - // Now get the name of the assembly from the project.
|
| - // Some project system throw if the property does not exist. We expect an ArgumentException.
|
| - EnvDTE.Property assemblyNameProperty = null;
|
| - try
|
| - {
|
| - assemblyNameProperty = this.ReferencedProjectObject.Properties.Item("OutputFileName");
|
| - }
|
| - catch(ArgumentException)
|
| - {
|
| - }
|
| -
|
| - if(null == assemblyNameProperty)
|
| - {
|
| - return null;
|
| - }
|
| - // build the full path adding the name of the assembly to the output path.
|
| - outputPath = System.IO.Path.Combine(outputPath, assemblyNameProperty.Value.ToString());
|
| -
|
| - return outputPath;
|
| - }
|
| - }
|
| -
|
| - private Automation.OAProjectReference projectReference;
|
| - internal override object Object
|
| - {
|
| - get
|
| - {
|
| - if(null == projectReference)
|
| - {
|
| - projectReference = new Automation.OAProjectReference(this);
|
| - }
|
| - return projectReference;
|
| - }
|
| - }
|
| - #endregion
|
| -
|
| - #region ctors
|
| - /// <summary>
|
| - /// Constructor for the ReferenceNode. It is called when the project is reloaded, when the project element representing the refernce exists.
|
| - /// </summary>
|
| - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings")]
|
| - public ProjectReferenceNode(ProjectNode root, ProjectElement element)
|
| - : base(root, element)
|
| - {
|
| - this.referencedProjectRelativePath = this.ItemNode.GetMetadata(ProjectFileConstants.Include);
|
| - Debug.Assert(!String.IsNullOrEmpty(this.referencedProjectRelativePath), "Could not retrive referenced project path form project file");
|
| -
|
| - string guidString = this.ItemNode.GetMetadata(ProjectFileConstants.Project);
|
| -
|
| - // Continue even if project setttings cannot be read.
|
| - try
|
| - {
|
| - this.referencedProjectGuid = new Guid(guidString);
|
| -
|
| - this.buildDependency = new BuildDependency(this.ProjectMgr, this.referencedProjectGuid);
|
| - this.ProjectMgr.AddBuildDependency(this.buildDependency);
|
| - }
|
| - finally
|
| - {
|
| - Debug.Assert(this.referencedProjectGuid != Guid.Empty, "Could not retrive referenced project guidproject file");
|
| -
|
| - this.referencedProjectName = this.ItemNode.GetMetadata(ProjectFileConstants.Name);
|
| -
|
| - Debug.Assert(!String.IsNullOrEmpty(this.referencedProjectName), "Could not retrive referenced project name form project file");
|
| - }
|
| -
|
| - Uri uri = new Uri(this.ProjectMgr.BaseURI.Uri, this.referencedProjectRelativePath);
|
| -
|
| - if(uri != null)
|
| - {
|
| - this.referencedProjectFullPath = Microsoft.VisualStudio.Shell.Url.Unescape(uri.LocalPath, true);
|
| - }
|
| - }
|
| -
|
| - /// <summary>
|
| - /// constructor for the ProjectReferenceNode
|
| - /// </summary>
|
| - public ProjectReferenceNode(ProjectNode root, string referencedProjectName, string projectPath, string projectReference)
|
| - : base(root)
|
| - {
|
| - Debug.Assert(root != null && !String.IsNullOrEmpty(referencedProjectName) && !String.IsNullOrEmpty(projectReference)
|
| - && !String.IsNullOrEmpty(projectPath), "Can not add a reference because the input for adding one is invalid.");
|
| - this.referencedProjectName = referencedProjectName;
|
| -
|
| - int indexOfSeparator = projectReference.IndexOf('|');
|
| -
|
| -
|
| - string fileName = String.Empty;
|
| -
|
| - // Unfortunately we cannot use the path part of the projectReference string since it is not resolving correctly relative pathes.
|
| - if(indexOfSeparator != -1)
|
| - {
|
| - string projectGuid = projectReference.Substring(0, indexOfSeparator);
|
| - this.referencedProjectGuid = new Guid(projectGuid);
|
| - if(indexOfSeparator + 1 < projectReference.Length)
|
| - {
|
| - string remaining = projectReference.Substring(indexOfSeparator + 1);
|
| - indexOfSeparator = remaining.IndexOf('|');
|
| -
|
| - if(indexOfSeparator == -1)
|
| - {
|
| - fileName = remaining;
|
| - }
|
| - else
|
| - {
|
| - fileName = remaining.Substring(0, indexOfSeparator);
|
| - }
|
| - }
|
| - }
|
| -
|
| - Debug.Assert(!String.IsNullOrEmpty(fileName), "Can not add a project reference because the input for adding one is invalid.");
|
| -
|
| - // Did we get just a file or a relative path?
|
| - Uri uri = new Uri(projectPath);
|
| -
|
| - string referenceDir = PackageUtilities.GetPathDistance(this.ProjectMgr.BaseURI.Uri, uri);
|
| -
|
| - Debug.Assert(!String.IsNullOrEmpty(referenceDir), "Can not add a project reference because the input for adding one is invalid.");
|
| -
|
| - string justTheFileName = Path.GetFileName(fileName);
|
| - this.referencedProjectRelativePath = Path.Combine(referenceDir, justTheFileName);
|
| -
|
| - this.referencedProjectFullPath = Path.Combine(projectPath, justTheFileName);
|
| -
|
| - this.buildDependency = new BuildDependency(this.ProjectMgr, this.referencedProjectGuid);
|
| -
|
| - }
|
| - #endregion
|
| -
|
| - #region methods
|
| - protected override NodeProperties CreatePropertiesObject()
|
| - {
|
| - return new ProjectReferencesProperties(this);
|
| - }
|
| -
|
| - /// <summary>
|
| - /// The node is added to the hierarchy and then updates the build dependency list.
|
| - /// </summary>
|
| - public override void AddReference()
|
| - {
|
| - if(this.ProjectMgr == null)
|
| - {
|
| - return;
|
| - }
|
| - base.AddReference();
|
| - this.ProjectMgr.AddBuildDependency(this.buildDependency);
|
| - return;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Overridden method. The method updates the build dependency list before removing the node from the hierarchy.
|
| - /// </summary>
|
| - public override void Remove(bool removeFromStorage)
|
| - {
|
| - if(this.ProjectMgr == null || !this.CanRemoveReference)
|
| - {
|
| - return;
|
| - }
|
| - this.ProjectMgr.RemoveBuildDependency(this.buildDependency);
|
| - base.Remove(removeFromStorage);
|
| - return;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Links a reference node to the project file.
|
| - /// </summary>
|
| - protected override void BindReferenceData()
|
| - {
|
| - Debug.Assert(!String.IsNullOrEmpty(this.referencedProjectName), "The referencedProjectName field has not been initialized");
|
| - Debug.Assert(this.referencedProjectGuid != Guid.Empty, "The referencedProjectName field has not been initialized");
|
| -
|
| - this.ItemNode = new ProjectElement(this.ProjectMgr, this.referencedProjectRelativePath, ProjectFileConstants.ProjectReference);
|
| -
|
| - this.ItemNode.SetMetadata(ProjectFileConstants.Name, this.referencedProjectName);
|
| - this.ItemNode.SetMetadata(ProjectFileConstants.Project, this.referencedProjectGuid.ToString("B"));
|
| - this.ItemNode.SetMetadata(ProjectFileConstants.Private, true.ToString());
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Defines whether this node is valid node for painting the refererence icon.
|
| - /// </summary>
|
| - /// <returns></returns>
|
| - protected override bool CanShowDefaultIcon()
|
| - {
|
| - if(this.referencedProjectGuid == Guid.Empty || this.ProjectMgr == null || this.ProjectMgr.IsClosed || this.isNodeValid)
|
| - {
|
| - return false;
|
| - }
|
| -
|
| - IVsHierarchy hierarchy = null;
|
| -
|
| - hierarchy = VsShellUtilities.GetHierarchy(this.ProjectMgr.Site, this.referencedProjectGuid);
|
| -
|
| - if(hierarchy == null)
|
| - {
|
| - return false;
|
| - }
|
| -
|
| - //If the Project is unloaded return false
|
| - if(this.ReferencedProjectObject == null)
|
| - {
|
| - return false;
|
| - }
|
| -
|
| - return (!String.IsNullOrEmpty(this.referencedProjectFullPath) && File.Exists(this.referencedProjectFullPath));
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Checks if a project reference can be added to the hierarchy. It calls base to see if the reference is not already there, then checks for circular references.
|
| - /// </summary>
|
| - /// <param name="errorHandler">The error handler delegate to return</param>
|
| - /// <returns></returns>
|
| - protected override bool CanAddReference(out CannotAddReferenceErrorMessage errorHandler)
|
| - {
|
| - // When this method is called this refererence has not yet been added to the hierarchy, only instantiated.
|
| - if(!base.CanAddReference(out errorHandler))
|
| - {
|
| - return false;
|
| - }
|
| -
|
| - errorHandler = null;
|
| - if(this.IsThisProjectReferenceInCycle())
|
| - {
|
| - errorHandler = new CannotAddReferenceErrorMessage(ShowCircularReferenceErrorMessage);
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| - }
|
| -
|
| - private bool IsThisProjectReferenceInCycle()
|
| - {
|
| - return IsReferenceInCycle(this.referencedProjectGuid);
|
| - }
|
| -
|
| - private void ShowCircularReferenceErrorMessage()
|
| - {
|
| - string message = String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.ProjectContainsCircularReferences, CultureInfo.CurrentUICulture), this.referencedProjectName);
|
| - string title = string.Empty;
|
| - OLEMSGICON icon = OLEMSGICON.OLEMSGICON_CRITICAL;
|
| - OLEMSGBUTTON buttons = OLEMSGBUTTON.OLEMSGBUTTON_OK;
|
| - OLEMSGDEFBUTTON defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST;
|
| - VsShellUtilities.ShowMessageBox(this.ProjectMgr.Site, title, message, icon, buttons, defaultButton);
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Recursively search if this project reference guid is in cycle.
|
| - /// </summary>
|
| - private bool IsReferenceInCycle(Guid projectGuid)
|
| - {
|
| - IVsHierarchy hierarchy = VsShellUtilities.GetHierarchy(this.ProjectMgr.Site, projectGuid);
|
| -
|
| - IReferenceContainerProvider provider = hierarchy as IReferenceContainerProvider;
|
| - if(provider != null)
|
| - {
|
| - IReferenceContainer referenceContainer = provider.GetReferenceContainer();
|
| -
|
| - Debug.Assert(referenceContainer != null, "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;
|
| - }
|
| - #endregion
|
| - }
|
| -
|
| -}
|
|
|