예제 #1
0
        public XmlAttributeWithLocation(string prefix, string localName, string namespaceURI, XmlDocument document, int lineNumber, int columnNumber)
            : base(prefix, localName, namespaceURI, document)
        {
            XmlDocumentWithLocation documentWithLocation = (XmlDocumentWithLocation)document;

            _elementLocation = ElementLocation.Create(documentWithLocation.FullPath, lineNumber, columnNumber);
        }
예제 #2
0
        /// <summary>
        /// Parses the document into the provided ProjectRootElement.
        /// Throws InvalidProjectFileExceptions for syntax errors.
        /// </summary>
        /// <remarks>
        /// The code markers here used to be around the Project class constructor in the old code.
        /// In the new code, that's not very interesting; we are repurposing to wrap parsing the XML.
        /// </remarks>
        internal static void Parse(XmlDocumentWithLocation document, ProjectRootElement projectRootElement)
        {
#if MSBUILDENABLEVSPROFILING
            try
            {
                string projectFile       = String.IsNullOrEmpty(projectRootElement.ProjectFileLocation.File) ? "(null)" : projectRootElement.ProjectFileLocation.File;
                string projectParseBegin = String.Format(CultureInfo.CurrentCulture, "Parse Project {0} - Begin", projectFile);
                DataCollection.CommentMarkProfile(8808, projectParseBegin);
#endif
#if (!STANDALONEBUILD)
            using (new CodeMarkerStartEnd(CodeMarkerEvent.perfMSBuildProjectConstructBegin, CodeMarkerEvent.perfMSBuildProjectConstructEnd))
#endif
            {
                ProjectParser parser = new ProjectParser(document, projectRootElement);
                parser.Parse();
            }
#if MSBUILDENABLEVSPROFILING
        }

        finally
        {
            string projectFile     = String.IsNullOrEmpty(projectRootElement.ProjectFileLocation.File) ? "(null)" : projectRootElement.ProjectFileLocation.File;
            string projectParseEnd = String.Format(CultureInfo.CurrentCulture, "Parse Project {0} - End", projectFile);
            DataCollection.CommentMarkProfile(8809, projectParseEnd);
        }
#endif
        }
예제 #3
0
        /// <summary>
        /// Private constructor to give static semantics
        /// </summary>
        private ProjectParser(XmlDocumentWithLocation document, ProjectRootElement project)
        {
            ErrorUtilities.VerifyThrowInternalNull(project, "project");
            ErrorUtilities.VerifyThrowInternalNull(document, "document");

            _document = document;
            _project  = project;
        }
예제 #4
0
 /// <summary>
 /// Parses the document into the provided ProjectRootElement.
 /// Throws InvalidProjectFileExceptions for syntax errors.
 /// </summary>
 /// <remarks>
 /// The code markers here used to be around the Project class constructor in the old code.
 /// In the new code, that's not very interesting; we are repurposing to wrap parsing the XML.
 /// </remarks>
 internal static void Parse(XmlDocumentWithLocation document, ProjectRootElement projectRootElement)
 {
     MSBuildEventSource.Log.ParseStart(projectRootElement.ProjectFileLocation.File);
     {
         ProjectParser parser = new ProjectParser(document, projectRootElement);
         parser.Parse();
     }
     MSBuildEventSource.Log.ParseStop(projectRootElement.ProjectFileLocation.File);
 }
예제 #5
0
        /// <summary>
        /// Constructor with location information
        /// </summary>
        public XmlElementWithLocation(string prefix, string localName, string namespaceURI, XmlDocumentWithLocation document, int lineNumber, int columnNumber)
            : base(prefix, localName, namespaceURI, document)
        {
            // Subtract one, just to give the same value as the old code did.
            // In the past we pointed to the column of the open angle bracket whereas the XmlTextReader points to the first character of the element name.
            // In well formed XML these are always adjacent on the same line, so it's safe to subtract one.
            // If we're loading from a stream it's zero, so don't subtract one.
            XmlDocumentWithLocation documentWithLocation = (XmlDocumentWithLocation)document;

            int adjustedColumn = (columnNumber == 0) ? columnNumber : columnNumber - 1;
            _elementLocation = ElementLocation.Create(documentWithLocation.FullPath, lineNumber, adjustedColumn);
        }
