PageRenderTime 42ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/Microsoft.Build/Microsoft.Build/Microsoft/Build/Execution/TaskRegistry.cs

#
C# | 588 lines | 558 code | 30 blank | 0 comment | 93 complexity | c4156c75c8d1120cc6a66103285d2efc MD5 | raw file
Possible License(s): Apache-2.0, LGPL-3.0
  1. namespace Microsoft.Build.Execution
  2. {
  3. using Microsoft.Build.BackEnd;
  4. using Microsoft.Build.BackEnd.Logging;
  5. using Microsoft.Build.Construction;
  6. using Microsoft.Build.Evaluation;
  7. using Microsoft.Build.Framework;
  8. using Microsoft.Build.Internal;
  9. using Microsoft.Build.Shared;
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Diagnostics;
  13. using System.IO;
  14. using System.Reflection;
  15. using System.Runtime;
  16. using System.Runtime.InteropServices;
  17. internal sealed class TaskRegistry
  18. {
  19. private Dictionary<string, RegisteredTaskRecord> cachedTaskRecordsWithExactMatch;
  20. private Dictionary<string, RegisteredTaskRecord> cachedTaskRecordsWithFuzzyMatch;
  21. private ProjectRootElementCache projectRootElementCache;
  22. private Dictionary<string, List<RegisteredTaskRecord>> taskRegistrations;
  23. private readonly Microsoft.Build.Evaluation.Toolset toolset;
  24. internal TaskRegistry(ProjectRootElementCache projectRootElementCache)
  25. {
  26. ErrorUtilities.VerifyThrowInternalNull(projectRootElementCache, "projectRootElementCache");
  27. this.projectRootElementCache = projectRootElementCache;
  28. }
  29. internal TaskRegistry(Microsoft.Build.Evaluation.Toolset toolset, ProjectRootElementCache projectRootElementCache)
  30. {
  31. ErrorUtilities.VerifyThrowInternalNull(projectRootElementCache, "projectRootElementCache");
  32. ErrorUtilities.VerifyThrowInternalNull(toolset, "toolset");
  33. this.projectRootElementCache = projectRootElementCache;
  34. this.toolset = toolset;
  35. }
  36. private RegisteredTaskRecord GetMatchingRegistration(string taskName, List<RegisteredTaskRecord> taskRecords, string taskProjectFile, TargetLoggingContext targetLoggingContext, IElementLocation elementLocation)
  37. {
  38. foreach (RegisteredTaskRecord record in taskRecords)
  39. {
  40. if (record.CanTaskBeCreatedByFactory(taskName, taskProjectFile, targetLoggingContext, elementLocation))
  41. {
  42. return record;
  43. }
  44. }
  45. return null;
  46. }
  47. internal TaskFactoryWrapper GetRegisteredTask(string taskName, string taskProjectFile, bool exactMatchRequired, TargetLoggingContext targetLoggingContext, IElementLocation elementLocation)
  48. {
  49. TaskFactoryWrapper wrapper = null;
  50. bool retrievedFromCache = false;
  51. RegisteredTaskRecord record = this.GetTaskRegistrationRecord(taskName, taskProjectFile, exactMatchRequired, targetLoggingContext, elementLocation, out retrievedFromCache);
  52. if (record != null)
  53. {
  54. string str = (taskName.Length > record.RegisteredName.Length) ? taskName : record.RegisteredName;
  55. wrapper = record.GetTaskFactoryFromRegistrationRecord(str, taskProjectFile, targetLoggingContext, elementLocation);
  56. if ((wrapper == null) || retrievedFromCache)
  57. {
  58. return wrapper;
  59. }
  60. if (record.TaskFactoryAttributeName.Equals("AssemblyTaskFactory"))
  61. {
  62. targetLoggingContext.LogComment(MessageImportance.Low, "TaskFound", new object[] { taskName, wrapper.Name });
  63. }
  64. else
  65. {
  66. targetLoggingContext.LogComment(MessageImportance.Low, "TaskFoundFromFactory", new object[] { taskName, wrapper.Name });
  67. }
  68. if (wrapper.TaskFactoryLoadedType.HasSTAThreadAttribute())
  69. {
  70. targetLoggingContext.LogComment(MessageImportance.Low, "TaskNeedsSTA", new object[] { taskName });
  71. }
  72. }
  73. return wrapper;
  74. }
  75. private Dictionary<string, List<RegisteredTaskRecord>> GetRelevantRegistrations(string taskName, bool exactMatchRequired)
  76. {
  77. List<RegisteredTaskRecord> list;
  78. Dictionary<string, List<RegisteredTaskRecord>> dictionary = new Dictionary<string, List<RegisteredTaskRecord>>(StringComparer.OrdinalIgnoreCase);
  79. if (this.taskRegistrations.TryGetValue(taskName, out list))
  80. {
  81. dictionary[taskName] = list;
  82. return dictionary;
  83. }
  84. if (!exactMatchRequired)
  85. {
  86. foreach (KeyValuePair<string, List<RegisteredTaskRecord>> pair in this.taskRegistrations)
  87. {
  88. if (TypeLoader.IsPartialTypeNameMatch(taskName, pair.Key))
  89. {
  90. dictionary[pair.Key] = pair.Value;
  91. }
  92. }
  93. }
  94. return dictionary;
  95. }
  96. internal RegisteredTaskRecord GetTaskRegistrationRecord(string taskName, string taskProjectFile, bool exactMatchRequired, TargetLoggingContext targetLoggingContext, IElementLocation elementLocation, out bool retrievedFromCache)
  97. {
  98. RegisteredTaskRecord record = null;
  99. retrievedFromCache = false;
  100. if (this.toolset != null)
  101. {
  102. record = this.toolset.GetOverrideTaskRegistry(targetLoggingContext.LoggingService, targetLoggingContext.BuildEventContext, this.projectRootElementCache).GetTaskRegistrationRecord(taskName, taskProjectFile, exactMatchRequired, targetLoggingContext, elementLocation, out retrievedFromCache);
  103. }
  104. if (((record == null) && (this.taskRegistrations != null)) && (this.taskRegistrations.Count > 0))
  105. {
  106. Dictionary<string, RegisteredTaskRecord> dictionary = exactMatchRequired ? this.cachedTaskRecordsWithExactMatch : this.cachedTaskRecordsWithFuzzyMatch;
  107. if ((dictionary != null) && dictionary.TryGetValue(taskName, out record))
  108. {
  109. retrievedFromCache = true;
  110. return record;
  111. }
  112. foreach (KeyValuePair<string, List<RegisteredTaskRecord>> pair in this.GetRelevantRegistrations(taskName, exactMatchRequired))
  113. {
  114. string str = (taskName.Length > pair.Key.Length) ? taskName : pair.Key;
  115. record = this.GetMatchingRegistration(str, pair.Value, taskProjectFile, targetLoggingContext, elementLocation);
  116. if (record != null)
  117. {
  118. break;
  119. }
  120. }
  121. }
  122. if ((record == null) && (this.toolset != null))
  123. {
  124. record = this.toolset.GetTaskRegistry(targetLoggingContext.LoggingService, targetLoggingContext.BuildEventContext, this.projectRootElementCache).GetTaskRegistrationRecord(taskName, taskProjectFile, exactMatchRequired, targetLoggingContext, elementLocation, out retrievedFromCache);
  125. }
  126. if (exactMatchRequired)
  127. {
  128. this.cachedTaskRecordsWithExactMatch = this.cachedTaskRecordsWithExactMatch ?? new Dictionary<string, RegisteredTaskRecord>(StringComparer.OrdinalIgnoreCase);
  129. this.cachedTaskRecordsWithExactMatch[taskName] = record;
  130. return record;
  131. }
  132. this.cachedTaskRecordsWithFuzzyMatch = this.cachedTaskRecordsWithFuzzyMatch ?? new Dictionary<string, RegisteredTaskRecord>(StringComparer.OrdinalIgnoreCase);
  133. this.cachedTaskRecordsWithFuzzyMatch[taskName] = record;
  134. return record;
  135. }
  136. private static bool IsTaskFactoryClass(Type type, object unused)
  137. {
  138. return ((type.IsClass && !type.IsAbstract) && typeof(ITaskFactory).IsAssignableFrom(type));
  139. }
  140. private void RegisterTask(string taskName, AssemblyLoadInfo assemblyLoadInfo, string taskFactory, RegisteredTaskRecord.ParameterGroupAndTaskElementRecord inlineTaskRecord)
  141. {
  142. List<RegisteredTaskRecord> list;
  143. ErrorUtilities.VerifyThrowInternalLength(taskName, "taskName");
  144. ErrorUtilities.VerifyThrowInternalNull(assemblyLoadInfo, "assemblyLoadInfo");
  145. if (this.taskRegistrations == null)
  146. {
  147. this.taskRegistrations = new Dictionary<string, List<RegisteredTaskRecord>>(StringComparer.OrdinalIgnoreCase);
  148. }
  149. if (!this.taskRegistrations.TryGetValue(taskName, out list))
  150. {
  151. list = new List<RegisteredTaskRecord>();
  152. this.taskRegistrations[taskName] = list;
  153. }
  154. list.Add(new RegisteredTaskRecord(taskName, assemblyLoadInfo, taskFactory, inlineTaskRecord));
  155. }
  156. internal static void RegisterTasksFromUsingTaskElement<P, I>(ILoggingService loggingService, BuildEventContext buildEventContext, string directoryOfImportingFile, ProjectUsingTaskElement projectUsingTaskXml, TaskRegistry taskRegistry, Expander<P, I> expander, ExpanderOptions expanderOptions) where P: class, IProperty where I: class, IItem
  157. {
  158. ErrorUtilities.VerifyThrowInternalNull(directoryOfImportingFile, "directoryOfImportingFile");
  159. if (ConditionEvaluator.EvaluateCondition<P, I>(projectUsingTaskXml.Condition, ParserOptions.AllowPropertiesAndItemLists, expander, expanderOptions, projectUsingTaskXml.ContainingProject.DirectoryPath, projectUsingTaskXml.ConditionLocation, loggingService, buildEventContext))
  160. {
  161. string str = null;
  162. string str2 = null;
  163. string str3 = expander.ExpandIntoStringLeaveEscaped(projectUsingTaskXml.TaskName, expanderOptions, projectUsingTaskXml.TaskNameLocation);
  164. ProjectErrorUtilities.VerifyThrowInvalidProject(str3.Length > 0, projectUsingTaskXml.TaskNameLocation, "InvalidEvaluatedAttributeValue", str3, projectUsingTaskXml.TaskName, "Name", "UsingTask");
  165. string str4 = expander.ExpandIntoStringLeaveEscaped(projectUsingTaskXml.TaskFactory, expanderOptions, projectUsingTaskXml.TaskFactoryLocation);
  166. if (string.IsNullOrEmpty(str4) || str4.Equals("AssemblyTaskFactory", StringComparison.OrdinalIgnoreCase))
  167. {
  168. ProjectXmlUtilities.VerifyThrowProjectNoChildElements(projectUsingTaskXml.XmlElement);
  169. }
  170. if (projectUsingTaskXml.AssemblyFile.Length > 0)
  171. {
  172. str = expander.ExpandIntoStringLeaveEscaped(projectUsingTaskXml.AssemblyFile, expanderOptions, projectUsingTaskXml.AssemblyFileLocation);
  173. }
  174. else
  175. {
  176. str2 = expander.ExpandIntoStringLeaveEscaped(projectUsingTaskXml.AssemblyName, expanderOptions, projectUsingTaskXml.AssemblyNameLocation);
  177. }
  178. ProjectErrorUtilities.VerifyThrowInvalidProject((str == null) || (str.Length > 0), projectUsingTaskXml.AssemblyFileLocation, "InvalidEvaluatedAttributeValue", str, projectUsingTaskXml.AssemblyFile, "AssemblyFile", "UsingTask");
  179. ProjectErrorUtilities.VerifyThrowInvalidProject((str2 == null) || (str2.Length > 0), projectUsingTaskXml.AssemblyNameLocation, "InvalidEvaluatedAttributeValue", str2, projectUsingTaskXml.AssemblyName, "AssemblyName", "UsingTask");
  180. try
  181. {
  182. if ((str != null) && !Path.IsPathRooted(str))
  183. {
  184. str = Path.Combine(directoryOfImportingFile, str);
  185. }
  186. }
  187. catch (ArgumentException exception)
  188. {
  189. ProjectErrorUtilities.ThrowInvalidProject(projectUsingTaskXml.Location, "InvalidAttributeValueWithException", str, "AssemblyFile", "UsingTask", exception.Message);
  190. }
  191. RegisteredTaskRecord.ParameterGroupAndTaskElementRecord inlineTaskRecord = null;
  192. if (projectUsingTaskXml.Count > 0)
  193. {
  194. inlineTaskRecord = new RegisteredTaskRecord.ParameterGroupAndTaskElementRecord();
  195. inlineTaskRecord.ExpandUsingTask<P, I>(projectUsingTaskXml, expander, expanderOptions);
  196. }
  197. taskRegistry.RegisterTask(str3, new AssemblyLoadInfo(str2, str), str4, inlineTaskRecord);
  198. }
  199. }
  200. internal IDictionary<string, List<RegisteredTaskRecord>> TaskRegistrations
  201. {
  202. get
  203. {
  204. if (this.taskRegistrations == null)
  205. {
  206. this.taskRegistrations = new Dictionary<string, List<RegisteredTaskRecord>>(StringComparer.OrdinalIgnoreCase);
  207. }
  208. return this.taskRegistrations;
  209. }
  210. }
  211. internal Microsoft.Build.Evaluation.Toolset Toolset
  212. {
  213. [DebuggerStepThrough, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  214. get
  215. {
  216. return this.toolset;
  217. }
  218. }
  219. internal class RegisteredTaskRecord
  220. {
  221. internal const string AssemblyTaskFactory = "AssemblyTaskFactory";
  222. private ParameterGroupAndTaskElementRecord parameterGroupAndTaskBody;
  223. private string registeredName;
  224. private string taskFactory;
  225. private AssemblyLoadInfo taskFactoryAssemblyLoadInfo;
  226. private static readonly TypeFilter taskFactoryTypeFilter = new TypeFilter(TaskRegistry.IsTaskFactoryClass);
  227. private static TypeLoader taskFactoryTypeLoader;
  228. private static readonly object taskFactoryTypeLoaderLock = new object();
  229. private TaskFactoryWrapper taskFactoryWrapperInstance;
  230. private Dictionary<string, object> taskNamesCreatableByFactory;
  231. internal RegisteredTaskRecord(string registeredName, AssemblyLoadInfo assemblyLoadInfo, string taskFactory, ParameterGroupAndTaskElementRecord inlineTask)
  232. {
  233. ErrorUtilities.VerifyThrowArgumentNull(assemblyLoadInfo, "AssemblyLoadInfo");
  234. this.registeredName = registeredName;
  235. this.taskFactoryAssemblyLoadInfo = assemblyLoadInfo;
  236. this.parameterGroupAndTaskBody = inlineTask;
  237. if (string.IsNullOrEmpty(taskFactory))
  238. {
  239. this.taskFactory = "AssemblyTaskFactory";
  240. }
  241. else
  242. {
  243. this.taskFactory = taskFactory;
  244. }
  245. if (inlineTask == null)
  246. {
  247. this.parameterGroupAndTaskBody = new ParameterGroupAndTaskElementRecord();
  248. }
  249. }
  250. internal bool CanTaskBeCreatedByFactory(string taskName, string taskProjectFile, TargetLoggingContext targetLoggingContext, IElementLocation elementLocation)
  251. {
  252. if (this.taskNamesCreatableByFactory == null)
  253. {
  254. this.taskNamesCreatableByFactory = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
  255. }
  256. object obj2 = null;
  257. if (!this.taskNamesCreatableByFactory.TryGetValue(taskName, out obj2))
  258. {
  259. try
  260. {
  261. if (this.GetTaskFactory(targetLoggingContext, elementLocation, taskProjectFile))
  262. {
  263. if (this.TaskFactoryAttributeName == "AssemblyTaskFactory")
  264. {
  265. if (taskName.Equals(this.RegisteredName, StringComparison.OrdinalIgnoreCase))
  266. {
  267. obj2 = this;
  268. }
  269. else if (((Microsoft.Build.BackEnd.AssemblyTaskFactory) this.taskFactoryWrapperInstance.TaskFactory).TaskNameCreatableByFactory(taskName, taskProjectFile, targetLoggingContext, elementLocation))
  270. {
  271. obj2 = this;
  272. }
  273. else
  274. {
  275. obj2 = null;
  276. }
  277. }
  278. else
  279. {
  280. try
  281. {
  282. if (this.taskFactoryWrapperInstance.IsCreatableByFactory(taskName))
  283. {
  284. obj2 = this;
  285. }
  286. else
  287. {
  288. obj2 = null;
  289. }
  290. }
  291. catch (Exception exception)
  292. {
  293. if (ExceptionHandling.IsCriticalException(exception))
  294. {
  295. throw;
  296. }
  297. string str = string.Empty + exception.ToString();
  298. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "TaskLoadFailure", taskName, this.taskFactoryWrapperInstance.Name, str);
  299. }
  300. }
  301. }
  302. }
  303. finally
  304. {
  305. this.taskNamesCreatableByFactory[taskName] = obj2;
  306. }
  307. }
  308. return (obj2 != null);
  309. }
  310. private bool GetTaskFactory(TargetLoggingContext targetLoggingContext, IElementLocation elementLocation, string taskProjectFile)
  311. {
  312. if (this.taskFactoryWrapperInstance == null)
  313. {
  314. AssemblyLoadInfo taskFactoryAssemblyLoadInfo = this.TaskFactoryAssemblyLoadInfo;
  315. ErrorUtilities.VerifyThrow(taskFactoryAssemblyLoadInfo != null, "TaskFactoryLoadInfo should never be null");
  316. ITaskFactory taskFactory = null;
  317. LoadedType taskFactoryLoadInfo = null;
  318. if (!string.Equals(this.TaskFactoryAttributeName, "AssemblyTaskFactory", StringComparison.OrdinalIgnoreCase))
  319. {
  320. TaskEngineAssemblyResolver resolver = null;
  321. try
  322. {
  323. resolver = new TaskEngineAssemblyResolver();
  324. resolver.Initialize(taskFactoryAssemblyLoadInfo.AssemblyFile);
  325. resolver.InstallHandler();
  326. try
  327. {
  328. lock (taskFactoryTypeLoaderLock)
  329. {
  330. if (taskFactoryTypeLoader == null)
  331. {
  332. taskFactoryTypeLoader = new TypeLoader(taskFactoryTypeFilter);
  333. }
  334. }
  335. taskFactoryLoadInfo = taskFactoryTypeLoader.Load(this.TaskFactoryAttributeName, taskFactoryAssemblyLoadInfo);
  336. if (taskFactoryLoadInfo == null)
  337. {
  338. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "CouldNotFindFactory", this.TaskFactoryAttributeName, taskFactoryAssemblyLoadInfo.AssemblyLocation);
  339. }
  340. targetLoggingContext.LogComment(MessageImportance.Low, "InitializingTaskFactory", new object[] { this.TaskFactoryAttributeName, taskFactoryAssemblyLoadInfo.AssemblyLocation });
  341. }
  342. catch (TargetInvocationException exception)
  343. {
  344. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "TaskFactoryLoadFailure", this.TaskFactoryAttributeName, taskFactoryAssemblyLoadInfo.AssemblyLocation, Environment.NewLine + exception.InnerException.ToString());
  345. }
  346. catch (ReflectionTypeLoadException exception2)
  347. {
  348. foreach (Exception exception3 in exception2.LoaderExceptions)
  349. {
  350. if (exception3 != null)
  351. {
  352. targetLoggingContext.LogError(new BuildEventFileInfo(taskProjectFile), "TaskFactoryLoadFailure", new object[] { this.TaskFactoryAttributeName, taskFactoryAssemblyLoadInfo.AssemblyLocation, exception3.Message });
  353. }
  354. }
  355. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "TaskFactoryLoadFailure", this.TaskFactoryAttributeName, taskFactoryAssemblyLoadInfo.AssemblyLocation, exception2.Message);
  356. }
  357. catch (Exception exception4)
  358. {
  359. if (ExceptionHandling.NotExpectedReflectionException(exception4))
  360. {
  361. throw;
  362. }
  363. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "TaskFactoryLoadFailure", this.TaskFactoryAttributeName, taskFactoryAssemblyLoadInfo.AssemblyLocation, exception4.Message);
  364. }
  365. try
  366. {
  367. taskFactory = (ITaskFactory) AppDomain.CurrentDomain.CreateInstanceAndUnwrap(taskFactoryLoadInfo.Type.Assembly.FullName, taskFactoryLoadInfo.Type.FullName);
  368. TaskFactoryLoggingHost taskFactoryLoggingHost = new TaskFactoryLoggingHost(true, elementLocation, targetLoggingContext);
  369. bool flag2 = false;
  370. try
  371. {
  372. flag2 = taskFactory.Initialize(this.RegisteredName, this.ParameterGroupAndTaskBody.UsingTaskParameters, this.ParameterGroupAndTaskBody.InlineTaskXmlBody, taskFactoryLoggingHost);
  373. }
  374. finally
  375. {
  376. taskFactoryLoggingHost.MarkAsInactive();
  377. }
  378. if (!flag2)
  379. {
  380. this.taskFactoryWrapperInstance = null;
  381. return false;
  382. }
  383. }
  384. catch (InvalidCastException exception5)
  385. {
  386. string str = string.Empty + exception5.Message;
  387. targetLoggingContext.LogError(new BuildEventFileInfo(elementLocation.File, elementLocation.Line, elementLocation.Column), "TaskFactoryInstantiationFailureErrorInvalidCast", new object[] { this.TaskFactoryAttributeName, taskFactoryAssemblyLoadInfo.AssemblyLocation, str });
  388. return false;
  389. }
  390. catch (Exception exception6)
  391. {
  392. if (ExceptionHandling.IsCriticalException(exception6))
  393. {
  394. throw;
  395. }
  396. string str2 = string.Empty + exception6.Message;
  397. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "TaskFactoryLoadFailure", this.TaskFactoryAttributeName, taskFactoryAssemblyLoadInfo.AssemblyLocation, str2);
  398. }
  399. }
  400. finally
  401. {
  402. if (resolver != null)
  403. {
  404. resolver.RemoveHandler();
  405. resolver = null;
  406. }
  407. }
  408. }
  409. else
  410. {
  411. Microsoft.Build.BackEnd.AssemblyTaskFactory factory2 = new Microsoft.Build.BackEnd.AssemblyTaskFactory();
  412. taskFactoryLoadInfo = factory2.InitializeFactory(taskFactoryAssemblyLoadInfo, this.RegisteredName, this.ParameterGroupAndTaskBody.UsingTaskParameters, this.ParameterGroupAndTaskBody.InlineTaskXmlBody, targetLoggingContext, elementLocation, taskProjectFile);
  413. taskFactory = factory2;
  414. }
  415. this.taskFactoryWrapperInstance = new TaskFactoryWrapper(taskFactory, taskFactoryLoadInfo, this.RegisteredName);
  416. }
  417. return true;
  418. }
  419. internal TaskFactoryWrapper GetTaskFactoryFromRegistrationRecord(string taskName, string taskProjectFile, TargetLoggingContext targetLoggingContext, IElementLocation elementLocation)
  420. {
  421. if (this.CanTaskBeCreatedByFactory(taskName, taskProjectFile, targetLoggingContext, elementLocation))
  422. {
  423. return this.taskFactoryWrapperInstance;
  424. }
  425. return null;
  426. }
  427. internal ParameterGroupAndTaskElementRecord ParameterGroupAndTaskBody
  428. {
  429. [DebuggerStepThrough, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  430. get
  431. {
  432. return this.parameterGroupAndTaskBody;
  433. }
  434. }
  435. internal string RegisteredName
  436. {
  437. [DebuggerStepThrough, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  438. get
  439. {
  440. return this.registeredName;
  441. }
  442. }
  443. internal AssemblyLoadInfo TaskFactoryAssemblyLoadInfo
  444. {
  445. [DebuggerStepThrough, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  446. get
  447. {
  448. return this.taskFactoryAssemblyLoadInfo;
  449. }
  450. }
  451. internal string TaskFactoryAttributeName
  452. {
  453. [DebuggerStepThrough, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  454. get
  455. {
  456. return this.taskFactory;
  457. }
  458. }
  459. internal class ParameterGroupAndTaskElementRecord
  460. {
  461. private string inlineTaskXmlBody;
  462. private bool taskBodyEvaluated;
  463. private Dictionary<string, TaskPropertyInfo> usingTaskParameters = new Dictionary<string, TaskPropertyInfo>(StringComparer.OrdinalIgnoreCase);
  464. internal ParameterGroupAndTaskElementRecord()
  465. {
  466. }
  467. private void EvaluateTaskBody<P, I>(Expander<P, I> expander, ProjectUsingTaskBodyElement taskElement, ExpanderOptions expanderOptions) where P: class, IProperty where I: class, IItem
  468. {
  469. bool flag;
  470. string str = expander.ExpandIntoStringLeaveEscaped(taskElement.Evaluate, expanderOptions, taskElement.EvaluateLocation);
  471. if (!bool.TryParse(str, out flag))
  472. {
  473. ProjectErrorUtilities.ThrowInvalidProject(taskElement.EvaluateLocation, "InvalidEvaluatedAttributeValue", str, taskElement.Evaluate, "Evaluate", "Task");
  474. }
  475. this.taskBodyEvaluated = flag;
  476. if (flag)
  477. {
  478. this.inlineTaskXmlBody = expander.ExpandIntoStringLeaveEscaped(taskElement.TaskBody, expanderOptions, taskElement.Location);
  479. }
  480. else
  481. {
  482. this.inlineTaskXmlBody = taskElement.TaskBody;
  483. }
  484. }
  485. internal void ExpandUsingTask<P, I>(ProjectUsingTaskElement projectUsingTaskXml, Expander<P, I> expander, ExpanderOptions expanderOptions) where P: class, IProperty where I: class, IItem
  486. {
  487. ErrorUtilities.VerifyThrowArgumentNull(projectUsingTaskXml, "projectUsingTaskXml");
  488. ErrorUtilities.VerifyThrowArgumentNull(expander, "expander");
  489. ProjectUsingTaskBodyElement taskBody = projectUsingTaskXml.TaskBody;
  490. if (taskBody != null)
  491. {
  492. this.EvaluateTaskBody<P, I>(expander, taskBody, expanderOptions);
  493. }
  494. UsingTaskParameterGroupElement parameterGroup = projectUsingTaskXml.ParameterGroup;
  495. if (parameterGroup != null)
  496. {
  497. this.ParseUsingTaskParameterGroupElement<P, I>(parameterGroup, expander, expanderOptions);
  498. }
  499. }
  500. private void ParseUsingTaskParameterGroupElement<P, I>(UsingTaskParameterGroupElement usingTaskParameterGroup, Expander<P, I> expander, ExpanderOptions expanderOptions) where P: class, IProperty where I: class, IItem
  501. {
  502. foreach (ProjectUsingTaskParameterElement element in usingTaskParameterGroup.Parameters)
  503. {
  504. bool flag;
  505. bool flag2;
  506. string str = expander.ExpandIntoStringLeaveEscaped(element.ParameterType, expanderOptions, element.ParameterTypeLocation);
  507. ProjectErrorUtilities.VerifyThrowInvalidProject(!string.IsNullOrEmpty(str), element.ParameterTypeLocation, "InvalidEvaluatedAttributeValue", str, element.ParameterType, "ParameterType", "Parameter");
  508. Type parameterType = Type.GetType(str);
  509. if (parameterType == null)
  510. {
  511. parameterType = Type.GetType(str + "," + typeof(ITaskItem).Assembly.FullName, false, true);
  512. ProjectErrorUtilities.VerifyThrowInvalidProject(parameterType != null, element.ParameterTypeLocation, "InvalidEvaluatedAttributeValue", str, element.ParameterType, "ParameterType", "Parameter");
  513. }
  514. str = expander.ExpandIntoStringLeaveEscaped(element.Output, expanderOptions, element.OutputLocation);
  515. if (!bool.TryParse(str, out flag))
  516. {
  517. ProjectErrorUtilities.ThrowInvalidProject(element.OutputLocation, "InvalidEvaluatedAttributeValue", str, element.Output, "Output", "Parameter");
  518. }
  519. if ((!flag && !TaskParameterTypeVerifier.IsValidInputParameter(parameterType)) || (flag && !TaskParameterTypeVerifier.IsValidOutputParameter(parameterType)))
  520. {
  521. ProjectErrorUtilities.ThrowInvalidProject(element.Location, "UnsupportedTaskParameterTypeError", parameterType.FullName, element.ParameterType, element.Name);
  522. }
  523. str = expander.ExpandIntoStringLeaveEscaped(element.Required, expanderOptions, element.RequiredLocation);
  524. if (!bool.TryParse(str, out flag2))
  525. {
  526. ProjectErrorUtilities.ThrowInvalidProject(element.RequiredLocation, "InvalidEvaluatedAttributeValue", str, element.Required, "Required", "Parameter");
  527. }
  528. this.UsingTaskParameters.Add(element.Name, new TaskPropertyInfo(element.Name, parameterType, flag, flag2));
  529. }
  530. }
  531. internal string InlineTaskXmlBody
  532. {
  533. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  534. get
  535. {
  536. return this.inlineTaskXmlBody;
  537. }
  538. }
  539. internal bool TaskBodyEvaluated
  540. {
  541. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  542. get
  543. {
  544. return this.taskBodyEvaluated;
  545. }
  546. }
  547. internal Dictionary<string, TaskPropertyInfo> UsingTaskParameters
  548. {
  549. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  550. get
  551. {
  552. return this.usingTaskParameters;
  553. }
  554. }
  555. }
  556. }
  557. }
  558. }