PageRenderTime 69ms CodeModel.GetById 34ms RepoModel.GetById 1ms app.codeStats 0ms

/Microsoft.Build/Microsoft.Build/Microsoft/Build/Construction/ProjectRootElement.cs

#
C# | 1088 lines | 985 code | 103 blank | 0 comment | 73 complexity | e9e48127a8294603a43a7f5513cfe351 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-3.0
  1. namespace Microsoft.Build.Construction
  2. {
  3. using Microsoft.Build.BackEnd.Logging;
  4. using Microsoft.Build.Collections;
  5. using Microsoft.Build.Evaluation;
  6. using Microsoft.Build.Exceptions;
  7. using Microsoft.Build.Framework;
  8. using Microsoft.Build.Internal;
  9. using Microsoft.Build.Shared;
  10. using Microsoft.Internal.Performance;
  11. using System;
  12. using System.Collections.Generic;
  13. using System.Diagnostics;
  14. using System.Globalization;
  15. using System.IO;
  16. using System.Runtime;
  17. using System.Runtime.CompilerServices;
  18. using System.Text;
  19. using System.Threading;
  20. using System.Xml;
  21. [DebuggerDisplay("{FullPath} #Children={Count} DefaultTargets={DefaultTargets} ToolsVersion={ToolsVersion} InitialTargets={InitialTargets}")]
  22. public class ProjectRootElement : ProjectElementContainer
  23. {
  24. private BuildEventContext buildEventContext;
  25. private static readonly System.Text.Encoding DefaultEncoding = System.Text.Encoding.UTF8;
  26. private string directory;
  27. private string dirtyParameter;
  28. private string dirtyReason;
  29. private const string EmptyProjectFileContent = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n</Project>";
  30. private System.Text.Encoding encoding;
  31. private static int globalVersionCounter = 0;
  32. private DateTime lastWriteTimeWhenRead;
  33. private RenameHandlerDelegate OnAfterProjectRename;
  34. private ElementLocation projectFileLocation;
  35. private Microsoft.Build.Evaluation.ProjectRootElementCache projectRootElementCache;
  36. private DateTime timeLastChangedUtc;
  37. private int version;
  38. private int versionOnDisk;
  39. internal event RenameHandlerDelegate OnAfterProjectRename
  40. {
  41. add
  42. {
  43. RenameHandlerDelegate delegate3;
  44. RenameHandlerDelegate onAfterProjectRename = this.OnAfterProjectRename;
  45. do
  46. {
  47. delegate3 = onAfterProjectRename;
  48. RenameHandlerDelegate delegate4 = (RenameHandlerDelegate) Delegate.Combine(delegate3, value);
  49. onAfterProjectRename = Interlocked.CompareExchange<RenameHandlerDelegate>(ref this.OnAfterProjectRename, delegate4, delegate3);
  50. }
  51. while (onAfterProjectRename != delegate3);
  52. }
  53. remove
  54. {
  55. RenameHandlerDelegate delegate3;
  56. RenameHandlerDelegate onAfterProjectRename = this.OnAfterProjectRename;
  57. do
  58. {
  59. delegate3 = onAfterProjectRename;
  60. RenameHandlerDelegate delegate4 = (RenameHandlerDelegate) Delegate.Remove(delegate3, value);
  61. onAfterProjectRename = Interlocked.CompareExchange<RenameHandlerDelegate>(ref this.OnAfterProjectRename, delegate4, delegate3);
  62. }
  63. while (onAfterProjectRename != delegate3);
  64. }
  65. }
  66. private ProjectRootElement(Microsoft.Build.Evaluation.ProjectRootElementCache projectRootElementCache)
  67. {
  68. this.dirtyReason = "first created project {0}";
  69. this.dirtyParameter = string.Empty;
  70. ErrorUtilities.VerifyThrowArgumentNull(projectRootElementCache, "projectRootElementCache");
  71. this.projectRootElementCache = projectRootElementCache;
  72. this.directory = NativeMethodsShared.GetCurrentDirectory();
  73. this.IncrementVersion();
  74. XmlDocumentWithLocation document = new XmlDocumentWithLocation();
  75. document.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n</Project>");
  76. ProjectParser.Parse(document, this);
  77. }
  78. private ProjectRootElement(XmlDocumentWithLocation document, Microsoft.Build.Evaluation.ProjectRootElementCache projectRootElementCache)
  79. {
  80. this.dirtyReason = "first created project {0}";
  81. this.dirtyParameter = string.Empty;
  82. ErrorUtilities.VerifyThrowArgumentNull(document, "document");
  83. ErrorUtilities.VerifyThrowArgumentNull(projectRootElementCache, "projectRootElementCache");
  84. this.projectRootElementCache = projectRootElementCache;
  85. this.directory = NativeMethodsShared.GetCurrentDirectory();
  86. this.IncrementVersion();
  87. ProjectParser.Parse(document, this);
  88. }
  89. internal ProjectRootElement(XmlReader xmlReader, Microsoft.Build.Evaluation.ProjectRootElementCache projectRootElementCache)
  90. {
  91. this.dirtyReason = "first created project {0}";
  92. this.dirtyParameter = string.Empty;
  93. ErrorUtilities.VerifyThrowArgumentNull(xmlReader, "xmlReader");
  94. ErrorUtilities.VerifyThrowArgumentNull(projectRootElementCache, "projectRootElementCache");
  95. this.projectRootElementCache = projectRootElementCache;
  96. this.directory = NativeMethodsShared.GetCurrentDirectory();
  97. this.IncrementVersion();
  98. ProjectParser.Parse(this.LoadDocument(xmlReader), this);
  99. }
  100. private ProjectRootElement(string path, Microsoft.Build.Evaluation.ProjectRootElementCache projectRootElementCache, BuildEventContext buildEventContext)
  101. {
  102. this.dirtyReason = "first created project {0}";
  103. this.dirtyParameter = string.Empty;
  104. ErrorUtilities.VerifyThrowArgumentLength(path, "path");
  105. ErrorUtilities.VerifyThrowInternalRooted(path);
  106. ErrorUtilities.VerifyThrowArgumentNull(projectRootElementCache, "projectRootElementCache");
  107. ErrorUtilities.VerifyThrowArgumentNull(buildEventContext, "buildEventContext");
  108. this.projectRootElementCache = projectRootElementCache;
  109. this.buildEventContext = buildEventContext;
  110. this.IncrementVersion();
  111. this.versionOnDisk = this.version;
  112. this.timeLastChangedUtc = DateTime.UtcNow;
  113. ProjectParser.Parse(this.LoadDocument(path), this);
  114. projectRootElementCache.AddEntry(this);
  115. }
  116. public ProjectImportElement AddImport(string project)
  117. {
  118. ErrorUtilities.VerifyThrowArgumentLength(project, "project");
  119. ProjectImportGroupElement element = null;
  120. foreach (ProjectImportGroupElement element2 in this.ImportGroupsReversed)
  121. {
  122. if (element2.Condition.Length <= 0)
  123. {
  124. element = element2;
  125. break;
  126. }
  127. }
  128. if (element != null)
  129. {
  130. return element.AddImport(project);
  131. }
  132. ProjectImportElement child = this.CreateImportElement(project);
  133. base.AppendChild(child);
  134. return child;
  135. }
  136. public ProjectImportGroupElement AddImportGroup()
  137. {
  138. ProjectImportGroupElement child = this.CreateImportGroupElement();
  139. base.AppendChild(child);
  140. return child;
  141. }
  142. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  143. public ProjectItemElement AddItem(string itemType, string include)
  144. {
  145. return this.AddItem(itemType, include, null);
  146. }
  147. public ProjectItemElement AddItem(string itemType, string include, IEnumerable<KeyValuePair<string, string>> metadata)
  148. {
  149. ErrorUtilities.VerifyThrowArgumentLength(itemType, "itemType");
  150. ErrorUtilities.VerifyThrowArgumentLength(include, "include");
  151. ProjectItemGroupElement element = null;
  152. foreach (ProjectItemGroupElement element2 in this.ItemGroups)
  153. {
  154. if (element2.Condition.Length > 0)
  155. {
  156. continue;
  157. }
  158. if ((element == null) && (element2.Count == 0))
  159. {
  160. element = element2;
  161. }
  162. foreach (ProjectItemElement element3 in element2.Items)
  163. {
  164. if (MSBuildNameIgnoreCaseComparer.Default.Equals(itemType, element3.ItemType))
  165. {
  166. element = element2;
  167. break;
  168. }
  169. }
  170. if ((element != null) && (element.Count > 0))
  171. {
  172. break;
  173. }
  174. }
  175. if (element == null)
  176. {
  177. element = this.AddItemGroup();
  178. }
  179. return element.AddItem(itemType, include, metadata);
  180. }
  181. public ProjectItemDefinitionElement AddItemDefinition(string itemType)
  182. {
  183. ErrorUtilities.VerifyThrowArgumentLength(itemType, "itemType");
  184. ProjectItemDefinitionGroupElement element = null;
  185. foreach (ProjectItemDefinitionGroupElement element2 in this.ItemDefinitionGroups)
  186. {
  187. if (element2.Condition.Length > 0)
  188. {
  189. continue;
  190. }
  191. foreach (ProjectItemDefinitionElement element3 in element2.ItemDefinitions)
  192. {
  193. if (MSBuildNameIgnoreCaseComparer.Default.Equals(itemType, element3.ItemType))
  194. {
  195. element = element2;
  196. break;
  197. }
  198. }
  199. if (element != null)
  200. {
  201. break;
  202. }
  203. }
  204. if (element == null)
  205. {
  206. element = this.AddItemDefinitionGroup();
  207. }
  208. ProjectItemDefinitionElement child = this.CreateItemDefinitionElement(itemType);
  209. element.AppendChild(child);
  210. return child;
  211. }
  212. public ProjectItemDefinitionGroupElement AddItemDefinitionGroup()
  213. {
  214. ProjectElement reference = null;
  215. foreach (ProjectItemDefinitionGroupElement element2 in this.ItemDefinitionGroupsReversed)
  216. {
  217. reference = element2;
  218. break;
  219. }
  220. if (reference == null)
  221. {
  222. foreach (ProjectPropertyGroupElement element3 in this.PropertyGroupsReversed)
  223. {
  224. reference = element3;
  225. break;
  226. }
  227. }
  228. ProjectItemDefinitionGroupElement child = this.CreateItemDefinitionGroupElement();
  229. base.InsertAfterChild(child, reference);
  230. return child;
  231. }
  232. public ProjectItemGroupElement AddItemGroup()
  233. {
  234. ProjectElement reference = null;
  235. foreach (ProjectItemGroupElement element2 in this.ItemGroupsReversed)
  236. {
  237. reference = element2;
  238. break;
  239. }
  240. if (reference == null)
  241. {
  242. foreach (ProjectPropertyGroupElement element3 in this.PropertyGroupsReversed)
  243. {
  244. reference = element3;
  245. break;
  246. }
  247. }
  248. ProjectItemGroupElement child = this.CreateItemGroupElement();
  249. if (reference == null)
  250. {
  251. base.AppendChild(child);
  252. return child;
  253. }
  254. base.InsertAfterChild(child, reference);
  255. return child;
  256. }
  257. public ProjectPropertyElement AddProperty(string name, string value)
  258. {
  259. ProjectPropertyGroupElement element = null;
  260. ProjectPropertyElement element2 = null;
  261. foreach (ProjectPropertyGroupElement element3 in this.PropertyGroups)
  262. {
  263. if (element3.Condition.Length <= 0)
  264. {
  265. if (element == null)
  266. {
  267. element = element3;
  268. }
  269. foreach (ProjectPropertyElement element4 in element3.Properties)
  270. {
  271. if ((element4.Condition.Length <= 0) && MSBuildNameIgnoreCaseComparer.Default.Equals(element4.Name, name))
  272. {
  273. element2 = element4;
  274. }
  275. }
  276. continue;
  277. }
  278. }
  279. if (element2 != null)
  280. {
  281. element2.Value = value;
  282. return element2;
  283. }
  284. if (element == null)
  285. {
  286. element = this.AddPropertyGroup();
  287. }
  288. return element.AddProperty(name, value);
  289. }
  290. public ProjectPropertyGroupElement AddPropertyGroup()
  291. {
  292. ProjectPropertyGroupElement reference = null;
  293. foreach (ProjectPropertyGroupElement element2 in this.PropertyGroupsReversed)
  294. {
  295. reference = element2;
  296. break;
  297. }
  298. ProjectPropertyGroupElement child = this.CreatePropertyGroupElement();
  299. base.InsertAfterChild(child, reference);
  300. return child;
  301. }
  302. public ProjectTargetElement AddTarget(string name)
  303. {
  304. ProjectTargetElement child = this.CreateTargetElement(name);
  305. base.AppendChild(child);
  306. return child;
  307. }
  308. public ProjectUsingTaskElement AddUsingTask(string name, string assemblyFile, string assemblyName)
  309. {
  310. ProjectUsingTaskElement child = this.CreateUsingTaskElement(name, assemblyFile, assemblyName);
  311. base.AppendChild(child);
  312. return child;
  313. }
  314. public static ProjectRootElement Create()
  315. {
  316. return Create(ProjectCollection.GlobalProjectCollection);
  317. }
  318. public static ProjectRootElement Create(ProjectCollection projectCollection)
  319. {
  320. ErrorUtilities.VerifyThrowArgumentNull(projectCollection, "projectCollection");
  321. return Create(projectCollection.ProjectRootElementCache);
  322. }
  323. internal static ProjectRootElement Create(Microsoft.Build.Evaluation.ProjectRootElementCache projectRootElementCache)
  324. {
  325. return new ProjectRootElement(projectRootElementCache);
  326. }
  327. public static ProjectRootElement Create(string path)
  328. {
  329. return Create(path, ProjectCollection.GlobalProjectCollection);
  330. }
  331. public static ProjectRootElement Create(XmlReader xmlReader)
  332. {
  333. return Create(xmlReader, ProjectCollection.GlobalProjectCollection);
  334. }
  335. public static ProjectRootElement Create(string path, ProjectCollection projectCollection)
  336. {
  337. ErrorUtilities.VerifyThrowArgumentLength(path, "path");
  338. ErrorUtilities.VerifyThrowArgumentNull(projectCollection, "projectCollection");
  339. return new ProjectRootElement(projectCollection.ProjectRootElementCache) { FullPath = path };
  340. }
  341. public static ProjectRootElement Create(XmlReader xmlReader, ProjectCollection projectCollection)
  342. {
  343. ErrorUtilities.VerifyThrowArgumentNull(projectCollection, "projectCollection");
  344. return new ProjectRootElement(xmlReader, projectCollection.ProjectRootElementCache);
  345. }
  346. public ProjectChooseElement CreateChooseElement()
  347. {
  348. return ProjectChooseElement.CreateDisconnected(this);
  349. }
  350. internal XmlElementWithLocation CreateElement(string name)
  351. {
  352. return (XmlElementWithLocation) base.XmlDocument.CreateElement(name, "http://schemas.microsoft.com/developer/msbuild/2003");
  353. }
  354. public ProjectImportElement CreateImportElement(string project)
  355. {
  356. return ProjectImportElement.CreateDisconnected(project, this);
  357. }
  358. public ProjectImportGroupElement CreateImportGroupElement()
  359. {
  360. return ProjectImportGroupElement.CreateDisconnected(this);
  361. }
  362. public ProjectItemDefinitionElement CreateItemDefinitionElement(string itemType)
  363. {
  364. return ProjectItemDefinitionElement.CreateDisconnected(itemType, this);
  365. }
  366. public ProjectItemDefinitionGroupElement CreateItemDefinitionGroupElement()
  367. {
  368. return ProjectItemDefinitionGroupElement.CreateDisconnected(this);
  369. }
  370. public ProjectItemElement CreateItemElement(string itemType)
  371. {
  372. return ProjectItemElement.CreateDisconnected(itemType, this);
  373. }
  374. public ProjectItemElement CreateItemElement(string itemType, string include)
  375. {
  376. ProjectItemElement element = ProjectItemElement.CreateDisconnected(itemType, this);
  377. element.Include = include;
  378. return element;
  379. }
  380. public ProjectItemGroupElement CreateItemGroupElement()
  381. {
  382. return ProjectItemGroupElement.CreateDisconnected(this);
  383. }
  384. public ProjectMetadataElement CreateMetadataElement(string name)
  385. {
  386. return ProjectMetadataElement.CreateDisconnected(name, this);
  387. }
  388. public ProjectMetadataElement CreateMetadataElement(string name, string unevaluatedValue)
  389. {
  390. ProjectMetadataElement element = ProjectMetadataElement.CreateDisconnected(name, this);
  391. element.Value = unevaluatedValue;
  392. return element;
  393. }
  394. public ProjectOnErrorElement CreateOnErrorElement(string executeTargets)
  395. {
  396. return ProjectOnErrorElement.CreateDisconnected(executeTargets, this);
  397. }
  398. public ProjectOtherwiseElement CreateOtherwiseElement()
  399. {
  400. return ProjectOtherwiseElement.CreateDisconnected(this);
  401. }
  402. public ProjectOutputElement CreateOutputElement(string taskParameter, string itemType, string propertyName)
  403. {
  404. return ProjectOutputElement.CreateDisconnected(taskParameter, itemType, propertyName, this);
  405. }
  406. public ProjectExtensionsElement CreateProjectExtensionsElement()
  407. {
  408. return ProjectExtensionsElement.CreateDisconnected(this);
  409. }
  410. private static ProjectRootElement CreateProjectFromPath(string projectFile, IDictionary<string, string> globalProperties, string toolsVersion, ILoggingService loggingService, Microsoft.Build.Evaluation.ProjectRootElementCache projectRootElementCache, BuildEventContext buildEventContext)
  411. {
  412. ProjectRootElement element;
  413. ErrorUtilities.VerifyThrowInternalRooted(projectFile);
  414. try
  415. {
  416. if (FileUtilities.IsVCProjFilename(projectFile))
  417. {
  418. ProjectFileErrorUtilities.ThrowInvalidProjectFile(new BuildEventFileInfo(projectFile), "ProjectUpgradeNeededToVcxProj", new object[] { projectFile });
  419. }
  420. element = new ProjectRootElement(projectFile, projectRootElementCache, buildEventContext);
  421. }
  422. catch (InvalidProjectFileException)
  423. {
  424. throw;
  425. }
  426. catch (Exception exception)
  427. {
  428. if (!ExceptionHandling.NotExpectedException(exception))
  429. {
  430. ProjectFileErrorUtilities.ThrowInvalidProjectFile(new BuildEventFileInfo(projectFile), exception, "InvalidProjectFile", new object[] { exception.Message });
  431. }
  432. throw;
  433. }
  434. return element;
  435. }
  436. public ProjectPropertyElement CreatePropertyElement(string name)
  437. {
  438. return ProjectPropertyElement.CreateDisconnected(name, this);
  439. }
  440. public ProjectPropertyGroupElement CreatePropertyGroupElement()
  441. {
  442. return ProjectPropertyGroupElement.CreateDisconnected(this);
  443. }
  444. public ProjectTargetElement CreateTargetElement(string name)
  445. {
  446. return ProjectTargetElement.CreateDisconnected(name, this);
  447. }
  448. public ProjectTaskElement CreateTaskElement(string name)
  449. {
  450. return ProjectTaskElement.CreateDisconnected(name, this);
  451. }
  452. public ProjectUsingTaskBodyElement CreateUsingTaskBodyElement(string evaluate, string body)
  453. {
  454. return ProjectUsingTaskBodyElement.CreateDisconnected(evaluate, body, this);
  455. }
  456. public ProjectUsingTaskElement CreateUsingTaskElement(string taskName, string assemblyFile, string assemblyName)
  457. {
  458. return ProjectUsingTaskElement.CreateDisconnected(taskName, assemblyFile, assemblyName, this);
  459. }
  460. public ProjectUsingTaskParameterElement CreateUsingTaskParameterElement(string name, string output, string required, string parameterType)
  461. {
  462. return ProjectUsingTaskParameterElement.CreateDisconnected(name, output, required, parameterType, this);
  463. }
  464. public UsingTaskParameterGroupElement CreateUsingTaskParameterGroupElement()
  465. {
  466. return UsingTaskParameterGroupElement.CreateDisconnected(this);
  467. }
  468. public ProjectWhenElement CreateWhenElement(string condition)
  469. {
  470. return ProjectWhenElement.CreateDisconnected(condition, this);
  471. }
  472. private void IncrementVersion()
  473. {
  474. this.version = Interlocked.Increment(ref globalVersionCounter);
  475. }
  476. private XmlDocumentWithLocation LoadDocument(string fullPath)
  477. {
  478. ErrorUtilities.VerifyThrowInternalRooted(fullPath);
  479. XmlDocumentWithLocation location = new XmlDocumentWithLocation();
  480. Microsoft.Internal.Performance.CodeMarkerStartEnd end = new Microsoft.Internal.Performance.CodeMarkerStartEnd(Microsoft.Internal.Performance.CodeMarkerEvent.perfMSBuildProjectLoadFromFileBegin, Microsoft.Internal.Performance.CodeMarkerEvent.perfMSBuildProjectLoadFromFileEnd);
  481. try
  482. {
  483. using (XmlTextReader reader = new XmlTextReader(fullPath))
  484. {
  485. reader.Read();
  486. this.encoding = reader.Encoding;
  487. location.Load(reader);
  488. }
  489. location.FullPath = fullPath;
  490. this.projectFileLocation = new ElementLocation(fullPath);
  491. this.directory = Path.GetDirectoryName(fullPath);
  492. if (base.XmlDocument != null)
  493. {
  494. base.XmlDocument.FullPath = fullPath;
  495. }
  496. this.lastWriteTimeWhenRead = FileUtilities.GetFileInfoNoThrow(fullPath).LastWriteTime;
  497. }
  498. catch (Exception exception)
  499. {
  500. BuildEventFileInfo info;
  501. if (ExceptionHandling.NotExpectedIoOrXmlException(exception))
  502. {
  503. throw;
  504. }
  505. XmlException e = exception as XmlException;
  506. if (e != null)
  507. {
  508. info = new BuildEventFileInfo(e);
  509. }
  510. else
  511. {
  512. info = new BuildEventFileInfo(fullPath);
  513. }
  514. ProjectFileErrorUtilities.ThrowInvalidProjectFile(info, exception, "InvalidProjectFile", new object[] { exception.Message });
  515. }
  516. finally
  517. {
  518. if (end != null)
  519. {
  520. end.Dispose();
  521. }
  522. }
  523. return location;
  524. }
  525. private XmlDocumentWithLocation LoadDocument(XmlReader reader)
  526. {
  527. XmlDocumentWithLocation location = new XmlDocumentWithLocation();
  528. try
  529. {
  530. location.Load(reader);
  531. }
  532. catch (XmlException exception)
  533. {
  534. BuildEventFileInfo projectFile = new BuildEventFileInfo(exception);
  535. ProjectFileErrorUtilities.ThrowInvalidProjectFile(projectFile, "InvalidProjectFile", new object[] { exception.Message });
  536. }
  537. return location;
  538. }
  539. internal sealed override void MarkDirty(string reason, string param)
  540. {
  541. this.IncrementVersion();
  542. this.dirtyReason = reason;
  543. this.dirtyParameter = param;
  544. this.timeLastChangedUtc = DateTime.UtcNow;
  545. }
  546. internal static ProjectRootElement Open(XmlDocumentWithLocation document)
  547. {
  548. ErrorUtilities.VerifyThrow(document.FullPath == null, "Only virtual documents supported");
  549. return new ProjectRootElement(document, ProjectCollection.GlobalProjectCollection.ProjectRootElementCache);
  550. }
  551. public static ProjectRootElement Open(string path)
  552. {
  553. return Open(path, ProjectCollection.GlobalProjectCollection);
  554. }
  555. public static ProjectRootElement Open(string path, ProjectCollection projectCollection)
  556. {
  557. ErrorUtilities.VerifyThrowArgumentLength(path, "path");
  558. ErrorUtilities.VerifyThrowArgumentNull(projectCollection, "projectCollection");
  559. path = FileUtilities.NormalizePath(path);
  560. return Open(path, projectCollection.ProjectRootElementCache);
  561. }
  562. internal static ProjectRootElement Open(string path, Microsoft.Build.Evaluation.ProjectRootElementCache projectRootElementCache)
  563. {
  564. ErrorUtilities.VerifyThrowInternalRooted(path);
  565. return projectRootElementCache.Get(path, () => new ProjectRootElement(path, projectRootElementCache, new BuildEventContext(0, -2, -2, -1)));
  566. }
  567. internal static ProjectRootElement OpenProjectOrSolution(string fullPath, IDictionary<string, string> globalProperties, string toolsVersion, ILoggingService loggingService, Microsoft.Build.Evaluation.ProjectRootElementCache projectRootElementCache, BuildEventContext buildEventContext)
  568. {
  569. ErrorUtilities.VerifyThrowInternalRooted(fullPath);
  570. return projectRootElementCache.Get(fullPath, () => CreateProjectFromPath(fullPath, globalProperties, toolsVersion, loggingService, projectRootElementCache, buildEventContext));
  571. }
  572. public void Save()
  573. {
  574. this.Save(this.Encoding);
  575. }
  576. public void Save(TextWriter writer)
  577. {
  578. using (ProjectWriter writer2 = new ProjectWriter(writer))
  579. {
  580. writer2.Initialize(base.XmlDocument);
  581. base.XmlDocument.Save(writer2);
  582. }
  583. this.versionOnDisk = this.Version;
  584. }
  585. public void Save(string path)
  586. {
  587. this.Save(path, this.Encoding);
  588. }
  589. public void Save(System.Text.Encoding saveEncoding)
  590. {
  591. ErrorUtilities.VerifyThrowInvalidOperation(this.projectFileLocation != null, "OM_MustSetFileNameBeforeSave");
  592. Directory.CreateDirectory(this.DirectoryPath);
  593. using (new Microsoft.Internal.Performance.CodeMarkerStartEnd(Microsoft.Internal.Performance.CodeMarkerEvent.perfMSBuildProjectSaveToFileBegin, Microsoft.Internal.Performance.CodeMarkerEvent.perfMSBuildProjectSaveToFileEnd))
  594. {
  595. if (this.HasUnsavedChanges || (saveEncoding != this.Encoding))
  596. {
  597. using (ProjectWriter writer = new ProjectWriter(this.projectFileLocation.File, saveEncoding))
  598. {
  599. writer.Initialize(base.XmlDocument);
  600. base.XmlDocument.Save(writer);
  601. }
  602. this.encoding = saveEncoding;
  603. this.lastWriteTimeWhenRead = FileUtilities.GetFileInfoNoThrow(this.projectFileLocation.File).LastWriteTime;
  604. this.versionOnDisk = this.Version;
  605. }
  606. }
  607. }
  608. public void Save(string path, System.Text.Encoding encoding)
  609. {
  610. this.FullPath = path;
  611. this.Save(encoding);
  612. }
  613. public static ProjectRootElement TryOpen(string path)
  614. {
  615. ErrorUtilities.VerifyThrowArgumentLength(path, "path");
  616. return TryOpen(path, ProjectCollection.GlobalProjectCollection);
  617. }
  618. public static ProjectRootElement TryOpen(string path, ProjectCollection projectCollection)
  619. {
  620. ErrorUtilities.VerifyThrowArgumentLength(path, "path");
  621. ErrorUtilities.VerifyThrowArgumentNull(projectCollection, "projectCollection");
  622. path = FileUtilities.NormalizePath(path);
  623. return projectCollection.ProjectRootElementCache.TryGet(path);
  624. }
  625. internal override void VerifyThrowInvalidOperationAcceptableLocation(ProjectElementContainer parent, ProjectElement previousSibling, ProjectElement nextSibling)
  626. {
  627. ErrorUtilities.ThrowInvalidOperation("OM_CannotAcceptParent", new object[0]);
  628. }
  629. public ICollection<ProjectChooseElement> ChooseElements
  630. {
  631. get
  632. {
  633. return new ReadOnlyCollection<ProjectChooseElement>(new FilteringEnumerable<ProjectElement, ProjectChooseElement>(base.Children));
  634. }
  635. }
  636. public override string Condition
  637. {
  638. get
  639. {
  640. return null;
  641. }
  642. set
  643. {
  644. ErrorUtilities.ThrowInvalidOperation("OM_CannotGetSetCondition", new object[0]);
  645. }
  646. }
  647. internal override IElementLocation ConditionLocation
  648. {
  649. get
  650. {
  651. ErrorUtilities.ThrowInternalError("Should not evaluate this", new object[0]);
  652. return null;
  653. }
  654. }
  655. internal bool ContainsTargetsWithReturnsAttribute
  656. {
  657. [CompilerGenerated, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  658. get
  659. {
  660. return this.<ContainsTargetsWithReturnsAttribute>k__BackingField;
  661. }
  662. [CompilerGenerated, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  663. set
  664. {
  665. this.<ContainsTargetsWithReturnsAttribute>k__BackingField = value;
  666. }
  667. }
  668. public string DefaultTargets
  669. {
  670. [DebuggerStepThrough]
  671. get
  672. {
  673. return ProjectXmlUtilities.GetAttributeValue(base.XmlElement, "DefaultTargets");
  674. }
  675. [DebuggerStepThrough]
  676. set
  677. {
  678. ProjectXmlUtilities.SetOrRemoveAttribute(base.XmlElement, "DefaultTargets", value);
  679. this.MarkDirty("Set Project DefaultTargets to '{0}'", value);
  680. }
  681. }
  682. internal IElementLocation DefaultTargetsLocation
  683. {
  684. get
  685. {
  686. return base.XmlElement.GetAttributeLocation("DefaultTargets");
  687. }
  688. }
  689. public string DirectoryPath
  690. {
  691. [DebuggerStepThrough]
  692. get
  693. {
  694. return (this.directory ?? string.Empty);
  695. }
  696. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  697. internal set
  698. {
  699. this.directory = value;
  700. }
  701. }
  702. public System.Text.Encoding Encoding
  703. {
  704. get
  705. {
  706. if (this.encoding == null)
  707. {
  708. XmlDeclaration firstChild = base.XmlDocument.FirstChild as XmlDeclaration;
  709. if ((firstChild != null) && (firstChild.Encoding.Length > 0))
  710. {
  711. this.encoding = System.Text.Encoding.GetEncoding(firstChild.Encoding);
  712. }
  713. }
  714. return (this.encoding ?? DefaultEncoding);
  715. }
  716. }
  717. public string FullPath
  718. {
  719. get
  720. {
  721. if (this.projectFileLocation == null)
  722. {
  723. return null;
  724. }
  725. return this.projectFileLocation.File;
  726. }
  727. set
  728. {
  729. ErrorUtilities.VerifyThrowArgumentLength(value, "value");
  730. string a = (this.projectFileLocation != null) ? this.projectFileLocation.File : null;
  731. string b = FileUtilities.NormalizePath(value);
  732. if (!string.Equals(a, b, StringComparison.OrdinalIgnoreCase))
  733. {
  734. this.projectFileLocation = new ElementLocation(b);
  735. this.directory = Path.GetDirectoryName(b);
  736. if (base.XmlDocument != null)
  737. {
  738. base.XmlDocument.FullPath = b;
  739. }
  740. if (a == null)
  741. {
  742. this.projectRootElementCache.AddEntry(this);
  743. }
  744. else
  745. {
  746. this.projectRootElementCache.RenameEntry(a, this);
  747. }
  748. RenameHandlerDelegate onAfterProjectRename = this.OnAfterProjectRename;
  749. if (onAfterProjectRename != null)
  750. {
  751. onAfterProjectRename(a);
  752. }
  753. this.MarkDirty("Set project FullPath to '{0}'", this.FullPath);
  754. }
  755. }
  756. }
  757. public bool HasUnsavedChanges
  758. {
  759. get
  760. {
  761. return (this.Version != this.versionOnDisk);
  762. }
  763. }
  764. public ICollection<ProjectImportGroupElement> ImportGroups
  765. {
  766. get
  767. {
  768. return new ReadOnlyCollection<ProjectImportGroupElement>(new FilteringEnumerable<ProjectElement, ProjectImportGroupElement>(base.Children));
  769. }
  770. }
  771. public ICollection<ProjectImportGroupElement> ImportGroupsReversed
  772. {
  773. get
  774. {
  775. return new ReadOnlyCollection<ProjectImportGroupElement>(new FilteringEnumerable<ProjectElement, ProjectImportGroupElement>(base.ChildrenReversed));
  776. }
  777. }
  778. public ICollection<ProjectImportElement> Imports
  779. {
  780. get
  781. {
  782. return new ReadOnlyCollection<ProjectImportElement>(new FilteringEnumerable<ProjectElement, ProjectImportElement>(base.AllChildren));
  783. }
  784. }
  785. public string InitialTargets
  786. {
  787. [DebuggerStepThrough]
  788. get
  789. {
  790. return ProjectXmlUtilities.GetAttributeValue(base.XmlElement, "InitialTargets");
  791. }
  792. [DebuggerStepThrough]
  793. set
  794. {
  795. ProjectXmlUtilities.SetOrRemoveAttribute(base.XmlElement, "InitialTargets", value);
  796. this.MarkDirty("Set project InitialTargets to '{0}'", value);
  797. }
  798. }
  799. internal IElementLocation InitialTargetsLocation
  800. {
  801. get
  802. {
  803. return base.XmlElement.GetAttributeLocation("InitialTargets");
  804. }
  805. }
  806. public ICollection<ProjectItemDefinitionGroupElement> ItemDefinitionGroups
  807. {
  808. get
  809. {
  810. return new ReadOnlyCollection<ProjectItemDefinitionGroupElement>(new FilteringEnumerable<ProjectElement, ProjectItemDefinitionGroupElement>(base.Children));
  811. }
  812. }
  813. public ICollection<ProjectItemDefinitionGroupElement> ItemDefinitionGroupsReversed
  814. {
  815. get
  816. {
  817. return new ReadOnlyCollection<ProjectItemDefinitionGroupElement>(new FilteringEnumerable<ProjectElement, ProjectItemDefinitionGroupElement>(base.ChildrenReversed));
  818. }
  819. }
  820. public ICollection<ProjectItemDefinitionElement> ItemDefinitions
  821. {
  822. get
  823. {
  824. return new ReadOnlyCollection<ProjectItemDefinitionElement>(new FilteringEnumerable<ProjectElement, ProjectItemDefinitionElement>(base.AllChildren));
  825. }
  826. }
  827. public ICollection<ProjectItemGroupElement> ItemGroups
  828. {
  829. get
  830. {
  831. return new ReadOnlyCollection<ProjectItemGroupElement>(new FilteringEnumerable<ProjectElement, ProjectItemGroupElement>(base.Children));
  832. }
  833. }
  834. public ICollection<ProjectItemGroupElement> ItemGroupsReversed
  835. {
  836. get
  837. {
  838. return new ReadOnlyCollection<ProjectItemGroupElement>(new FilteringEnumerable<ProjectElement, ProjectItemGroupElement>(base.ChildrenReversed));
  839. }
  840. }
  841. public ICollection<ProjectItemElement> Items
  842. {
  843. get
  844. {
  845. return new ReadOnlyCollection<ProjectItemElement>(new FilteringEnumerable<ProjectElement, ProjectItemElement>(base.AllChildren));
  846. }
  847. }
  848. internal string LastDirtyReason
  849. {
  850. get
  851. {
  852. if (this.dirtyReason == null)
  853. {
  854. return null;
  855. }
  856. return string.Format(CultureInfo.InvariantCulture, this.dirtyReason, new object[] { this.dirtyParameter });
  857. }
  858. }
  859. public DateTime LastWriteTimeWhenRead
  860. {
  861. [DebuggerStepThrough, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  862. get
  863. {
  864. return this.lastWriteTimeWhenRead;
  865. }
  866. }
  867. internal ProjectExtensionsElement ProjectExtensions
  868. {
  869. get
  870. {
  871. foreach (ProjectElement element in base.ChildrenReversed)
  872. {
  873. ProjectExtensionsElement element2 = element as ProjectExtensionsElement;
  874. if (element2 != null)
  875. {
  876. return element2;
  877. }
  878. }
  879. return null;
  880. }
  881. }
  882. internal IElementLocation ProjectFileLocation
  883. {
  884. get
  885. {
  886. return (this.projectFileLocation ?? ElementLocation.EmptyLocation);
  887. }
  888. }
  889. internal Microsoft.Build.Evaluation.ProjectRootElementCache ProjectRootElementCache
  890. {
  891. [DebuggerStepThrough, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  892. get
  893. {
  894. return this.projectRootElementCache;
  895. }
  896. }
  897. public ICollection<ProjectPropertyElement> Properties
  898. {
  899. get
  900. {
  901. return new ReadOnlyCollection<ProjectPropertyElement>(new FilteringEnumerable<ProjectElement, ProjectPropertyElement>(base.AllChildren));
  902. }
  903. }
  904. public ICollection<ProjectPropertyGroupElement> PropertyGroups
  905. {
  906. get
  907. {
  908. return new ReadOnlyCollection<ProjectPropertyGroupElement>(new FilteringEnumerable<ProjectElement, ProjectPropertyGroupElement>(base.Children));
  909. }
  910. }
  911. public ICollection<ProjectPropertyGroupElement> PropertyGroupsReversed
  912. {
  913. get
  914. {
  915. return new ReadOnlyCollection<ProjectPropertyGroupElement>(new FilteringEnumerable<ProjectElement, ProjectPropertyGroupElement>(base.ChildrenReversed));
  916. }
  917. }
  918. public string RawXml
  919. {
  920. get
  921. {
  922. using (StringWriter writer = new StringWriter(CultureInfo.InvariantCulture))
  923. {
  924. using (ProjectWriter writer2 = new ProjectWriter(writer))
  925. {
  926. writer2.Initialize(base.XmlDocument);
  927. base.XmlDocument.Save(writer2);
  928. }
  929. return writer.ToString();
  930. }
  931. }
  932. }
  933. public ICollection<ProjectTargetElement> Targets
  934. {
  935. get
  936. {
  937. return new ReadOnlyCollection<ProjectTargetElement>(new FilteringEnumerable<ProjectElement, ProjectTargetElement>(base.Children));
  938. }
  939. }
  940. public DateTime TimeLastChanged
  941. {
  942. [DebuggerStepThrough]
  943. get
  944. {
  945. return this.timeLastChangedUtc.ToLocalTime();
  946. }
  947. }
  948. public string ToolsVersion
  949. {
  950. [DebuggerStepThrough]
  951. get
  952. {
  953. return ProjectXmlUtilities.GetAttributeValue(base.XmlElement, "ToolsVersion");
  954. }
  955. [DebuggerStepThrough]
  956. set
  957. {
  958. ProjectXmlUtilities.SetOrRemoveAttribute(base.XmlElement, "ToolsVersion", value);
  959. this.MarkDirty("Set project ToolsVersion {0}", value);
  960. }
  961. }
  962. internal IElementLocation ToolsVersionLocation
  963. {
  964. get
  965. {
  966. return base.XmlElement.GetAttributeLocation("ToolsVersion");
  967. }
  968. }
  969. public ICollection<ProjectUsingTaskElement> UsingTasks
  970. {
  971. get
  972. {
  973. return new ReadOnlyCollection<ProjectUsingTaskElement>(new FilteringEnumerable<ProjectElement, ProjectUsingTaskElement>(base.Children));
  974. }
  975. }
  976. public int Version
  977. {
  978. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  979. get
  980. {
  981. return this.version;
  982. }
  983. }
  984. }
  985. }