예제 #6
0
        /// <summary>
        /// Constructor with location information
        /// </summary>
        public XmlElementWithLocation(string prefix, string localName, string namespaceURI, XmlDocumentWithLocation document, int lineNumber, int columnNumber)
            : base(prefix, localName, namespaceURI, document)
        {
            // Subtract one, just to give the same value as the old code did.
            // In the past we pointed to the column of the open angle bracket whereas the XmlTextReader points to the first character of the element name.
            // In well formed XML these are always adjacent on the same line, so it's safe to subtract one.
            // If we're loading from a stream it's zero, so don't subtract one.
            XmlDocumentWithLocation documentWithLocation = (XmlDocumentWithLocation)document;

            int adjustedColumn = (columnNumber == 0) ? columnNumber : columnNumber - 1;

            _elementLocation = ElementLocation.Create(documentWithLocation.FullPath, lineNumber, adjustedColumn);
        }
        public void ContentIsSameAcrossInstances()
        {
            string content = ObjectModelHelpers.CleanupFileContents(@"
                    <Project xmlns='msbuildnamespace' ToolsVersion='msbuilddefaulttoolsversion'>
                        <ItemGroup>
                           Item group content
                        </ItemGroup>
                    </Project>
                    ");

            string path = FileUtilities.GetTemporaryFile();

            try
            {
                File.WriteAllText(path, content);

                ProjectStringCache cache = new ProjectStringCache();
                XmlDocumentWithLocation document1 = new XmlDocumentWithLocation();
                document1.StringCache = cache;
                document1.Load(path);

                XmlDocumentWithLocation document2 = new XmlDocumentWithLocation();
                document2.StringCache = cache;
                document2.Load(path);

                XmlNodeList nodes1 = document1.GetElementsByTagName("ItemGroup");
                XmlNodeList nodes2 = document2.GetElementsByTagName("ItemGroup");

                Assert.AreEqual(1, nodes1.Count);
                Assert.AreEqual(1, nodes2.Count);

                XmlNode node1 = nodes1[0].FirstChild;
                XmlNode node2 = nodes2[0].FirstChild;

                Assert.IsNotNull(node1);
                Assert.IsNotNull(node2);
                Assert.AreNotSame(node1, node2);
                Assert.AreSame(node1.Value, node2.Value);
            }
            finally
            {
                File.Delete(path);
            }
        }
예제 #8
0
        /// <summary>
        /// Get location strings for the content, loading as readonly if specified
        /// </summary>
        private string GetLocations(string content, bool readOnly)
        {
            string file = null;

            try
            {
                file = FileUtilities.GetTemporaryFile();
                File.WriteAllText(file, content);
                var doc = new XmlDocumentWithLocation(loadAsReadOnly: readOnly);
                doc.Load(file);
                var allNodes = doc.SelectNodes("//*|//@*");

                string locations = String.Empty;
                foreach (var node in allNodes)
                {
                    foreach (var property in node.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
                    {
                        if (property.Name.Equals("Location"))
                        {
                            var value = ((ElementLocation)property.GetValue(node, null));

                            if (value != null) // null means attribute is not present
                            {
                                locations += ((XmlNode)node).Name + "==" + ((XmlNode)node).Value ?? String.Empty + ":  " + value.LocationString + "\r\n";
                            }
                        }
                    }
                }

                locations = locations.Replace(file, "c:\\foo\\bar.csproj");

                return locations;
            }
            finally
            {
                File.Delete(file);
            }
        }
예제 #9
0
 public void SaveReadOnly4()
 {
     Assert.Throws<InvalidOperationException>(() =>
     {
         var doc = new XmlDocumentWithLocation(loadAsReadOnly: true);
         doc.Load(_pathToCommonTargets);
         doc.Save(XmlWriter.Create(FileUtilities.GetTemporaryFile()));
     }
    );
 }
예제 #10
0
 public void SaveReadOnly3()
 {
     Assert.Throws<InvalidOperationException>(() =>
     {
         var doc = new XmlDocumentWithLocation(loadAsReadOnly: true);
         doc.Load(_pathToCommonTargets);
         doc.Save(new StringWriter());
     }
    );
 }
예제 #11
0
 private XmlDocumentWithLocation loadXmlFromPath(string path)
 {
     string xmlContents = _defaultTasksFileMap[path];
     XmlDocumentWithLocation xmlDocument = new XmlDocumentWithLocation();
     xmlDocument.LoadXml(xmlContents);
     return xmlDocument;
 }
예제 #12
0
        /// <summary>
        /// Constructor helper to load an XmlDocumentWithLocation from a path.
        /// Assumes path is already normalized.
        /// May throw InvalidProjectFileException.
        /// Never returns null.
        /// Does NOT add to the ProjectRootElementCache. Caller should add after verifying subsequent MSBuild parsing succeeds.
        /// </summary>
        /// <param name="fullPath">The full path to the document to load.</param>
        private XmlDocumentWithLocation LoadDocument(string fullPath)
        {
            ErrorUtilities.VerifyThrowInternalRooted(fullPath);

            XmlDocumentWithLocation document = new XmlDocumentWithLocation();
#if (!STANDALONEBUILD)
            using (new CodeMarkerStartEnd(CodeMarkerEvent.perfMSBuildProjectLoadFromFileBegin, CodeMarkerEvent.perfMSBuildProjectLoadFromFileEnd))
#endif
            {
                try
                {
#if MSBUILDENABLEVSPROFILING 
                    string beginProjectLoad = String.Format(CultureInfo.CurrentCulture, "Load Project {0} From File - Start", fullPath);
                    DataCollection.CommentMarkProfile(8806, beginProjectLoad);
#endif
                    using (XmlTextReader xtr = new XmlTextReader(fullPath))
                    {
                        // Start the reader so it has an idea of what the encoding is.
                        xtr.DtdProcessing = DtdProcessing.Ignore;
                        xtr.Read();
                        _encoding = xtr.Encoding;
                        document.Load(xtr);
                    }

                    document.FullPath = fullPath;
                    _projectFileLocation = ElementLocation.Create(fullPath);
                    _directory = Path.GetDirectoryName(fullPath);

                    if (XmlDocument != null)
                    {
                        XmlDocument.FullPath = fullPath;
                    }

                    _lastWriteTimeWhenRead = FileUtilities.GetFileInfoNoThrow(fullPath).LastWriteTime;
                }
                catch (Exception ex)
                {
                    if (ExceptionHandling.NotExpectedIoOrXmlException(ex))
                    {
                        throw;
                    }

                    XmlException xmlException = ex as XmlException;

                    BuildEventFileInfo fileInfo;

                    if (xmlException != null)
                    {
                        fileInfo = new BuildEventFileInfo(xmlException);
                    }
                    else
                    {
                        fileInfo = new BuildEventFileInfo(fullPath);
                    }

                    ProjectFileErrorUtilities.ThrowInvalidProjectFile(fileInfo, ex, "InvalidProjectFile", ex.Message);
                }
#if MSBUILDENABLEVSPROFILING 
                finally
                {
                    string endProjectLoad = String.Format(CultureInfo.CurrentCulture, "Load Project {0} From File - End", fullPath);
                    DataCollection.CommentMarkProfile(8807, endProjectLoad);
                }
#endif
            }

            return document;
        }
예제 #13
0
        /// <summary>
        /// Private constructor to give static semantics
        /// </summary>
        private ProjectParser(XmlDocumentWithLocation document, ProjectRootElement project)
        {
            ErrorUtilities.VerifyThrowInternalNull(project, "project");
            ErrorUtilities.VerifyThrowInternalNull(document, "document");

            _document = document;
            _project = project;
        }
예제 #14
0
        /// <summary>
        /// This is the entry point method, which performs the project file format
        /// conversion.  This method will simply create a new XmlDocument
        /// in memory, instead of trying to write it to disk.
        /// </summary>
        /// <owner>RGoel</owner>
        private void ConvertInMemoryToMSBuildProject()
        {
            // Make sure we were passed in non-empty source and destination project
            // file names.
            error.VerifyThrowArgument((this.oldProjectFile != null) && (this.oldProjectFile.Length > 0),
                "MissingOldProjectFile");

            // Make sure the source project file exists.
            error.VerifyThrowArgument(File.Exists(oldProjectFile), "ProjectFileNotFound",
                oldProjectFile);

            Initialize();

            // Load the old project file as an XML document.
            XmlDocumentWithLocation oldProjectDocument = new XmlDocumentWithLocation();
            oldProjectDocument.PreserveWhitespace = true;
            TextReader oldProjectFileReader = new OldVSProjectFileReader(oldProjectFile);
            try
            {
                // We have our own custom XML reader to read in the old VS7/Everett project
                // file.  This is because the VS7/Everett project file format supported
                // having characters like <, >, &, etc. embedded inside XML attribute
                // values, but the default XmlTextReader won't handle this.
                using (XmlTextReader xmlReader = new XmlTextReader(oldProjectFileReader))
                {
                    xmlReader.DtdProcessing = DtdProcessing.Ignore;
                    oldProjectDocument.Load(xmlReader);
                }
            }
            catch (Exception e)
            {
                throw new InvalidProjectFileException(e.Message);
            }
            finally
            {
                oldProjectFileReader.Close();
            }

            // Get the top-level nodes from the XML.
            XmlNodeList rootNodes = oldProjectDocument.ChildNodes;
            XmlElementWithLocation visualStudioProjectElement = null;

            // The XML parser will guarantee that we only have one real root element,
            // but since XML comments may appear outside of the <VisualStudioProject> scope,
            // it's possible to get more than one child node.  Just find the first
            // non-comment node.  That should be the <VisualStudioProject> element.
            foreach(XmlNode childNode in rootNodes)
            {
                if ((childNode.NodeType != XmlNodeType.Comment) &&
                    (childNode.NodeType != XmlNodeType.XmlDeclaration) &&
                    (childNode.NodeType != XmlNodeType.Whitespace))
                {
                    visualStudioProjectElement = (XmlElementWithLocation) childNode;
                    break;
                }
            }

            IElementLocation oldProjectDocumentLocation = ElementLocation.Create(oldProjectDocument.FullPath, 1, 1);

            // Verify that we found a non-comment root node.
            ProjectErrorUtilities.VerifyThrowInvalidProject(visualStudioProjectElement != null,
                oldProjectDocumentLocation,
                "NoRootProjectElement", VSProjectElements.visualStudioProject);

            // If the root element is <Project>, then assume that this project is
            // already in XMake format.
            if (visualStudioProjectElement.Name == XMakeProjectStrings.project)
            {
                this.xmakeProject = ProjectRootElement.Open(oldProjectFile);

                // For Whidbey project just need to set the "ToolsVersion" attribute for the main project file
                // and remove imports like <Import Project="$(MSBuildBinPath)\Microsoft.WinFX.targets" />
                // because the Fidalgo stuff is part of .NET Framework 3.5

                // For upgraded workflow projects, the workflow targets need to reference the new v3.5 targets instead of v3.0 targets
                // this change is required to fix the msbuild break when building workflow rules.
                // e.g. before upgrade :<Import Project="$(MSBuildExtensionsPath)\Microsoft\Windows Workflow Foundation\v3.0\Workflow.Targets" />
                // after upgrade  <Import Project="$(MSBuildExtensionsPath)\Microsoft\Windows Workflow Foundation\v3.5\Workflow.Targets" />

                string oldToolsVersion = xmakeProject.ToolsVersion;

                xmakeProject.ToolsVersion = XMakeProjectStrings.toolsVersion;
                List<ProjectImportElement> listOfImportsToBeDeleted = new List<ProjectImportElement>();
                List<ProjectImportElement> listOfWFImportsToBeDeleted = new List<ProjectImportElement>();
                List<string> workflowImportsToAdd = new List<string>();
                string workflowTargetsBasePath = @"$(MSBuildExtensionsPath)\Microsoft\Windows Workflow Foundation\";
                string workflowOldWhidbeyTargetsPath = workflowTargetsBasePath + @"v3.0\";
                string workflowOldOrcasTargetsPath = workflowTargetsBasePath + @"v3.5\";
                string workflowNewTargetsPath = @"$(MSBuildToolsPath)\";
                bool removedWFWhidbeyTargets = false;
                bool changedProject = false;

                // Find matching imports but don't delete whilst enumerating else it will throw an error
                foreach (ProjectImportElement nextImport in xmakeProject.Imports)
                {
                    if (String.Compare(nextImport.Project, @"$(MSBuildBinPath)\Microsoft.WinFX.targets", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        listOfImportsToBeDeleted.Add(nextImport);
                    }

                    if (nextImport.Project.Contains(workflowOldWhidbeyTargetsPath))
                    {
                        listOfWFImportsToBeDeleted.Add(nextImport);
                        workflowImportsToAdd.Add(nextImport.Project.Replace(workflowOldWhidbeyTargetsPath, workflowNewTargetsPath));
                        removedWFWhidbeyTargets = true;
                    }
                    if (nextImport.Project.Contains(workflowOldOrcasTargetsPath))
                    {
                        listOfWFImportsToBeDeleted.Add(nextImport);
                        workflowImportsToAdd.Add(nextImport.Project.Replace(workflowOldOrcasTargetsPath, workflowNewTargetsPath));
                    }

                }

                // Now delete any matching imports
                foreach (ProjectImportElement importToDelete in listOfWFImportsToBeDeleted)
                {
                    this.xmakeProject.RemoveChild(importToDelete);
                    changedProject = true;
                }

                bool removedWinFXTargets = false;
                foreach (ProjectImportElement importToDelete in listOfImportsToBeDeleted)
                {
                    this.xmakeProject.RemoveChild(importToDelete);
                    removedWinFXTargets = true;
                    changedProject = true;
                }

                // If we removed WinFX targets this is a sparkle project and should use v3.0
                if (removedWinFXTargets)
                {
                    xmakeProject.AddProperty(XMakeProjectStrings.TargetFrameworkVersion, "v3.0");
                    changedProject = true;
                }

                //If we removed WFWhidbey imports, we should target this project to v3.0
                if (removedWFWhidbeyTargets)
                {
                    xmakeProject.AddProperty(XMakeProjectStrings.TargetFrameworkVersion, "v3.0");
                    changedProject = true;
                }


                // Re-add the workflow imports with the v4.0 targets.
                foreach (string workflowImportToAdd in workflowImportsToAdd)
                {
                    this.xmakeProject.AddImport(workflowImportToAdd);
                    changedProject = true;
                }

                // Find all the XAML files in the project and give them the custom attributes
                //   <Generator>MSBuild:Compile</Generator> (DevDiv Bugs bug 81222)
                //   <SubType>Designer</SubType> (DevDiv Bugs bug 82748)

                // Find all references to old VC project files (.vcproj extension) and change the
                // extension to .vcxproj instead.  NOTE: we assume that the actual .vcproj -> .vcxproj
                // conversion has already been / is being / will be done elsewhere.
                // Dev10 Bug 557388

                foreach (ProjectItemElement nextItem in xmakeProject.Items)
                {
                    if ((!nextItem.ItemType.Equals("Reference", StringComparison.OrdinalIgnoreCase)) &&
                        (nextItem.Include.Trim().EndsWith(".xaml", StringComparison.OrdinalIgnoreCase)))
                        
                    {
                        if (!nextItem.Metadata.Any(m => String.Equals(m.Name, "Generator", StringComparison.OrdinalIgnoreCase)))
                        {
                            nextItem.AddMetadata("Generator", "MSBuild:Compile");
                            changedProject = true;
                        }

                        if (!nextItem.Metadata.Any(m => String.Equals(m.Name, "SubType", StringComparison.OrdinalIgnoreCase)))
                        {
                            nextItem.AddMetadata("SubType", "Designer");
                            changedProject = true;
                        }
                    }

                    if (String.Equals(nextItem.ItemType, "ProjectReference", StringComparison.OrdinalIgnoreCase) &&
                        nextItem.Include.Trim().EndsWith(".vcproj", StringComparison.OrdinalIgnoreCase))
                    {
                        nextItem.Include = Path.ChangeExtension(nextItem.Include, ".vcxproj");
                        changedProject = true;
                    }
                }

                // DevDiv Bugs bug 100701: if we removed the Microsoft.WinFX.targets import,
                // and if there is no ProjectTypeGuids property, add the WPF flavor GUID
                if (removedWinFXTargets)
                {
                    ProjectPropertyElement currentGuidsProperty = FindPropertyIfPresent(this.xmakeProject, XMakeProjectStrings.projectTypeGuids);
                    string newGuids = "{" + XMakeProjectStrings.wpfFlavorGuid + "}";
                    if (currentGuidsProperty == null || currentGuidsProperty.Value.Length == 0)
                    {
                        string currentGuids = String.Empty;

                        // To have a flavor GUID we need a base GUID.
                        if (oldProjectFile.EndsWith(".csproj", StringComparison.OrdinalIgnoreCase))
                        {
                            currentGuids = "{" + XMakeProjectStrings.cSharpGuid + "}";
                        }
                        if (oldProjectFile.EndsWith(".vbproj", StringComparison.OrdinalIgnoreCase))
                        {
                            currentGuids = "{" + XMakeProjectStrings.visualBasicGuid + "}";
                        }
                        xmakeProject.AddProperty(XMakeProjectStrings.projectTypeGuids, newGuids + ";" + currentGuids);
                        changedProject = true;
                    }
                }

                // Fix up TargetFrameworkSubset
                changedProject = FixTargetFrameworkSubset() || changedProject;
                
                var hasFSharpSpecificConversions = FSharpSpecificConversions(true);
                
                changedProject = hasFSharpSpecificConversions || changedProject;
                changedProject = VBSpecificConversions() || changedProject;

                // Do asset compat repair for any project that was previously a TV < 12.0
                if (
                        String.IsNullOrEmpty(oldToolsVersion) || 
                        String.Equals(oldToolsVersion, "3.5", StringComparison.OrdinalIgnoreCase) ||
                        String.Equals(oldToolsVersion, "4.0", StringComparison.OrdinalIgnoreCase)
                    )
                {
                    changedProject = DoRepairForAssetCompat() || changedProject;
                }

                // Remove any default fully qualified Code Analysis paths.
                // DevDiv bug 63415
                changedProject = FixCodeAnalysisPaths() || changedProject;

                if (hasFSharpSpecificConversions && !String.IsNullOrEmpty(oldToolsVersion))
                {
                    // for Bug 609702:A ToolsVersion=12.0 F# project fails to load in VS 2012
                    // for F# project after upgrade we restore previous value of ToolsVersion so Dev11 still can load upgraded project
                    // however if old ToolsVersion as 3.5 - it will be upgraded to 4.0 to avoid any unexpected behavior in Dev10\Dev11
                    xmakeProject.ToolsVersion = String.Equals(oldToolsVersion, "3.5", StringComparison.OrdinalIgnoreCase) ? "4.0" : oldToolsVersion;
                }
                else if (this.isMinorUpgrade ||
                        (!changedProject &&
                         !String.IsNullOrEmpty(oldToolsVersion) &&
                         !String.Equals(oldToolsVersion, "3.5", StringComparison.OrdinalIgnoreCase))
                    )
                {
                    // If it's minor upgrade, or nothing changed and the project was already TV 4.0 or higher,
                    // set the ToolsVersion back to its old value. 
                    xmakeProject.ToolsVersion = oldToolsVersion;
                }
            }
            else
            {
                // OK, we have to start with a fresh project and assemble it
                this.xmakeProject = ProjectRootElement.Create();

                // This root node must be a <VisualStudioProject> node.
                ProjectErrorUtilities.VerifyThrowInvalidProject(visualStudioProjectElement.Name ==
                    VSProjectElements.visualStudioProject,
                    visualStudioProjectElement.Location, "UnrecognizedElement", visualStudioProjectElement.Name);

                // Set the "DefaultTargets" attribute for the main project file.
                if (!isUserFile)
                {
                    xmakeProject.DefaultTargets = XMakeProjectStrings.defaultTargets;
                }

                // Set the "ToolsVersion" attribute for the main project file.
                if (!isUserFile)
                {
                    xmakeProject.ToolsVersion = XMakeProjectStrings.toolsVersion;
                }

                // Process the <VisualStudioProject> element in the source project file,
                // adding the necessary stuff to the XMake project.
                this.ProcessVisualStudioProjectElement(visualStudioProjectElement);
            }
        }
예제 #15
0
 /// <summary>
 /// Constructor allows you to set all the data members
 /// </summary>
 public ProjectDefinition(string filename, string initialTargets, string defaultTargets, string toolsVersion, bool createMSBuildProject)
 {
     this.initialTargets = initialTargets;
     this.defaultTargets = defaultTargets;
     this.toolsVersion = toolsVersion;
     this.filename = filename;
     this.createMSBuildProject = createMSBuildProject;
     this.projectXmlDocument = new XmlDocumentWithLocation();
     this.targets = new Dictionary<string, TargetDefinition>();
     this.projectRootElement = this.projectXmlDocument.CreateElement("Project", @"http://schemas.microsoft.com/developer/msbuild/2003");
     GenerateProjectRootElement();
 }
예제 #16
0
 /// <summary>
 /// Constructor without location information
 /// </summary>
 public XmlElementWithLocation(string prefix, string localName, string namespaceURI, XmlDocumentWithLocation document)
     : this(prefix, localName, namespaceURI, document, 0, 0)
 {
 }
예제 #17
0
        public void ContentCanBeModified()
        {
            string content = ObjectModelHelpers.CleanupFileContents(@"
                    <Project xmlns='msbuildnamespace' ToolsVersion='msbuilddefaulttoolsversion'>
                        <ItemGroup attr1='attr1value'>
                           Item group content
                        </ItemGroup>
                    </Project>
                    ");

            string path = FileUtilities.GetTemporaryFile();

            try
            {
                File.WriteAllText(path, content);
                ProjectStringCache cache = new ProjectStringCache();
                XmlDocumentWithLocation document1 = new XmlDocumentWithLocation();
                document1.StringCache = cache;
                document1.Load(path);

                XmlDocumentWithLocation document2 = new XmlDocumentWithLocation();
                document2.StringCache = cache;
                document2.Load(path);

                string outerXml1 = document1.OuterXml;
                string outerXml2 = document2.OuterXml;
                Assert.AreEqual(outerXml1, outerXml2);

                XmlNodeList nodes1 = document1.GetElementsByTagName("ItemGroup");
                XmlNodeList nodes2 = document2.GetElementsByTagName("ItemGroup");

                Assert.AreEqual(1, nodes1.Count);
                Assert.AreEqual(1, nodes2.Count);

                XmlNode node1 = nodes1[0];
                XmlNode node2 = nodes2[0];
                Assert.IsNotNull(node1);
                Assert.IsNotNull(node2);
                Assert.AreNotSame(node1, node2);
                Assert.AreEqual(1, node1.Attributes.Count);
                Assert.AreEqual(1, node2.Attributes.Count);
                Assert.AreSame(node1.Attributes[0].Value, node2.Attributes[0].Value);

                node2.Attributes[0].Value = "attr1value";
                Assert.AreEqual(node1.Attributes[0].Value, node2.Attributes[0].Value);
                Assert.AreNotSame(node1.Attributes[0].Value, node2.Attributes[0].Value);

                node1 = nodes1[0].FirstChild;
                node2 = nodes2[0].FirstChild;
                Assert.AreNotSame(node1, node2);
                Assert.AreSame(node1.Value, node2.Value);

                XmlText newText = document2.CreateTextNode("New Value");
                XmlNode parent = node2.ParentNode;
                parent.ReplaceChild(newText, node2);

                Assert.AreNotEqual(outerXml1, document2.OuterXml);
            }
            finally
            {
                File.Delete(path);
            }
        }
예제 #18
0
        /// <summary>
        /// Initialize a ProjectRootElement instance from an existing document.
        /// May throw InvalidProjectFileException.
        /// Leaves the project dirty, indicating there are unsaved changes.
        /// </summary>
        /// <remarks>
        /// Do not make public: we do not wish to expose particular XML API's.
        /// </remarks>
        private ProjectRootElement(XmlDocumentWithLocation document, ProjectRootElementCache projectRootElementCache)
            : base()
        {
            ErrorUtilities.VerifyThrowArgumentNull(document, "document");
            ErrorUtilities.VerifyThrowArgumentNull(projectRootElementCache, "projectRootElementCache");

            _projectRootElementCache = projectRootElementCache;
            _directory = NativeMethodsShared.GetCurrentDirectory();
            IncrementVersion();

            ProjectParser.Parse(document, this);
        }
예제 #19
0
        /// <summary>
        /// Constructor helper to load an XmlDocumentWithLocation from an XmlReader.
        /// May throw InvalidProjectFileException.
        /// Never returns null.
        /// </summary>
        private XmlDocumentWithLocation LoadDocument(XmlReader reader)
        {
            XmlDocumentWithLocation document = new XmlDocumentWithLocation();

            try
            {
                document.Load(reader);
            }
            catch (XmlException ex)
            {
                BuildEventFileInfo fileInfo = new BuildEventFileInfo(ex);

                ProjectFileErrorUtilities.ThrowInvalidProjectFile(fileInfo, "InvalidProjectFile", ex.Message);
            }

            return document;
        }
예제 #20
0
 /// <summary>
 /// Constructor without location information
 /// </summary>
 public XmlElementWithLocation(string prefix, string localName, string namespaceURI, XmlDocumentWithLocation document)
     : this(prefix, localName, namespaceURI, document, 0, 0)
 {
 }
예제 #21
0
        /// <summary>
        /// Initialize a ProjectRootElement instance from an existing document.
        /// Uses the global project collection.
        /// May throw InvalidProjectFileException.
        /// </summary>
        /// <remarks>
        /// This is ultimately for unit testing.
        /// Do not make public: we do not wish to expose particular XML API's.
        /// </remarks>
        internal static ProjectRootElement Open(XmlDocumentWithLocation document)
        {
            ErrorUtilities.VerifyThrow(document.FullPath == null, "Only virtual documents supported");

            return new ProjectRootElement(document, ProjectCollection.GlobalProjectCollection.ProjectRootElementCache);
        }
예제 #22
0
        /// <summary>
        /// Constructor helper to load an XmlDocumentWithLocation from an XmlReader.
        /// May throw InvalidProjectFileException.
        /// Never returns null.
        /// </summary>
        private XmlDocumentWithLocation LoadDocument(XmlReader reader, bool preserveFormatting)
        {
            XmlDocumentWithLocation document = new XmlDocumentWithLocation();
            document.PreserveWhitespace = preserveFormatting;

            try
            {
                document.Load(reader);
            }
            catch (XmlException ex)
            {
                BuildEventFileInfo fileInfo = new BuildEventFileInfo(ex);

                ProjectFileErrorUtilities.ThrowInvalidProjectFile(fileInfo, "InvalidProjectFile", ex.Message);
            }

            return document;
        }
예제 #23
0
        /// <summary>
        /// Parses the document into the provided ProjectRootElement.
        /// Throws InvalidProjectFileExceptions for syntax errors.
        /// </summary>
        /// <remarks>
        /// The code markers here used to be around the Project class constructor in the old code.
        /// In the new code, that's not very interesting; we are repurposing to wrap parsing the XML.
        /// </remarks>
        internal static void Parse(XmlDocumentWithLocation document, ProjectRootElement projectRootElement)
        {
#if MSBUILDENABLEVSPROFILING
            try
            {
                string projectFile = String.IsNullOrEmpty(projectRootElement.ProjectFileLocation.File) ? "(null)" : projectRootElement.ProjectFileLocation.File;
                string projectParseBegin = String.Format(CultureInfo.CurrentCulture, "Parse Project {0} - Begin", projectFile);
                DataCollection.CommentMarkProfile(8808, projectParseBegin);
#endif
#if (!STANDALONEBUILD)
                using (new CodeMarkerStartEnd(CodeMarkerEvent.perfMSBuildProjectConstructBegin, CodeMarkerEvent.perfMSBuildProjectConstructEnd))
#endif
            {
                ProjectParser parser = new ProjectParser(document, projectRootElement);
                parser.Parse();
            }
#if MSBUILDENABLEVSPROFILING 
            }
            finally
            {
                string projectFile = String.IsNullOrEmpty(projectRootElement.ProjectFileLocation.File) ? "(null)" : projectRootElement.ProjectFileLocation.File;
                string projectParseEnd = String.Format(CultureInfo.CurrentCulture, "Parse Project {0} - End", projectFile);
                DataCollection.CommentMarkProfile(8809, projectParseEnd);
            }
#endif
        }
예제 #24
0
 public void SaveReadOnly4()
 {
     var doc = new XmlDocumentWithLocation(loadAsReadOnly: true);
     doc.Load(_pathToCommonTargets);
     doc.Save(XmlWriter.Create(FileUtilities.GetTemporaryFile()));
 }
예제 #25
0
 public void SaveReadOnly2()
 {
     var doc = new XmlDocumentWithLocation(loadAsReadOnly: true);
     doc.Load(_pathToCommonTargets);
     doc.Save(new MemoryStream());
 }
예제 #26
0
        /// <summary>
        /// Initialize an in-memory, empty ProjectRootElement instance that can be saved later.
        /// Leaves the project dirty, indicating there are unsaved changes.
        /// </summary>
        private ProjectRootElement(ProjectRootElementCache projectRootElementCache)
        {
            ErrorUtilities.VerifyThrowArgumentNull(projectRootElementCache, "projectRootElementCache");

            _projectRootElementCache = projectRootElementCache;
            _directory = NativeMethodsShared.GetCurrentDirectory();
            IncrementVersion();

            XmlDocumentWithLocation document = new XmlDocumentWithLocation();

            XmlReaderSettings xrs = new XmlReaderSettings();
            xrs.DtdProcessing = DtdProcessing.Ignore;

            using (XmlReader xr = XmlReader.Create(new StringReader(ProjectRootElement.EmptyProjectFileContent), xrs))
            {
                document.Load(xr);
            }

            ProjectParser.Parse(document, this);
        }
예제 #27
0
 public void SaveReadOnly3()
 {
     var doc = new XmlDocumentWithLocation(loadAsReadOnly: true);
     doc.Load(_pathToCommonTargets);
     doc.Save(new StringWriter());
 }
예제 #28
0
        /// <summary>
        /// Initialize an in-memory, empty ProjectRootElement instance that can be saved later.
        /// Leaves the project dirty, indicating there are unsaved changes.
        /// </summary>
        private ProjectRootElement(ProjectRootElementCache projectRootElementCache, NewProjectFileOptions projectFileOptions)
        {
            ErrorUtilities.VerifyThrowArgumentNull(projectRootElementCache, "projectRootElementCache");

            _projectRootElementCache = projectRootElementCache;
            _directory = NativeMethodsShared.GetCurrentDirectory();
            IncrementVersion();

            XmlDocumentWithLocation document = new XmlDocumentWithLocation();

            XmlReaderSettings xrs = new XmlReaderSettings();
            xrs.DtdProcessing = DtdProcessing.Ignore;
            
            var emptyProjectFile = string.Format(EmptyProjectFileContent,
                (projectFileOptions & NewProjectFileOptions.IncludeXmlDeclaration) != 0 ? EmptyProjectFileXmlDeclaration : string.Empty,
                (projectFileOptions & NewProjectFileOptions.IncludeToolsVersion) != 0 ? EmptyProjectFileToolsVersion : string.Empty,
                (projectFileOptions & NewProjectFileOptions.IncludeXmlNamespace) != 0 ? EmptyProjectFileXmlNamespace : string.Empty);

            using (XmlReader xr = XmlReader.Create(new StringReader(emptyProjectFile), xrs))
            {
                document.Load(xr);
            }

            ProjectParser.Parse(document, this);
        }