/// <summary> /// Sets the value of an attribute, removing the attribute if the value is null, but still setting it /// if the value is the empty string. Returns the attribute, or null if it was removed. /// UNDONE: Make this return a bool if the attribute did not change, so we can avoid dirtying. /// </summary> internal static XmlAttributeWithLocation SetOrRemoveAttribute(XmlElementWithLocation element, string name, string value, bool allowSettingEmptyAttributes) { if (value == null || (!allowSettingEmptyAttributes && value.Length == 0)) { // The caller passed in a null or an empty value. So remove the attribute. element.RemoveAttribute(name); return null; } else { // Set the new attribute value element.SetAttribute(name, value); XmlAttributeWithLocation attribute = (XmlAttributeWithLocation)element.Attributes[name]; return attribute; } }
/// <summary> /// Given an element corresponding to a P2P reference, create the appropriate element in the new project /// </summary> /// <param name="referenceElement"></param> /// <param name="referencesItemGroup"></param> /// <param name="referenceName"></param> /// <param name="referencedProjectGuid"></param> /// <returns></returns> private ProjectItemElement ConvertProjectToProjectReference(XmlElementWithLocation referenceElement, ProjectItemGroupElement referencesItemGroup, string referenceName, ref string referencedProjectGuid) { ProjectItemElement newReferenceItem; // This is a project-to-project reference. // This gets added as a new XMake item of type "ProjectReference". // The "Include" attribute should be the relative path from the // current project to the referenced project file. For example, // ----------------------------------------------------------------------- // Everett format: // =============== // <Reference // Name = "XMakeTasks" // Project = "{44342961-78F4-4F98-AFD6-720DA6E648A2}" // Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}" // /> // ----------------------------------------------------------------------- // XMake format: // ============= // <ProjectReference Include = "..\XMakeTasks\XMakeTasks.csproj"> // <Name>XMakeTasks</Name> // <Project>{44342961-78F4-4F98-AFD6-720DA6E648A2}</Project> // <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package> // </ProjectReference> // ----------------------------------------------------------------------- // Apparently, sometimes project reference guids contain additional goo with relative project path. // Just strip it off. The project system does the same thing, and by doing this early we make // sure that we have the correct guid attribute in the project file and ResolveNonMSBuildReferences // does not complain about invalid characters there which causes all the references to fail to resolve. int barIndex = referencedProjectGuid.IndexOf('|'); if (barIndex != -1) { referencedProjectGuid = referencedProjectGuid.Remove(barIndex); referenceElement.SetAttribute(VSProjectAttributes.project, referencedProjectGuid); } string pathToReferencedProject = this.GetRelativePathToReferencedProject(referencedProjectGuid); if (pathToReferencedProject != null) { // For VSD Projects, we want to transform all Everett ( .csdproj & .vbdproj ) project 2 project references into // Whidbey ( .csproj & .vbproj ) references. if (0 == String.Compare(Path.GetExtension(pathToReferencedProject), XMakeProjectStrings.csdprojFileExtension, StringComparison.OrdinalIgnoreCase)) { pathToReferencedProject = Path.ChangeExtension(pathToReferencedProject, XMakeProjectStrings.csprojFileExtension); } else if (0 == String.Compare(Path.GetExtension(pathToReferencedProject), XMakeProjectStrings.vbdprojFileExtension, StringComparison.OrdinalIgnoreCase)) { pathToReferencedProject = Path.ChangeExtension(pathToReferencedProject, XMakeProjectStrings.vbprojFileExtension); } } // Add a new item to XMake of type "ProjectReference". If we were able to find // the relative path to the project, use it for the "Include", otherwise just use // the project name. string value = (pathToReferencedProject != null) ? pathToReferencedProject : referenceName; newReferenceItem = referencesItemGroup.AddItem(XMakeProjectStrings.projectReference, ProjectCollection.Escape(value)); return newReferenceItem; }