PageRenderTime 48ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/Microsoft.Build/Microsoft.Build/Microsoft/Build/Evaluation/Project.cs

#
C# | 1678 lines | 1520 code | 158 blank | 0 comment | 152 complexity | d76c758d4fc87ae599c80bed986a662d MD5 | raw file
Possible License(s): Apache-2.0, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. namespace Microsoft.Build.Evaluation
  2. {
  3. using Microsoft.Build.BackEnd.Logging;
  4. using Microsoft.Build.Collections;
  5. using Microsoft.Build.Construction;
  6. using Microsoft.Build.Exceptions;
  7. using Microsoft.Build.Execution;
  8. using Microsoft.Build.Framework;
  9. using Microsoft.Build.Internal;
  10. using Microsoft.Build.Shared;
  11. using System;
  12. using System.Collections;
  13. using System.Collections.Generic;
  14. using System.Diagnostics;
  15. using System.IO;
  16. using System.Linq;
  17. using System.Runtime;
  18. using System.Runtime.CompilerServices;
  19. using System.Runtime.InteropServices;
  20. using System.Text;
  21. using System.Threading;
  22. using System.Xml;
  23. [DebuggerDisplay("{FullPath} EffectiveToolsVersion={ToolsVersion} #GlobalProperties={data.globalProperties.Count} #Properties={data.Properties.Count} #ItemTypes={data.ItemTypes.Count} #ItemDefinitions={data.ItemDefinitions.Count} #Items={data.Items.Count} #Targets={data.Targets.Count}")]
  24. public class Project
  25. {
  26. private static BuildEventContext buildEventContext = new BuildEventContext(0, -1, -2, -1);
  27. private Data data;
  28. private static readonly bool debugEvaluation = (Environment.GetEnvironmentVariable("MSBUILDDEBUGEVALUATION") != null);
  29. private int evaluatedToolsetCollectionVersion;
  30. private int evaluatedVersion;
  31. private int evaluationCounter;
  32. private bool explicitlyMarkedDirty;
  33. private BuildEnabledSetting isBuildEnabled;
  34. private ProjectLoadSettings loadSettings;
  35. private readonly Microsoft.Build.Evaluation.ProjectCollection projectCollection;
  36. private RenameHandlerDelegate renameHandler;
  37. private readonly ProjectRootElement xml;
  38. public Project() : this(ProjectRootElement.Create(Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection))
  39. {
  40. }
  41. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  42. public Project(ProjectRootElement xml) : this(xml, null, null)
  43. {
  44. }
  45. public Project(Microsoft.Build.Evaluation.ProjectCollection projectCollection) : this(ProjectRootElement.Create(projectCollection), null, null, projectCollection)
  46. {
  47. }
  48. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  49. public Project(string projectFile) : this(projectFile, null, null)
  50. {
  51. }
  52. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  53. public Project(XmlReader xmlReader) : this(xmlReader, null, null)
  54. {
  55. }
  56. public Project(IDictionary<string, string> globalProperties, string toolsVersion, Microsoft.Build.Evaluation.ProjectCollection projectCollection) : this(ProjectRootElement.Create(projectCollection), globalProperties, toolsVersion, projectCollection)
  57. {
  58. }
  59. public Project(ProjectRootElement xml, IDictionary<string, string> globalProperties, string toolsVersion) : this(xml, globalProperties, toolsVersion, Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection)
  60. {
  61. }
  62. public Project(string projectFile, IDictionary<string, string> globalProperties, string toolsVersion) : this(projectFile, globalProperties, toolsVersion, Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection)
  63. {
  64. }
  65. public Project(XmlReader xmlReader, IDictionary<string, string> globalProperties, string toolsVersion) : this(xmlReader, globalProperties, toolsVersion, Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection)
  66. {
  67. }
  68. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  69. public Project(ProjectRootElement xml, IDictionary<string, string> globalProperties, string toolsVersion, Microsoft.Build.Evaluation.ProjectCollection projectCollection) : this(xml, globalProperties, toolsVersion, projectCollection, ProjectLoadSettings.Default)
  70. {
  71. }
  72. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  73. public Project(string projectFile, IDictionary<string, string> globalProperties, string toolsVersion, Microsoft.Build.Evaluation.ProjectCollection projectCollection) : this(projectFile, globalProperties, toolsVersion, projectCollection, ProjectLoadSettings.Default)
  74. {
  75. }
  76. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  77. public Project(XmlReader xmlReader, IDictionary<string, string> globalProperties, string toolsVersion, Microsoft.Build.Evaluation.ProjectCollection projectCollection) : this(xmlReader, globalProperties, toolsVersion, projectCollection, ProjectLoadSettings.Default)
  78. {
  79. }
  80. public Project(ProjectRootElement xml, IDictionary<string, string> globalProperties, string toolsVersion, Microsoft.Build.Evaluation.ProjectCollection projectCollection, ProjectLoadSettings loadSettings)
  81. {
  82. this.projectCollection = Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection;
  83. this.isBuildEnabled = BuildEnabledSetting.UseProjectCollectionSetting;
  84. ErrorUtilities.VerifyThrowArgumentNull(xml, "xml");
  85. ErrorUtilities.VerifyThrowArgumentLengthIfNotNull(toolsVersion, "toolsVersion");
  86. ErrorUtilities.VerifyThrowArgumentNull(projectCollection, "projectCollection");
  87. this.xml = xml;
  88. this.projectCollection = projectCollection;
  89. this.Initialize(globalProperties, toolsVersion, loadSettings);
  90. }
  91. public Project(string projectFile, IDictionary<string, string> globalProperties, string toolsVersion, Microsoft.Build.Evaluation.ProjectCollection projectCollection, ProjectLoadSettings loadSettings)
  92. {
  93. this.projectCollection = Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection;
  94. this.isBuildEnabled = BuildEnabledSetting.UseProjectCollectionSetting;
  95. ErrorUtilities.VerifyThrowArgumentNull(projectFile, "projectFile");
  96. ErrorUtilities.VerifyThrowArgumentLengthIfNotNull(toolsVersion, "toolsVersion");
  97. ErrorUtilities.VerifyThrowArgumentNull(projectCollection, "projectCollection");
  98. this.projectCollection = projectCollection;
  99. projectFile = FileUtilities.NormalizePath(projectFile);
  100. try
  101. {
  102. this.xml = ProjectRootElement.OpenProjectOrSolution(projectFile, globalProperties, toolsVersion, this.LoggingService, projectCollection.ProjectRootElementCache, buildEventContext);
  103. }
  104. catch (InvalidProjectFileException exception)
  105. {
  106. this.LoggingService.LogInvalidProjectFileError(buildEventContext, exception);
  107. throw;
  108. }
  109. try
  110. {
  111. this.Initialize(globalProperties, toolsVersion, loadSettings);
  112. }
  113. catch (Exception exception2)
  114. {
  115. if (!ExceptionHandling.IsCriticalException(exception2))
  116. {
  117. projectCollection.TryUnloadProject(this.xml);
  118. }
  119. throw;
  120. }
  121. }
  122. public Project(XmlReader xmlReader, IDictionary<string, string> globalProperties, string toolsVersion, Microsoft.Build.Evaluation.ProjectCollection projectCollection, ProjectLoadSettings loadSettings)
  123. {
  124. this.projectCollection = Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection;
  125. this.isBuildEnabled = BuildEnabledSetting.UseProjectCollectionSetting;
  126. ErrorUtilities.VerifyThrowArgumentNull(xmlReader, "xmlReader");
  127. ErrorUtilities.VerifyThrowArgumentLengthIfNotNull(toolsVersion, "toolsVersion");
  128. ErrorUtilities.VerifyThrowArgumentNull(projectCollection, "projectCollection");
  129. this.projectCollection = projectCollection;
  130. try
  131. {
  132. this.xml = ProjectRootElement.Create(xmlReader, projectCollection);
  133. }
  134. catch (InvalidProjectFileException exception)
  135. {
  136. this.LoggingService.LogInvalidProjectFileError(buildEventContext, exception);
  137. throw;
  138. }
  139. this.Initialize(globalProperties, toolsVersion, loadSettings);
  140. }
  141. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  142. public IList<ProjectItem> AddItem(string itemType, string unevaluatedInclude)
  143. {
  144. return this.AddItem(itemType, unevaluatedInclude, null);
  145. }
  146. public IList<ProjectItem> AddItem(string itemType, string unevaluatedInclude, IEnumerable<KeyValuePair<string, string>> metadata)
  147. {
  148. ProjectItemElement element;
  149. ProjectElement element2 = this.GetAnySuitableExistingItemXml(itemType, unevaluatedInclude, metadata, out element);
  150. if (element == null)
  151. {
  152. ProjectItemElement reference = element2 as ProjectItemElement;
  153. if (reference != null)
  154. {
  155. element = this.xml.CreateItemElement(itemType, unevaluatedInclude);
  156. reference.Parent.InsertBeforeChild(element, reference);
  157. }
  158. else
  159. {
  160. ProjectItemGroupElement element4 = element2 as ProjectItemGroupElement;
  161. if (element4 != null)
  162. {
  163. element = element4.AddItem(itemType, unevaluatedInclude);
  164. }
  165. else
  166. {
  167. element = this.xml.AddItem(itemType, unevaluatedInclude);
  168. }
  169. }
  170. }
  171. return this.AddItemHelper(element, unevaluatedInclude, metadata);
  172. }
  173. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  174. public IList<ProjectItem> AddItemFast(string itemType, string unevaluatedInclude)
  175. {
  176. return this.AddItemFast(itemType, unevaluatedInclude, null);
  177. }
  178. public IList<ProjectItem> AddItemFast(string itemType, string unevaluatedInclude, IEnumerable<KeyValuePair<string, string>> metadata)
  179. {
  180. ProjectItemElement element3;
  181. ErrorUtilities.VerifyThrowArgumentLength(itemType, "itemType");
  182. ErrorUtilities.VerifyThrowArgumentLength(unevaluatedInclude, "unevalutedInclude");
  183. ProjectItemGroupElement element = null;
  184. foreach (ProjectItemGroupElement element2 in this.xml.ItemGroups)
  185. {
  186. if ((element2.Condition.Length <= 0) && ((element2.Count == 0) || MSBuildNameIgnoreCaseComparer.Default.Equals(itemType, element2.Items.First<ProjectItemElement>().ItemType)))
  187. {
  188. element = element2;
  189. break;
  190. }
  191. }
  192. if (element == null)
  193. {
  194. element = this.xml.AddItemGroup();
  195. }
  196. if (((element.Count == 0) || FileMatcher.HasWildcardsSemicolonItemOrPropertyReferences(unevaluatedInclude)) || !this.IsSuitableExistingItemXml(element.Items.First<ProjectItemElement>(), unevaluatedInclude, metadata))
  197. {
  198. element3 = this.xml.CreateItemElement(itemType, unevaluatedInclude);
  199. element.AppendChild(element3);
  200. }
  201. else
  202. {
  203. element3 = element.Items.First<ProjectItemElement>();
  204. }
  205. return this.AddItemHelper(element3, unevaluatedInclude, metadata);
  206. }
  207. private List<ProjectItem> AddItemHelper(ProjectItemElement itemElement, string unevaluatedInclude, IEnumerable<KeyValuePair<string, string>> metadata)
  208. {
  209. ProjectItem.ProjectItemFactory itemFactory = new ProjectItem.ProjectItemFactory(this, itemElement);
  210. List<ProjectItem> list = Evaluator<ProjectProperty, ProjectItem, ProjectMetadata, ProjectItemDefinition>.CreateItemsFromInclude(this.DirectoryPath, itemElement, itemFactory, unevaluatedInclude, this.data.Expander);
  211. foreach (ProjectItem item in list)
  212. {
  213. this.data.AddItem(item);
  214. this.data.AddItemIgnoringCondition(item);
  215. }
  216. if (metadata != null)
  217. {
  218. foreach (ProjectItem item2 in list)
  219. {
  220. foreach (KeyValuePair<string, string> pair in metadata)
  221. {
  222. item2.SetMetadataValue(pair.Key, pair.Value);
  223. }
  224. }
  225. }
  226. return list;
  227. }
  228. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  229. public bool Build()
  230. {
  231. return this.Build((string[]) null);
  232. }
  233. public bool Build(ILogger logger)
  234. {
  235. List<ILogger> loggers = new List<ILogger>(1) {
  236. logger
  237. };
  238. return this.Build((string[]) null, loggers, null);
  239. }
  240. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  241. public bool Build(string[] targets)
  242. {
  243. return this.Build(targets, null, null);
  244. }
  245. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  246. public bool Build(IEnumerable<ILogger> loggers)
  247. {
  248. return this.Build((string[]) null, loggers, null);
  249. }
  250. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  251. public bool Build(string target)
  252. {
  253. return this.Build(target, null, null);
  254. }
  255. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  256. public bool Build(string target, IEnumerable<ILogger> loggers)
  257. {
  258. return this.Build(target, loggers, null);
  259. }
  260. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  261. public bool Build(string[] targets, IEnumerable<ILogger> loggers)
  262. {
  263. return this.Build(targets, loggers, null);
  264. }
  265. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  266. public bool Build(IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers)
  267. {
  268. return this.Build((string[]) null, loggers, remoteLoggers);
  269. }
  270. public bool Build(string[] targets, IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers)
  271. {
  272. IDictionary<string, TargetResult> dictionary;
  273. if (!this.IsBuildEnabled)
  274. {
  275. this.LoggingService.LogError(buildEventContext, new BuildEventFileInfo(this.FullPath), "SecurityProjectBuildDisabled", new object[0]);
  276. return false;
  277. }
  278. ProjectInstance instance = this.CreateProjectInstance(this.LoggingService);
  279. if ((loggers == null) && (this.ProjectCollection.Loggers != null))
  280. {
  281. loggers = this.ProjectCollection.Loggers;
  282. }
  283. return instance.Build(targets, loggers, remoteLoggers, null, out dictionary);
  284. }
  285. public bool Build(string target, IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers)
  286. {
  287. string[] targets = (target == null) ? null : new string[] { target };
  288. return this.Build(targets, loggers, remoteLoggers);
  289. }
  290. public ProjectInstance CreateProjectInstance()
  291. {
  292. return this.CreateProjectInstance(this.LoggingService);
  293. }
  294. private ProjectInstance CreateProjectInstance(ILoggingService loggingServiceForEvaluation)
  295. {
  296. this.ReevaluateIfNecessary(loggingServiceForEvaluation);
  297. return new ProjectInstance(this.data, this.DirectoryPath, this.FullPath, this.ProjectCollection.HostServices, this.projectCollection.EnvironmentProperties);
  298. }
  299. internal string ExpandItemIncludeBestEffortLeaveEscaped(ProjectItemElement renamedItemElement)
  300. {
  301. if (renamedItemElement.Exclude.Length > 0)
  302. {
  303. return renamedItemElement.Include;
  304. }
  305. ProjectItem.ProjectItemFactory itemFactory = new ProjectItem.ProjectItemFactory(this, renamedItemElement);
  306. List<ProjectItem> list = Evaluator<ProjectProperty, ProjectItem, ProjectMetadata, ProjectItemDefinition>.CreateItemsFromInclude(this.DirectoryPath, renamedItemElement, itemFactory, renamedItemElement.Include, this.data.Expander);
  307. if (list.Count != 1)
  308. {
  309. return renamedItemElement.Include;
  310. }
  311. return list[0].EvaluatedIncludeEscaped;
  312. }
  313. internal string ExpandMetadataValueBestEffortLeaveEscaped(IMetadataTable metadataTable, string unevaluatedValue, IElementLocation metadataLocation)
  314. {
  315. ErrorUtilities.VerifyThrow(this.data.Expander.Metadata == null, "Should be null");
  316. this.data.Expander.Metadata = metadataTable;
  317. string str = this.data.Expander.ExpandIntoStringLeaveEscaped(unevaluatedValue, ExpanderOptions.ExpandAll, metadataLocation);
  318. this.data.Expander.Metadata = null;
  319. return str;
  320. }
  321. internal string ExpandPropertyValueBestEffortLeaveEscaped(string unevaluatedValue, IElementLocation propertyLocation)
  322. {
  323. return this.data.Expander.ExpandIntoStringLeaveEscaped(unevaluatedValue, ExpanderOptions.ExpandProperties, propertyLocation);
  324. }
  325. public string ExpandString(string unexpandedValue)
  326. {
  327. ErrorUtilities.VerifyThrowArgumentNull(unexpandedValue, "unexpandedValue");
  328. return this.data.Expander.ExpandIntoStringAndUnescape(unexpandedValue, ExpanderOptions.ExpandPropertiesAndItems, this.ProjectFileLocation);
  329. }
  330. private ProjectElement GetAnySuitableExistingItemXml(string itemType, string unevaluatedInclude, IEnumerable<KeyValuePair<string, string>> metadata, out ProjectItemElement suitableExistingItemXml)
  331. {
  332. suitableExistingItemXml = null;
  333. if (FileMatcher.HasWildcardsSemicolonItemOrPropertyReferences(unevaluatedInclude))
  334. {
  335. return null;
  336. }
  337. if ((metadata != null) && metadata.Any<KeyValuePair<string, string>>())
  338. {
  339. return null;
  340. }
  341. ProjectItemGroupElement element = null;
  342. ProjectItemElement element2 = null;
  343. foreach (ProjectItemGroupElement element3 in this.xml.ItemGroups)
  344. {
  345. if ((element3.Condition.Length <= 0) && !element3.DefinitelyAreNoChildrenWithWildcards)
  346. {
  347. if ((element == null) && (element3.Count == 0))
  348. {
  349. element = element3;
  350. }
  351. foreach (ProjectItemElement element4 in element3.Items)
  352. {
  353. if (!MSBuildNameIgnoreCaseComparer.Default.Equals(itemType, element4.ItemType))
  354. {
  355. continue;
  356. }
  357. if ((element == null) || (element.Count == 0))
  358. {
  359. element = element3;
  360. }
  361. if ((element2 == null) && (string.Compare(unevaluatedInclude, element4.Include, StringComparison.OrdinalIgnoreCase) < 0))
  362. {
  363. element2 = element4;
  364. }
  365. if (this.IsSuitableExistingItemXml(element4, unevaluatedInclude, metadata))
  366. {
  367. suitableExistingItemXml = element4;
  368. return null;
  369. }
  370. }
  371. continue;
  372. }
  373. }
  374. if (element2 == null)
  375. {
  376. return element;
  377. }
  378. return element2;
  379. }
  380. public static string GetEvaluatedItemIncludeEscaped(ProjectItem item)
  381. {
  382. ErrorUtilities.VerifyThrowArgumentNull(item, "item");
  383. return ((IItem) item).EvaluatedIncludeEscaped;
  384. }
  385. public static string GetEvaluatedItemIncludeEscaped(ProjectItemDefinition item)
  386. {
  387. ErrorUtilities.VerifyThrowArgumentNull(item, "item");
  388. return ((IItem) item).EvaluatedIncludeEscaped;
  389. }
  390. public ICollection<ProjectItem> GetItems(string itemType)
  391. {
  392. return this.data.GetItems(itemType);
  393. }
  394. public ICollection<ProjectItem> GetItemsByEvaluatedInclude(string evaluatedInclude)
  395. {
  396. return this.data.GetItemsByEvaluatedInclude(evaluatedInclude);
  397. }
  398. public ICollection<ProjectItem> GetItemsIgnoringCondition(string itemType)
  399. {
  400. return this.data.ItemsIgnoringCondition[itemType];
  401. }
  402. public IEnumerable<ProjectElement> GetLogicalProject()
  403. {
  404. return this.GetLogicalProject(this.Xml.AllChildren);
  405. }
  406. private IEnumerable<ProjectElement> GetLogicalProject(IEnumerable<ProjectElement> projectElements)
  407. {
  408. foreach (ProjectElement iteratorVariable0 in projectElements)
  409. {
  410. Func<Triple<ProjectImportElement, ProjectRootElement, int>, bool> predicate = null;
  411. ProjectImportElement import = iteratorVariable0 as ProjectImportElement;
  412. if (import == null)
  413. {
  414. yield return iteratorVariable0;
  415. }
  416. else
  417. {
  418. if (predicate == null)
  419. {
  420. predicate = triple => object.ReferenceEquals(triple.First, import);
  421. }
  422. IEnumerable<ProjectRootElement> iteratorVariable1 = from triple in this.data.ImportClosure.Where<Triple<ProjectImportElement, ProjectRootElement, int>>(predicate) select triple.Second;
  423. foreach (ProjectRootElement iteratorVariable2 in iteratorVariable1)
  424. {
  425. if (iteratorVariable2 != null)
  426. {
  427. IEnumerable<ProjectElement> logicalProject = this.GetLogicalProject(iteratorVariable2.AllChildren);
  428. foreach (ProjectElement iteratorVariable4 in logicalProject)
  429. {
  430. yield return iteratorVariable4;
  431. }
  432. }
  433. }
  434. }
  435. }
  436. }
  437. public static string GetMetadataValueEscaped(ProjectMetadata metadatum)
  438. {
  439. ErrorUtilities.VerifyThrowArgumentNull(metadatum, "metadatum");
  440. return metadatum.EvaluatedValueEscaped;
  441. }
  442. public static string GetMetadataValueEscaped(ProjectItem item, string name)
  443. {
  444. ErrorUtilities.VerifyThrowArgumentNull(item, "item");
  445. return ((IItem) item).GetMetadataValueEscaped(name);
  446. }
  447. public static string GetMetadataValueEscaped(ProjectItemDefinition item, string name)
  448. {
  449. ErrorUtilities.VerifyThrowArgumentNull(item, "item");
  450. return ((IItem) item).GetMetadataValueEscaped(name);
  451. }
  452. [DebuggerStepThrough]
  453. public ProjectProperty GetProperty(string name)
  454. {
  455. return this.data.Properties[name];
  456. }
  457. public string GetPropertyValue(string name)
  458. {
  459. return this.data.GetPropertyValue(name);
  460. }
  461. public static string GetPropertyValueEscaped(ProjectProperty property)
  462. {
  463. ErrorUtilities.VerifyThrowArgumentNull(property, "property");
  464. return ((IProperty) property).EvaluatedValueEscaped;
  465. }
  466. private void Initialize(IDictionary<string, string> globalProperties, string toolsVersion, ProjectLoadSettings loadSettings)
  467. {
  468. PropertyDictionary<ProjectPropertyInstance> dictionary = new PropertyDictionary<ProjectPropertyInstance>();
  469. foreach (ProjectPropertyInstance instance in this.ProjectCollection.GlobalPropertiesCollection)
  470. {
  471. ProjectPropertyInstance projectProperty = instance.DeepClone();
  472. dictionary.Set(projectProperty);
  473. }
  474. if (globalProperties != null)
  475. {
  476. foreach (KeyValuePair<string, string> pair in globalProperties)
  477. {
  478. dictionary.Set(new ProjectPropertyInstance(pair.Key, pair.Value));
  479. }
  480. }
  481. this.data = new Data(this, dictionary, toolsVersion);
  482. this.loadSettings = loadSettings;
  483. this.ReevaluateIfNecessary();
  484. this.renameHandler = delegate (string oldFullPath) {
  485. this.projectCollection.OnAfterRenameLoadedProject(oldFullPath, this);
  486. };
  487. this.xml.OnAfterProjectRename += this.renameHandler;
  488. this.renameHandler(null);
  489. }
  490. internal bool IsSuitableExistingItemXml(ProjectItemElement candidateExistingItemXml, string unevaluatedInclude, IEnumerable<KeyValuePair<string, string>> metadata)
  491. {
  492. if (((candidateExistingItemXml.Condition.Length == 0) && (candidateExistingItemXml.Exclude.Length == 0)) && candidateExistingItemXml.IncludeHasWildcards)
  493. {
  494. if (((metadata != null) && metadata.Any<KeyValuePair<string, string>>()) || (candidateExistingItemXml.Count > 0))
  495. {
  496. return false;
  497. }
  498. foreach (string str2 in this.data.Expander.ExpandIntoStringLeaveEscaped(candidateExistingItemXml.Include, ExpanderOptions.ExpandProperties, candidateExistingItemXml.IncludeLocation).Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
  499. {
  500. if (FileMatcher.HasWildcards(str2))
  501. {
  502. FileMatcher.Result result = FileMatcher.FileMatch(str2, unevaluatedInclude);
  503. if (result.isLegalFileSpec && result.isMatch)
  504. {
  505. return true;
  506. }
  507. }
  508. }
  509. }
  510. return false;
  511. }
  512. public void MarkDirty()
  513. {
  514. if (!this.DisableMarkDirty && !this.projectCollection.DisableMarkDirty)
  515. {
  516. this.explicitlyMarkedDirty = true;
  517. }
  518. }
  519. internal void ReAddExistingItemAfterItemTypeChange(ProjectItem item)
  520. {
  521. this.data.AddItem(item);
  522. this.data.AddItemIgnoringCondition(item);
  523. }
  524. public void ReevaluateIfNecessary()
  525. {
  526. this.ReevaluateIfNecessary(this.LoggingService);
  527. }
  528. private void ReevaluateIfNecessary(ILoggingService loggingServiceForEvaluation)
  529. {
  530. if ((!this.SkipEvaluation && !this.projectCollection.SkipEvaluation) && this.IsDirty)
  531. {
  532. try
  533. {
  534. Evaluator<ProjectProperty, ProjectItem, ProjectMetadata, ProjectItemDefinition>.Evaluate(this.data, this.xml, this.loadSettings, this.ProjectCollection.MaxNodeCount, this.ProjectCollection.EnvironmentProperties, loggingServiceForEvaluation, new ProjectItem.ProjectItemFactory(this), this.projectCollection, this.projectCollection.ProjectRootElementCache, buildEventContext, null);
  535. int version = this.Xml.Version;
  536. if (this.data.ImportClosure != null)
  537. {
  538. foreach (Triple<ProjectImportElement, ProjectRootElement, int> triple in this.data.ImportClosure)
  539. {
  540. version = (version < triple.Third) ? triple.Third : version;
  541. }
  542. }
  543. this.explicitlyMarkedDirty = false;
  544. this.evaluatedVersion = version;
  545. this.evaluatedToolsetCollectionVersion = this.ProjectCollection.ToolsetsVersion;
  546. this.evaluationCounter++;
  547. this.data.HasUnsavedChanges = false;
  548. ErrorUtilities.VerifyThrow(!this.IsDirty, "Should not be dirty now");
  549. }
  550. catch (InvalidProjectFileException exception)
  551. {
  552. loggingServiceForEvaluation.LogInvalidProjectFileError(buildEventContext, exception);
  553. throw;
  554. }
  555. }
  556. }
  557. public bool RemoveGlobalProperty(string name)
  558. {
  559. ErrorUtilities.VerifyThrowArgumentLength(name, "name");
  560. bool flag = this.data.GlobalPropertiesDictionary.Remove(name);
  561. if (flag)
  562. {
  563. this.ProjectCollection.AfterUpdateLoadedProjectGlobalProperties(this);
  564. this.MarkDirty();
  565. bool debugEvaluation = Project.debugEvaluation;
  566. }
  567. return flag;
  568. }
  569. public bool RemoveItem(ProjectItem item)
  570. {
  571. ErrorUtilities.VerifyThrowArgumentNull(item, "item");
  572. ErrorUtilities.VerifyThrowArgument(item.Project == this, "OM_IncorrectObjectAssociation", "ProjectItem", "Project");
  573. return this.RemoveItemHelper(item);
  574. }
  575. internal void RemoveItemBeforeItemTypeChange(ProjectItem item)
  576. {
  577. this.data.RemoveItem(item);
  578. }
  579. private bool RemoveItemHelper(ProjectItem item)
  580. {
  581. ErrorUtilities.VerifyThrowArgumentNull(item, "item");
  582. if ((item.Project == null) || (item.Xml.Parent == null))
  583. {
  584. return false;
  585. }
  586. ErrorUtilities.VerifyThrowArgument(item.Project == this, "OM_IncorrectObjectAssociation", "ProjectItem", "Project");
  587. this.VerifyThrowInvalidOperationNotImported(item.Xml.ContainingProject);
  588. this.SplitItemElementIfNecessary(item.Xml);
  589. ProjectElementContainer parent = item.Xml.Parent;
  590. item.Xml.Parent.RemoveChild(item.Xml);
  591. if (parent.Count == 0)
  592. {
  593. parent.Parent.RemoveChild(parent);
  594. }
  595. return this.data.RemoveItem(item);
  596. }
  597. public void RemoveItems(IEnumerable<ProjectItem> items)
  598. {
  599. ErrorUtilities.VerifyThrowArgumentNull(items, "items");
  600. List<ProjectItem> list = new List<ProjectItem>(items);
  601. foreach (ProjectItem item in list)
  602. {
  603. this.RemoveItemHelper(item);
  604. }
  605. }
  606. public bool RemoveProperty(ProjectProperty property)
  607. {
  608. ErrorUtilities.VerifyThrowArgumentNull(property, "property");
  609. ErrorUtilities.VerifyThrowInvalidOperation(!property.IsReservedProperty, "OM_ReservedName", property.Name);
  610. ErrorUtilities.VerifyThrowInvalidOperation(!property.IsGlobalProperty, "OM_GlobalProperty", property.Name);
  611. ErrorUtilities.VerifyThrowArgument(property.Xml.Parent != null, "OM_IncorrectObjectAssociation", "ProjectProperty", "Project");
  612. this.VerifyThrowInvalidOperationNotImported(property.Xml.ContainingProject);
  613. ProjectElementContainer parent = property.Xml.Parent;
  614. property.Xml.Parent.RemoveChild(property.Xml);
  615. if (parent.Count == 0)
  616. {
  617. parent.Parent.RemoveChild(parent);
  618. }
  619. return this.data.Properties.Remove(property.Name);
  620. }
  621. public void Save()
  622. {
  623. this.Xml.Save();
  624. }
  625. public void Save(TextWriter writer)
  626. {
  627. this.Xml.Save(writer);
  628. }
  629. public void Save(string path)
  630. {
  631. this.Xml.Save(path);
  632. }
  633. public void Save(Encoding encoding)
  634. {
  635. this.Xml.Save(encoding);
  636. }
  637. public void Save(string path, Encoding encoding)
  638. {
  639. this.Xml.Save(path, encoding);
  640. }
  641. public void SaveLogicalProject(TextWriter writer)
  642. {
  643. XmlDocument preprocessedDocument = Preprocessor.GetPreprocessedDocument(this);
  644. using (ProjectWriter writer2 = new ProjectWriter(writer))
  645. {
  646. writer2.Initialize(preprocessedDocument);
  647. preprocessedDocument.Save(writer2);
  648. }
  649. }
  650. public bool SetGlobalProperty(string name, string escapedValue)
  651. {
  652. ProjectPropertyInstance instance = this.data.GlobalPropertiesDictionary[name];
  653. if ((instance != null) && !(((IProperty) instance).EvaluatedValueEscaped != escapedValue))
  654. {
  655. return false;
  656. }
  657. string str = (instance == null) ? string.Empty : ((IProperty) instance).EvaluatedValueEscaped;
  658. this.data.GlobalPropertiesDictionary.Set(new ProjectPropertyInstance(name, escapedValue));
  659. this.data.Properties.Set(new ProjectProperty(this, name, escapedValue, true, false));
  660. this.ProjectCollection.AfterUpdateLoadedProjectGlobalProperties(this);
  661. this.MarkDirty();
  662. if (debugEvaluation)
  663. {
  664. string text1 = escapedValue.Substring(0, Math.Min(escapedValue.Length, 0x4b)) + ((escapedValue.Length > 0x4b) ? "..." : string.Empty);
  665. if (instance != null)
  666. {
  667. string text2 = str.Substring(0, Math.Min(str.Length, 0x4b)) + ((str.Length > 0x4b) ? "..." : string.Empty);
  668. }
  669. }
  670. return true;
  671. }
  672. public ProjectProperty SetProperty(string name, string unevaluatedValue)
  673. {
  674. ErrorUtilities.VerifyThrowArgumentLength(name, "name");
  675. ErrorUtilities.VerifyThrowArgumentNull(unevaluatedValue, "unevaluatedValue");
  676. ProjectProperty property = this.data.Properties[name];
  677. ErrorUtilities.VerifyThrowInvalidOperation((property == null) || !property.IsReservedProperty, "OM_ReservedName", name);
  678. ErrorUtilities.VerifyThrowInvalidOperation((property == null) || !property.IsGlobalProperty, "OM_GlobalProperty", name);
  679. if ((((property != null) && !property.IsEnvironmentProperty) && ((property.Xml.Parent != null) && (property.Xml.Parent.Parent != null))) && object.ReferenceEquals(property.Xml.ContainingProject, this.xml))
  680. {
  681. property.UnevaluatedValue = unevaluatedValue;
  682. }
  683. else
  684. {
  685. ProjectPropertyElement xml = this.xml.AddProperty(name, unevaluatedValue);
  686. property = new ProjectProperty(this, xml, unevaluatedValue, null);
  687. this.data.Properties[name] = property;
  688. }
  689. property.UpdateEvaluatedValue(this.ExpandPropertyValueBestEffortLeaveEscaped(unevaluatedValue, property.Xml.Location));
  690. return property;
  691. }
  692. internal bool SplitItemElementIfNecessary(ProjectItemElement itemElement)
  693. {
  694. if (!FileMatcher.HasWildcardsSemicolonItemOrPropertyReferences(itemElement.Include))
  695. {
  696. return false;
  697. }
  698. List<ProjectItem> list = new List<ProjectItem>();
  699. foreach (ProjectItem item in this.Items)
  700. {
  701. if (item.Xml == itemElement)
  702. {
  703. list.Add(item);
  704. }
  705. }
  706. if (list.Count <= 1)
  707. {
  708. return false;
  709. }
  710. foreach (ProjectItem item2 in list)
  711. {
  712. item2.SplitOwnItemElement();
  713. }
  714. itemElement.Parent.RemoveChild(itemElement);
  715. return true;
  716. }
  717. internal bool UsesProjectRootElement(ProjectRootElement xmlRootElement)
  718. {
  719. return (object.ReferenceEquals(this.Xml, xmlRootElement) || this.data.ImportClosure.Any<Triple<ProjectImportElement, ProjectRootElement, int>>(triple => object.ReferenceEquals(triple.Second, xmlRootElement)));
  720. }
  721. internal void VerifyThrowInvalidOperationNotImported(ProjectRootElement otherXml)
  722. {
  723. ErrorUtilities.VerifyThrowInvalidOperation(object.ReferenceEquals(this.Xml, otherXml), "OM_CannotModifyEvaluatedObjectInImportedFile", otherXml.Location.File);
  724. }
  725. internal void VerifyThrowInvalidOperationNotZombie()
  726. {
  727. ErrorUtilities.VerifyThrow(this.renameHandler != null, "OM_ProjectIsNoLongerActive");
  728. }
  729. internal void Zombify()
  730. {
  731. this.xml.OnAfterProjectRename -= this.renameHandler;
  732. this.renameHandler = null;
  733. }
  734. public ICollection<ProjectMetadata> AllEvaluatedItemDefinitionMetadata
  735. {
  736. get
  737. {
  738. ICollection<ProjectMetadata> allEvaluatedItemDefinitionMetadata = this.data.AllEvaluatedItemDefinitionMetadata;
  739. if (allEvaluatedItemDefinitionMetadata == null)
  740. {
  741. return ReadOnlyEmptyCollection<ProjectMetadata>.Instance;
  742. }
  743. return new ReadOnlyCollection<ProjectMetadata>(allEvaluatedItemDefinitionMetadata);
  744. }
  745. }
  746. public ICollection<ProjectItem> AllEvaluatedItems
  747. {
  748. get
  749. {
  750. ICollection<ProjectItem> allEvaluatedItems = this.data.AllEvaluatedItems;
  751. if (allEvaluatedItems == null)
  752. {
  753. return ReadOnlyEmptyCollection<ProjectItem>.Instance;
  754. }
  755. return new ReadOnlyCollection<ProjectItem>(allEvaluatedItems);
  756. }
  757. }
  758. public ICollection<ProjectProperty> AllEvaluatedProperties
  759. {
  760. get
  761. {
  762. ICollection<ProjectProperty> allEvaluatedProperties = this.data.AllEvaluatedProperties;
  763. if (allEvaluatedProperties == null)
  764. {
  765. return ReadOnlyEmptyCollection<ProjectProperty>.Instance;
  766. }
  767. return new ReadOnlyCollection<ProjectProperty>(allEvaluatedProperties);
  768. }
  769. }
  770. public IDictionary<string, List<string>> ConditionedProperties
  771. {
  772. [DebuggerStepThrough]
  773. get
  774. {
  775. return ReadOnlyDictionary<string, List<string>>.CreateWrapper(this.data.ConditionedProperties);
  776. }
  777. }
  778. public string DirectoryPath
  779. {
  780. [DebuggerStepThrough]
  781. get
  782. {
  783. return this.Xml.DirectoryPath;
  784. }
  785. }
  786. public bool DisableMarkDirty
  787. {
  788. [CompilerGenerated, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  789. get
  790. {
  791. return this.<DisableMarkDirty>k__BackingField;
  792. }
  793. [CompilerGenerated, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  794. set
  795. {
  796. this.<DisableMarkDirty>k__BackingField = value;
  797. }
  798. }
  799. public int EvaluationCounter
  800. {
  801. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  802. get
  803. {
  804. return this.evaluationCounter;
  805. }
  806. }
  807. public string FullPath
  808. {
  809. [DebuggerStepThrough]
  810. get
  811. {
  812. return this.Xml.FullPath;
  813. }
  814. [DebuggerStepThrough]
  815. set
  816. {
  817. this.Xml.FullPath = value;
  818. }
  819. }
  820. public IDictionary<string, string> GlobalProperties
  821. {
  822. [DebuggerStepThrough]
  823. get
  824. {
  825. if (this.data.GlobalPropertiesDictionary.Count == 0)
  826. {
  827. return ReadOnlyEmptyDictionary<string, string>.Instance;
  828. }
  829. Dictionary<string, string> backing = new Dictionary<string, string>(this.data.GlobalPropertiesDictionary.Count, MSBuildNameIgnoreCaseComparer.Default);
  830. foreach (ProjectPropertyInstance instance in this.data.GlobalPropertiesDictionary)
  831. {
  832. backing[instance.Name] = ((IProperty) instance).EvaluatedValueEscaped;
  833. }
  834. return ReadOnlyDictionary<string, string>.CreateWrapper(backing);
  835. }
  836. }
  837. public IList<ResolvedImport> Imports
  838. {
  839. get
  840. {
  841. List<ResolvedImport> list = new List<ResolvedImport>(this.data.ImportClosure.Count - 1);
  842. foreach (Triple<ProjectImportElement, ProjectRootElement, int> triple in this.data.ImportClosure)
  843. {
  844. if (triple.First != null)
  845. {
  846. list.Add(new ResolvedImport(triple.First, triple.Second));
  847. }
  848. }
  849. return list;
  850. }
  851. }
  852. public IList<ResolvedImport> ImportsIncludingDuplicates
  853. {
  854. get
  855. {
  856. ErrorUtilities.VerifyThrowInvalidOperation((this.loadSettings & ProjectLoadSettings.RecordDuplicateButNotCircularImports) != ProjectLoadSettings.Default, "OM_MustSetRecordDuplicateInputs");
  857. List<ResolvedImport> list = new List<ResolvedImport>(this.data.ImportClosureWithDuplicates.Count - 1);
  858. foreach (Triple<ProjectImportElement, ProjectRootElement, int> triple in this.data.ImportClosureWithDuplicates)
  859. {
  860. if (triple.First != null)
  861. {
  862. list.Add(new ResolvedImport(triple.First, triple.Second));
  863. }
  864. }
  865. return list;
  866. }
  867. }
  868. public bool IsBuildEnabled
  869. {
  870. get
  871. {
  872. switch (this.isBuildEnabled)
  873. {
  874. case BuildEnabledSetting.BuildEnabled:
  875. return true;
  876. case BuildEnabledSetting.BuildDisabled:
  877. return false;
  878. case BuildEnabledSetting.UseProjectCollectionSetting:
  879. return this.ProjectCollection.IsBuildEnabled;
  880. }
  881. ErrorUtilities.ThrowInternalErrorUnreachable();
  882. return false;
  883. }
  884. set
  885. {
  886. this.isBuildEnabled = value ? BuildEnabledSetting.BuildEnabled : BuildEnabledSetting.BuildDisabled;
  887. }
  888. }
  889. public bool IsDirty
  890. {
  891. get
  892. {
  893. if (this.explicitlyMarkedDirty)
  894. {
  895. bool debugEvaluation = Project.debugEvaluation;
  896. return true;
  897. }
  898. if (this.evaluatedVersion < this.xml.Version)
  899. {
  900. if (Project.debugEvaluation)
  901. {
  902. int count = this.xml.Count;
  903. }
  904. return true;
  905. }
  906. if (this.evaluatedToolsetCollectionVersion != this.ProjectCollection.ToolsetsVersion)
  907. {
  908. bool flag2 = Project.debugEvaluation;
  909. return true;
  910. }
  911. foreach (Triple<ProjectImportElement, ProjectRootElement, int> triple in this.data.ImportClosure)
  912. {
  913. if ((triple.Second.Version != triple.Third) || (this.evaluatedVersion < triple.Third))
  914. {
  915. if (Project.debugEvaluation)
  916. {
  917. string lastDirtyReason = triple.Second.LastDirtyReason;
  918. }
  919. return true;
  920. }
  921. }
  922. return false;
  923. }
  924. }
  925. public IDictionary<string, ProjectItemDefinition> ItemDefinitions
  926. {
  927. [DebuggerStepThrough]
  928. get
  929. {
  930. return this.data.ItemDefinitions;
  931. }
  932. }
  933. public ICollection<ProjectItem> Items
  934. {
  935. [DebuggerStepThrough]
  936. get
  937. {
  938. return new ReadOnlyCollection<ProjectItem>(this.data.Items);
  939. }
  940. }
  941. public ICollection<ProjectItem> ItemsIgnoringCondition
  942. {
  943. [DebuggerStepThrough]
  944. get
  945. {
  946. return new ReadOnlyCollection<ProjectItem>(this.data.ItemsIgnoringCondition);
  947. }
  948. }
  949. public ICollection<string> ItemTypes
  950. {
  951. [DebuggerStepThrough]
  952. get
  953. {
  954. return this.data.ItemTypes;
  955. }
  956. }
  957. internal ILoggingService LoggingService
  958. {
  959. [DebuggerStepThrough]
  960. get
  961. {
  962. return this.ProjectCollection.LoggingService;
  963. }
  964. }
  965. public Microsoft.Build.Evaluation.ProjectCollection ProjectCollection
  966. {
  967. [DebuggerStepThrough, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  968. get
  969. {
  970. return this.projectCollection;
  971. }
  972. }
  973. internal IElementLocation ProjectFileLocation
  974. {
  975. get
  976. {
  977. return this.xml.ProjectFileLocation;
  978. }
  979. }
  980. public ICollection<ProjectProperty> Properties
  981. {
  982. [DebuggerStepThrough]
  983. get
  984. {
  985. return new ReadOnlyCollection<ProjectProperty>(this.data.Properties);
  986. }
  987. }
  988. public bool SkipEvaluation
  989. {
  990. [CompilerGenerated, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  991. get
  992. {
  993. return this.<SkipEvaluation>k__BackingField;
  994. }
  995. [CompilerGenerated, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  996. set
  997. {
  998. this.<SkipEvaluation>k__BackingField = value;
  999. }
  1000. }
  1001. public IDictionary<string, ProjectTargetInstance> Targets
  1002. {
  1003. [DebuggerStepThrough]
  1004. get
  1005. {
  1006. return ReadOnlyDictionary<string, ProjectTargetInstance>.CreateWrapper(this.data.Targets);
  1007. }
  1008. }
  1009. public string ToolsVersion
  1010. {
  1011. get
  1012. {
  1013. return this.data.Toolset.ToolsVersion;
  1014. }
  1015. }
  1016. public ProjectRootElement Xml
  1017. {
  1018. [DebuggerStepThrough, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  1019. get
  1020. {
  1021. return this.xml;
  1022. }
  1023. }
  1024. private enum BuildEnabledSetting
  1025. {
  1026. BuildEnabled,
  1027. BuildDisabled,
  1028. UseProjectCollectionSetting
  1029. }
  1030. internal class Data : IEvaluatorData<ProjectProperty, ProjectItem, ProjectMetadata, ProjectItemDefinition>, IPropertyProvider<ProjectProperty>, IItemProvider<ProjectItem>
  1031. {
  1032. private readonly PropertyDictionary<ProjectPropertyInstance> globalProperties;
  1033. private ItemDictionary<ProjectItem> items;
  1034. private MultiDictionary<string, ProjectItem> itemsByEvaluatedInclude;
  1035. private string originalProjectToolsVersion;
  1036. private readonly Microsoft.Build.Evaluation.Project project;
  1037. private bool treatingHigherToolsVersionsAs40;
  1038. internal Data(Microsoft.Build.Evaluat

Large files files are truncated, but you can click here to view the full file