PageRenderTime 61ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/Microsoft.Build/Microsoft.Build/Microsoft/Build/Evaluation/Expander!2.cs

#
C# | 3960 lines | 3951 code | 9 blank | 0 comment | 31 complexity | 76d716ef0e206723446b06fb2f45bbf0 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;
  4. using Microsoft.Build.Collections;
  5. using Microsoft.Build.Execution;
  6. using Microsoft.Build.Internal;
  7. using Microsoft.Build.Shared;
  8. using Microsoft.Win32;
  9. using System;
  10. using System.Collections;
  11. using System.Collections.Concurrent;
  12. using System.Collections.Generic;
  13. using System.Diagnostics;
  14. using System.Globalization;
  15. using System.IO;
  16. using System.Linq;
  17. using System.Reflection;
  18. using System.Runtime;
  19. using System.Runtime.CompilerServices;
  20. using System.Runtime.InteropServices;
  21. using System.Text;
  22. using System.Text.RegularExpressions;
  23. using System.Threading;
  24. internal class Expander<P, I> where P: class, IProperty where I: class, IItem
  25. {
  26. private static readonly bool defaultWarnForUninitializedProperties;
  27. private static char[] expandableChars;
  28. private static CompareInfo invariantCompareInfo;
  29. private IItemProvider<I> items;
  30. private IMetadataTable metadata;
  31. private IPropertyProvider<P> properties;
  32. private Microsoft.Build.Evaluation.UsedUninitializedProperties usedUninitializedProperties;
  33. static Expander()
  34. {
  35. Expander<P, I>.defaultWarnForUninitializedProperties = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("MSBUILDWARNONUNINITIALIZEDPROPERTY"));
  36. Expander<P, I>.expandableChars = new char[] { '$', '%', '@' };
  37. Expander<P, I>.invariantCompareInfo = CultureInfo.InvariantCulture.CompareInfo;
  38. }
  39. internal Expander(IPropertyProvider<P> properties)
  40. {
  41. this.properties = properties;
  42. this.usedUninitializedProperties = new Microsoft.Build.Evaluation.UsedUninitializedProperties();
  43. }
  44. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  45. internal Expander(IPropertyProvider<P> properties, IItemProvider<I> items) : this(properties)
  46. {
  47. this.items = items;
  48. }
  49. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  50. internal Expander(IPropertyProvider<P> properties, IItemProvider<I> items, IMetadataTable metadata) : this(properties, items)
  51. {
  52. this.metadata = metadata;
  53. }
  54. private static void AddArgument(List<string> arguments, StringBuilder argumentBuilder)
  55. {
  56. ErrorUtilities.VerifyThrowArgumentNull(argumentBuilder, "argumentBuilder");
  57. string strB = OpportunisticIntern.StringBuilderToString(argumentBuilder).Trim();
  58. if (string.Compare("null", strB, StringComparison.OrdinalIgnoreCase) == 0)
  59. {
  60. arguments.Add(null);
  61. }
  62. else if (strB.Length > 0)
  63. {
  64. if ((strB[0] == '\'') && (strB[strB.Length - 1] == '\''))
  65. {
  66. arguments.Add(strB.Trim(new char[] { '\'' }));
  67. }
  68. else if ((strB[0] == '`') && (strB[strB.Length - 1] == '`'))
  69. {
  70. arguments.Add(strB.Trim(new char[] { '`' }));
  71. }
  72. else if ((strB[0] == '"') && (strB[strB.Length - 1] == '"'))
  73. {
  74. arguments.Add(strB.Trim(new char[] { '"' }));
  75. }
  76. else
  77. {
  78. arguments.Add(strB);
  79. }
  80. }
  81. else
  82. {
  83. arguments.Add(strB);
  84. }
  85. }
  86. internal IList<T> ExpandIntoItemsLeaveEscaped<T>(string expression, IItemFactory<I, T> itemFactory, ExpanderOptions options, IElementLocation elementLocation) where T: class, IItem
  87. {
  88. if (expression.Length == 0)
  89. {
  90. return ReadOnlyEmptyList<T>.Instance;
  91. }
  92. ErrorUtilities.VerifyThrowInternalNull(elementLocation, "elementLocation");
  93. expression = MetadataExpander<P, I>.ExpandMetadataLeaveEscaped(expression, this.metadata, options);
  94. expression = PropertyExpander<P, I, P>.ExpandPropertiesLeaveEscaped(expression, this.properties, options, elementLocation, this.usedUninitializedProperties);
  95. List<T> list = new List<T>();
  96. if (expression.Length != 0)
  97. {
  98. foreach (string str in ExpressionShredder.SplitSemiColonSeparatedList(expression))
  99. {
  100. bool flag;
  101. IList<T> collection = ItemExpander<P, I>.ExpandSingleItemVectorExpressionIntoItems<I, T>((Expander<P, I>) this, str, this.items, itemFactory, options, false, out flag, elementLocation);
  102. if (((collection == null) || (collection.Count > 0)) && ((options & ExpanderOptions.BreakOnNotEmpty) != ExpanderOptions.Invalid))
  103. {
  104. return null;
  105. }
  106. if (collection != null)
  107. {
  108. list.AddRange(collection);
  109. }
  110. else
  111. {
  112. T item = itemFactory.CreateItem(str);
  113. list.Add(item);
  114. }
  115. }
  116. }
  117. return list;
  118. }
  119. internal string ExpandIntoStringAndUnescape(string expression, ExpanderOptions options, IElementLocation elementLocation)
  120. {
  121. string escapedString = this.ExpandIntoStringLeaveEscaped(expression, options, elementLocation);
  122. return ((escapedString == null) ? null : EscapingUtilities.UnescapeAll(escapedString));
  123. }
  124. internal string ExpandIntoStringLeaveEscaped(string expression, ExpanderOptions options, IElementLocation elementLocation)
  125. {
  126. if (expression.Length == 0)
  127. {
  128. return string.Empty;
  129. }
  130. ErrorUtilities.VerifyThrowInternalNull(elementLocation, "elementLocation");
  131. string str = PropertyExpander<P, I, P>.ExpandPropertiesLeaveEscaped(MetadataExpander<P, I>.ExpandMetadataLeaveEscaped(expression, this.metadata, options), this.properties, options, elementLocation, this.usedUninitializedProperties);
  132. return ItemExpander<P, I>.ExpandItemVectorsIntoString<I>((Expander<P, I>) this, str, this.items, options, elementLocation);
  133. }
  134. internal IList<string> ExpandIntoStringListLeaveEscaped(string expression, ExpanderOptions options, IElementLocation elementLocation)
  135. {
  136. ErrorUtilities.VerifyThrow((options & ExpanderOptions.BreakOnNotEmpty) == ExpanderOptions.Invalid, "not supported");
  137. return ExpressionShredder.SplitSemiColonSeparatedList(this.ExpandIntoStringLeaveEscaped(expression, options, elementLocation));
  138. }
  139. internal IList<ProjectItemInstance.TaskItem> ExpandIntoTaskItemsLeaveEscaped(string expression, ExpanderOptions options, IElementLocation elementLocation)
  140. {
  141. return this.ExpandIntoItemsLeaveEscaped<ProjectItemInstance.TaskItem>(expression, (IItemFactory<I, ProjectItemInstance.TaskItem>) ProjectItemInstance.TaskItem.TaskItemFactory.Instance, options, elementLocation);
  142. }
  143. internal object ExpandPropertiesLeaveTypedAndEscaped(string expression, ExpanderOptions options, IElementLocation elementLocation)
  144. {
  145. if (expression.Length == 0)
  146. {
  147. return string.Empty;
  148. }
  149. ErrorUtilities.VerifyThrowInternalNull(elementLocation, "elementLocation");
  150. return PropertyExpander<P, I, P>.ExpandPropertiesLeaveTypedAndEscaped(MetadataExpander<P, I>.ExpandMetadataLeaveEscaped(expression, this.metadata, options), this.properties, options, elementLocation, this.usedUninitializedProperties);
  151. }
  152. internal IList<T> ExpandSingleItemVectorExpressionIntoItems<T>(string expression, IItemFactory<I, T> itemFactory, ExpanderOptions options, bool includeNullItems, out bool isTransformExpression, IElementLocation elementLocation) where T: class, IItem
  153. {
  154. if (expression.Length == 0)
  155. {
  156. isTransformExpression = false;
  157. return ReadOnlyEmptyList<T>.Instance;
  158. }
  159. ErrorUtilities.VerifyThrowInternalNull(elementLocation, "elementLocation");
  160. return ItemExpander<P, I>.ExpandSingleItemVectorExpressionIntoItems<I, T>((Expander<P, I>) this, expression, this.items, itemFactory, options, includeNullItems, out isTransformExpression, elementLocation);
  161. }
  162. internal static bool ExpressionContainsItemVector(string expression)
  163. {
  164. return (ExpressionShredder.GetReferencedItemExpressions(expression) != null);
  165. }
  166. internal static bool ExpressionMayContainExpandableExpressions(string expression)
  167. {
  168. return (expression.IndexOfAny(Expander<P, I>.expandableChars) > -1);
  169. }
  170. private static unsafe string[] ExtractFunctionArguments(IElementLocation elementLocation, string expressionFunction, string argumentsString)
  171. {
  172. int length = argumentsString.Length;
  173. List<string> arguments = new List<string>();
  174. StringBuilder argumentBuilder = new StringBuilder(length);
  175. fixed (char* str = ((char*) argumentsString))
  176. {
  177. char* chPtr = str;
  178. for (int i = 0; i < length; i++)
  179. {
  180. if (((i < (length - 1)) && (chPtr[i] == '$')) && (chPtr[i + 1] == '('))
  181. {
  182. int startIndex = i;
  183. i += 2;
  184. i = Expander<P, I>.ScanForClosingParenthesis(argumentsString, i);
  185. if (i == -1)
  186. {
  187. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "InvalidFunctionPropertyExpression", expressionFunction, AssemblyResources.GetString("InvalidFunctionPropertyExpressionDetailMismatchedParenthesis"));
  188. }
  189. argumentBuilder.Append(argumentsString.Substring(startIndex, (i - startIndex) + 1));
  190. }
  191. else if (((chPtr[i] == '`') || (chPtr[i] == '"')) || (chPtr[i] == '\''))
  192. {
  193. int num4 = i;
  194. i++;
  195. i = Expander<P, I>.ScanForClosingQuote(argumentsString[num4], argumentsString, i);
  196. if (i == -1)
  197. {
  198. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "InvalidFunctionPropertyExpression", expressionFunction, AssemblyResources.GetString("InvalidFunctionPropertyExpressionDetailMismatchedQuote"));
  199. }
  200. argumentBuilder.Append(argumentsString.Substring(num4, (i - num4) + 1));
  201. }
  202. else if (chPtr[i] == ',')
  203. {
  204. Expander<P, I>.AddArgument(arguments, argumentBuilder);
  205. argumentBuilder.Remove(0, argumentBuilder.Length);
  206. }
  207. else
  208. {
  209. argumentBuilder.Append(chPtr[i]);
  210. }
  211. }
  212. }
  213. Expander<P, I>.AddArgument(arguments, argumentBuilder);
  214. return arguments.ToArray();
  215. }
  216. private static bool IsValidPropertyName(string propertyName)
  217. {
  218. if ((propertyName.Length == 0) || !XmlUtilities.IsValidInitialElementNameCharacter(propertyName[0]))
  219. {
  220. return false;
  221. }
  222. for (int i = 1; i < propertyName.Length; i++)
  223. {
  224. if (!XmlUtilities.IsValidSubsequentElementNameCharacter(propertyName[i]))
  225. {
  226. return false;
  227. }
  228. }
  229. return true;
  230. }
  231. private static int ScanForClosingParenthesis(string expression, int index)
  232. {
  233. bool potentialPropertyFunction = false;
  234. bool potentialRegistryFunction = false;
  235. return Expander<P, I>.ScanForClosingParenthesis(expression, index, out potentialPropertyFunction, out potentialRegistryFunction);
  236. }
  237. private static unsafe int ScanForClosingParenthesis(string expression, int index, out bool potentialPropertyFunction, out bool potentialRegistryFunction)
  238. {
  239. int num = 1;
  240. int length = expression.Length;
  241. potentialPropertyFunction = false;
  242. potentialRegistryFunction = false;
  243. fixed (char* str = ((char*) expression))
  244. {
  245. char* chPtr = str;
  246. while ((index < length) && (num > 0))
  247. {
  248. char quoteChar = chPtr[index];
  249. switch (quoteChar)
  250. {
  251. case '\'':
  252. case '`':
  253. case '"':
  254. index++;
  255. index = Expander<P, I>.ScanForClosingQuote(quoteChar, expression, index);
  256. if (index < 0)
  257. {
  258. return -1;
  259. }
  260. break;
  261. case '(':
  262. num++;
  263. break;
  264. case ')':
  265. num--;
  266. break;
  267. case '.':
  268. case '[':
  269. case '$':
  270. potentialPropertyFunction = true;
  271. break;
  272. default:
  273. if (quoteChar == ':')
  274. {
  275. potentialRegistryFunction = true;
  276. }
  277. break;
  278. }
  279. index++;
  280. }
  281. }
  282. index--;
  283. if (num != 0)
  284. {
  285. return -1;
  286. }
  287. return index;
  288. }
  289. private static unsafe int ScanForClosingQuote(char quoteChar, string expression, int index)
  290. {
  291. fixed (char* str = ((char*) expression))
  292. {
  293. char* chPtr = str;
  294. while (index < expression.Length)
  295. {
  296. if (chPtr[index] == quoteChar)
  297. {
  298. return index;
  299. }
  300. index++;
  301. }
  302. }
  303. return -1;
  304. }
  305. internal IMetadataTable Metadata
  306. {
  307. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  308. get
  309. {
  310. return this.metadata;
  311. }
  312. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  313. set
  314. {
  315. this.metadata = value;
  316. }
  317. }
  318. internal Microsoft.Build.Evaluation.UsedUninitializedProperties UsedUninitializedProperties
  319. {
  320. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  321. get
  322. {
  323. return this.usedUninitializedProperties;
  324. }
  325. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  326. set
  327. {
  328. this.usedUninitializedProperties = value;
  329. }
  330. }
  331. internal bool WarnForUninitializedProperties
  332. {
  333. get
  334. {
  335. return this.usedUninitializedProperties.Warn;
  336. }
  337. set
  338. {
  339. this.usedUninitializedProperties.Warn = value;
  340. }
  341. }
  342. private class Function<T> where T: class, IProperty
  343. {
  344. private string[] arguments;
  345. private BindingFlags bindingFlags;
  346. private string expression;
  347. private string expressionRootName;
  348. private string name;
  349. private Type objectType;
  350. private string remainder;
  351. private UsedUninitializedProperties usedUninitializedProperties;
  352. internal Function(Type objectType, string expression, string expressionRootName, string name, string[] arguments, BindingFlags bindingFlags, string remainder, UsedUninitializedProperties usedUninitializedProperties)
  353. {
  354. this.name = name;
  355. if (arguments == null)
  356. {
  357. this.arguments = new string[0];
  358. }
  359. else
  360. {
  361. this.arguments = arguments;
  362. }
  363. this.expressionRootName = expressionRootName;
  364. this.expression = expression;
  365. this.objectType = objectType;
  366. this.bindingFlags = bindingFlags;
  367. this.remainder = remainder;
  368. this.usedUninitializedProperties = usedUninitializedProperties;
  369. }
  370. private static object[] CoerceArguments(object[] args, ParameterInfo[] parameters)
  371. {
  372. object[] objArray = new object[args.Length];
  373. try
  374. {
  375. for (int i = 0; i < parameters.Length; i++)
  376. {
  377. if (args[i] != null)
  378. {
  379. if (parameters[i].ParameterType == typeof(char[]))
  380. {
  381. objArray[i] = args[i].ToString().ToCharArray();
  382. }
  383. else if ((parameters[i].ParameterType.IsEnum && (args[i] is string)) && ((string) args[i]).Contains("."))
  384. {
  385. Type parameterType = parameters[i].ParameterType;
  386. string oldValue = parameterType.Name + ".";
  387. string str2 = parameterType.FullName + ".";
  388. string str3 = args[i].ToString().Replace('|', ',').Replace(str2, "").Replace(oldValue, "");
  389. objArray[i] = Enum.Parse(parameterType, str3);
  390. }
  391. else
  392. {
  393. objArray[i] = Convert.ChangeType(args[i], parameters[i].ParameterType, CultureInfo.InvariantCulture);
  394. }
  395. }
  396. }
  397. }
  398. catch (InvalidCastException)
  399. {
  400. return null;
  401. }
  402. return objArray;
  403. }
  404. private static Expander<P, I>.Function<T> ConstructFunction(IElementLocation elementLocation, string expressionFunction, string expressionRootName, Type objectType, int argumentStartIndex, int methodStartIndex, UsedUninitializedProperties usedUninitializedProperties)
  405. {
  406. string[] strArray;
  407. string str;
  408. string str2 = string.Empty;
  409. BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.IgnoreCase;
  410. if ((argumentStartIndex > -1) && !expressionFunction.Substring(methodStartIndex, argumentStartIndex - methodStartIndex).Contains("."))
  411. {
  412. string str3;
  413. str = expressionFunction.Substring(methodStartIndex, argumentStartIndex - methodStartIndex).Trim();
  414. argumentStartIndex++;
  415. int num = Expander<P, I>.ScanForClosingParenthesis(expressionFunction, argumentStartIndex);
  416. ErrorUtilities.VerifyThrow(num != -1, "Unmatched braces when constructing function.", "$(" + expressionFunction + ")");
  417. bindingFlags |= BindingFlags.InvokeMethod;
  418. if (argumentStartIndex == (expressionFunction.Length - 1))
  419. {
  420. str3 = string.Empty;
  421. strArray = new string[0];
  422. }
  423. else
  424. {
  425. str3 = expressionFunction.Substring(argumentStartIndex, num - argumentStartIndex);
  426. if (string.IsNullOrEmpty(str3))
  427. {
  428. strArray = new string[0];
  429. }
  430. else
  431. {
  432. strArray = Expander<P, I>.ExtractFunctionArguments(elementLocation, expressionFunction, str3);
  433. }
  434. str2 = expressionFunction.Substring(num + 1);
  435. }
  436. }
  437. else
  438. {
  439. int index = expressionFunction.IndexOf('.', methodStartIndex);
  440. int length = expressionFunction.Length - methodStartIndex;
  441. int num4 = expressionFunction.IndexOf('[', methodStartIndex);
  442. if ((num4 >= 0) && (num4 < index))
  443. {
  444. index = num4;
  445. }
  446. strArray = new string[0];
  447. if (index > 0)
  448. {
  449. length = index - methodStartIndex;
  450. str2 = expressionFunction.Substring(index);
  451. }
  452. string str4 = expressionFunction.Substring(methodStartIndex, length).Trim();
  453. ProjectErrorUtilities.VerifyThrowInvalidProject(str4.Length > 0, elementLocation, "InvalidFunctionPropertyExpression", expressionFunction, string.Empty);
  454. bindingFlags |= BindingFlags.GetProperty | BindingFlags.GetField;
  455. str = str4;
  456. }
  457. if ((string.IsNullOrEmpty(str2) || (str2[0] == '.')) || (str2[0] == '['))
  458. {
  459. return new Expander<P, I>.Function<T>(objectType, expressionFunction, expressionRootName, str, strArray, bindingFlags, str2, usedUninitializedProperties);
  460. }
  461. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "InvalidFunctionPropertyExpression", expressionFunction, string.Empty);
  462. return null;
  463. }
  464. private static Expander<P, I>.Function<T> ConstructIndexerFunction(string expressionFunction, IElementLocation elementLocation, object propertyValue, string propertyName, Type objectType, int methodStartIndex, string argumentsContent, UsedUninitializedProperties usedUnInitializedProperties)
  465. {
  466. string str2;
  467. string[] strArray;
  468. string remainder = expressionFunction.Substring(methodStartIndex);
  469. if (string.IsNullOrEmpty(argumentsContent))
  470. {
  471. strArray = new string[0];
  472. }
  473. else
  474. {
  475. strArray = Expander<P, I>.ExtractFunctionArguments(elementLocation, expressionFunction, argumentsContent);
  476. }
  477. if (propertyValue is Array)
  478. {
  479. str2 = "GetValue";
  480. }
  481. else if (propertyValue is string)
  482. {
  483. str2 = "get_Chars";
  484. }
  485. else
  486. {
  487. str2 = "get_Item";
  488. }
  489. return new Expander<P, I>.Function<T>(objectType, expressionFunction, propertyName, str2, strArray, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.IgnoreCase, remainder, usedUnInitializedProperties);
  490. }
  491. internal object Execute(object objectInstance, IPropertyProvider<T> properties, ExpanderOptions options, IElementLocation elementLocation)
  492. {
  493. object propertyValue = string.Empty;
  494. object[] args = null;
  495. try
  496. {
  497. if (objectInstance == null)
  498. {
  499. if (!this.IsStaticMethodAvailable(this.objectType, this.name))
  500. {
  501. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "InvalidFunctionMethodUnavailable", this.name, this.objectType.FullName);
  502. }
  503. this.bindingFlags |= BindingFlags.Static;
  504. if (this.objectType == typeof(IntrinsicFunctions))
  505. {
  506. this.bindingFlags |= BindingFlags.NonPublic;
  507. }
  508. }
  509. else
  510. {
  511. this.bindingFlags |= BindingFlags.Instance;
  512. if (objectInstance is string)
  513. {
  514. objectInstance = EscapingUtilities.UnescapeAll((string) objectInstance);
  515. }
  516. }
  517. args = new object[this.arguments.Length];
  518. for (int i = 0; i < this.arguments.Length; i++)
  519. {
  520. object obj3 = Expander<P, I>.PropertyExpander<T>.ExpandPropertiesLeaveTypedAndEscaped(this.arguments[i], properties, options, elementLocation, this.usedUninitializedProperties);
  521. string escapedString = obj3 as string;
  522. if (escapedString != null)
  523. {
  524. args[i] = EscapingUtilities.UnescapeAll(escapedString);
  525. }
  526. else
  527. {
  528. args[i] = obj3;
  529. }
  530. }
  531. if (((objectInstance != null) && (args.Length == 1)) && (string.Equals("Equals", this.name, StringComparison.OrdinalIgnoreCase) || string.Equals("CompareTo", this.name, StringComparison.OrdinalIgnoreCase)))
  532. {
  533. args[0] = Convert.ChangeType(args[0], objectInstance.GetType(), CultureInfo.InvariantCulture);
  534. }
  535. if (string.Equals("new", this.name, StringComparison.OrdinalIgnoreCase))
  536. {
  537. propertyValue = this.LateBindExecute(null, BindingFlags.Public | BindingFlags.Instance, null, args, true);
  538. }
  539. else
  540. {
  541. try
  542. {
  543. propertyValue = this.objectType.InvokeMember(this.name, this.bindingFlags, Type.DefaultBinder, objectInstance, args, CultureInfo.InvariantCulture);
  544. }
  545. catch (MissingMethodException exception)
  546. {
  547. if ((this.bindingFlags & BindingFlags.InvokeMethod) != BindingFlags.InvokeMethod)
  548. {
  549. throw;
  550. }
  551. propertyValue = this.LateBindExecute(exception, this.bindingFlags, objectInstance, args, false);
  552. }
  553. }
  554. if (((propertyValue is string) && !string.Equals("Unescape", this.name, StringComparison.OrdinalIgnoreCase)) && !string.Equals("Escape", this.name, StringComparison.OrdinalIgnoreCase))
  555. {
  556. propertyValue = EscapingUtilities.Escape((string) propertyValue);
  557. }
  558. if (string.IsNullOrEmpty(this.remainder))
  559. {
  560. return propertyValue;
  561. }
  562. return Expander<P, I>.PropertyExpander<T>.ExpandPropertyBody(this.remainder, propertyValue, properties, options, elementLocation, this.usedUninitializedProperties);
  563. }
  564. catch (TargetInvocationException exception2)
  565. {
  566. string str2 = this.GenerateStringOfMethodExecuted(this.expression, objectInstance, this.name, args);
  567. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "InvalidFunctionPropertyExpression", str2, exception2.InnerException.Message.Replace("\r\n", " "));
  568. return null;
  569. }
  570. catch (Exception exception3)
  571. {
  572. if (ExceptionHandling.NotExpectedFunctionException(exception3))
  573. {
  574. throw;
  575. }
  576. if (Expander<P, I>.invariantCompareInfo.IndexOf(this.expression, "::", CompareOptions.OrdinalIgnoreCase) > -1)
  577. {
  578. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "InvalidFunctionStaticMethodSyntax", this.expression, exception3.Message.Replace("Microsoft.Build.Evaluation.IntrinsicFunctions.", "[MSBuild]::"));
  579. }
  580. else
  581. {
  582. string str3 = this.GenerateStringOfMethodExecuted(this.expression, objectInstance, this.name, args);
  583. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "InvalidFunctionPropertyExpression", str3, exception3.Message);
  584. }
  585. return null;
  586. }
  587. }
  588. internal static Expander<P, I>.Function<T> ExtractPropertyFunction(string expressionFunction, IElementLocation elementLocation, object propertyValue, UsedUninitializedProperties usedUnInitializedProperties)
  589. {
  590. string propertyName = null;
  591. Type objectType = null;
  592. string str2 = expressionFunction;
  593. int index = expressionFunction.IndexOf('(');
  594. if (index > -1)
  595. {
  596. str2 = expressionFunction.Substring(0, index);
  597. }
  598. ProjectErrorUtilities.VerifyThrowInvalidProject(!string.IsNullOrEmpty(str2), elementLocation, "InvalidFunctionPropertyExpression", expressionFunction, string.Empty);
  599. int methodStartIndex = -1;
  600. if ((propertyValue == null) && (str2[0] == '['))
  601. {
  602. int num3 = str2.IndexOf(']', 1);
  603. if (num3 < 1)
  604. {
  605. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "InvalidFunctionStaticMethodSyntax", expressionFunction, string.Empty);
  606. }
  607. string typeName = str2.Substring(1, num3 - 1);
  608. methodStartIndex = num3 + 1;
  609. objectType = Expander<P, I>.Function<T>.GetTypeForStaticMethod(typeName);
  610. if (objectType == null)
  611. {
  612. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "InvalidFunctionTypeUnavailable", expressionFunction, typeName);
  613. }
  614. if (((str2.Length > (methodStartIndex + 2)) && (str2[methodStartIndex] == ':')) && (str2[methodStartIndex + 1] == ':'))
  615. {
  616. methodStartIndex += 2;
  617. }
  618. else
  619. {
  620. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "InvalidFunctionStaticMethodSyntax", expressionFunction, string.Empty);
  621. }
  622. }
  623. else
  624. {
  625. if (expressionFunction[0] == '[')
  626. {
  627. objectType = propertyValue.GetType();
  628. int num4 = expressionFunction.IndexOf(']', 1);
  629. if (num4 < 1)
  630. {
  631. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "InvalidFunctionPropertyExpression", expressionFunction, AssemblyResources.GetString("InvalidFunctionPropertyExpressionDetailMismatchedSquareBrackets"));
  632. }
  633. string argumentsContent = expressionFunction.Substring(1, num4 - 1);
  634. methodStartIndex = num4 + 1;
  635. return Expander<P, I>.Function<T>.ConstructIndexerFunction(expressionFunction, elementLocation, propertyValue, propertyName, objectType, methodStartIndex, argumentsContent, usedUnInitializedProperties);
  636. }
  637. methodStartIndex = str2.IndexOf('.');
  638. if (methodStartIndex == -1)
  639. {
  640. return null;
  641. }
  642. methodStartIndex++;
  643. }
  644. if (objectType == null)
  645. {
  646. int length = str2.IndexOf('.');
  647. propertyName = str2.Substring(0, length);
  648. if ((propertyValue == null) && !Expander<P, I>.IsValidPropertyName(propertyName))
  649. {
  650. ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "InvalidFunctionPropertyExpression", expressionFunction, string.Empty);
  651. }
  652. objectType = typeof(string);
  653. }
  654. if (propertyValue != null)
  655. {
  656. objectType = propertyValue.GetType();
  657. }
  658. return Expander<P, I>.Function<T>.ConstructFunction(elementLocation, expressionFunction, propertyName, objectType, index, methodStartIndex, usedUnInitializedProperties);
  659. }
  660. private string GenerateStringOfMethodExecuted(string expression, object objectInstance, string name, object[] args)
  661. {
  662. string str = string.Empty;
  663. if (args != null)
  664. {
  665. foreach (object obj2 in args)
  666. {
  667. if (obj2 == null)
  668. {
  669. str = str + "null";
  670. }
  671. else
  672. {
  673. string str2 = obj2.ToString();
  674. if ((obj2 is string) && (str2.Length == 0))
  675. {
  676. str = str + "''";
  677. }
  678. else
  679. {
  680. str = str + obj2.ToString();
  681. }
  682. }
  683. str = str + ", ";
  684. }
  685. if (str.Length > 2)
  686. {
  687. str = str.Substring(0, str.Length - 2);
  688. }
  689. }
  690. if (objectInstance == null)
  691. {
  692. string fullName = this.objectType.FullName;
  693. if (this.objectType == typeof(IntrinsicFunctions))
  694. {
  695. fullName = "MSBuild";
  696. }
  697. if ((this.bindingFlags & BindingFlags.InvokeMethod) == BindingFlags.InvokeMethod)
  698. {
  699. return ("[" + fullName + "]::" + name + "(" + str + ")");
  700. }
  701. return ("[" + fullName + "]::" + name);
  702. }
  703. string str4 = "\"" + objectInstance + "\"";
  704. if ((this.bindingFlags & BindingFlags.InvokeMethod) == BindingFlags.InvokeMethod)
  705. {
  706. return (str4 + "." + name + "(" + str + ")");
  707. }
  708. return (str4 + "." + name);
  709. }
  710. private static Type GetTypeForStaticMethod(string typeName)
  711. {
  712. Type typeFromAssembly;
  713. Tuple<string, Type> tuple;
  714. if (FunctionConstants.AvailableStaticMethods.TryGetValue(typeName, out tuple) && (tuple != null))
  715. {
  716. ErrorUtilities.VerifyThrow((tuple.Item1 != null) || (tuple.Item2 != null), "Function type information needs either string or type represented.");
  717. if (tuple.Item2 != null)
  718. {
  719. return tuple.Item2;
  720. }
  721. if (tuple.Item1 != null)
  722. {
  723. typeName = tuple.Item1;
  724. typeFromAssembly = Type.GetType(typeName, false, true);
  725. FunctionConstants.AvailableStaticMethods[typeName] = new Tuple<string, Type>(typeName, typeFromAssembly);
  726. return typeFromAssembly;
  727. }
  728. }
  729. typeFromAssembly = Type.GetType(typeName, false, true);
  730. if (typeFromAssembly == null)
  731. {
  732. if (!(Environment.GetEnvironmentVariable("MSBUILDENABLEALLPROPERTYFUNCTIONS") == "1"))
  733. {
  734. return typeFromAssembly;
  735. }
  736. if (typeFromAssembly == null)
  737. {
  738. typeFromAssembly = Expander<P, I>.Function<T>.GetTypeFromAssembly(typeName, "System");
  739. }
  740. if (typeFromAssembly == null)
  741. {
  742. typeFromAssembly = Expander<P, I>.Function<T>.GetTypeFromAssembly(typeName, "System.Core");
  743. }
  744. if (typeFromAssembly == null)
  745. {
  746. typeFromAssembly = Expander<P, I>.Function<T>.GetTypeFromAssemblyUsingNamespace(typeName);
  747. }
  748. if (typeFromAssembly != null)
  749. {
  750. FunctionConstants.AvailableStaticMethods[typeName] = new Tuple<string, Type>(typeName, typeFromAssembly);
  751. }
  752. }
  753. return typeFromAssembly;
  754. }
  755. private static Type GetTypeFromAssembly(string typeName, string candidateAssemblyName)
  756. {
  757. Type type = null;
  758. Assembly assembly = Assembly.LoadWithPartialName(candidateAssemblyName);
  759. if (assembly != null)
  760. {
  761. type = assembly.GetType(typeName, false, true);
  762. }
  763. return type;
  764. }
  765. private static Type GetTypeFromAssemblyUsingNamespace(string typeName)
  766. {
  767. string str = typeName;
  768. int length = str.LastIndexOf('.');
  769. Type typeFromAssembly = null;
  770. ErrorUtilities.VerifyThrow(length > 0, "Invalid typename: {0}", typeName);
  771. while (length > 0)
  772. {
  773. string candidateAssemblyName = null;
  774. candidateAssemblyName = str.Substring(0, length);
  775. typeFromAssembly = Expander<P, I>.Function<T>.GetTypeFromAssembly(typeName, candidateAssemblyName);
  776. if (typeFromAssembly != null)
  777. {
  778. return typeFromAssembly;
  779. }
  780. length = candidateAssemblyName.LastIndexOf('.');
  781. }
  782. return null;
  783. }
  784. private bool IsStaticMethodAvailable(Type objectType, string methodName)
  785. {
  786. if (objectType == typeof(IntrinsicFunctions))
  787. {
  788. return true;
  789. }
  790. string key = objectType.FullName + "::" + methodName;
  791. return (FunctionConstants.AvailableStaticMethods.ContainsKey(objectType.FullName) || (FunctionConstants.AvailableStaticMethods.ContainsKey(key) || (Environment.GetEnvironmentVariable("MSBUILDENABLEALLPROPERTYFUNCTIONS") == "1")));
  792. }
  793. private object LateBindExecute(Exception ex, BindingFlags bindingFlags, object objectInstance, object[] args, bool isConstructor)
  794. {
  795. ParameterInfo[] parameters = null;
  796. MethodBase[] constructors = null;
  797. MethodBase base2 = null;
  798. Type[] types = new Type[this.arguments.Length];
  799. for (int i = 0; i < this.arguments.Length; i++)
  800. {
  801. types[i] = typeof(string);
  802. }
  803. if (isConstructor)
  804. {
  805. base2 = this.objectType.GetConstructor(bindingFlags, null, types, null);
  806. }
  807. else
  808. {
  809. base2 = this.objectType.GetMethod(this.name, bindingFlags, null, types, null);
  810. }
  811. if (base2 == null)
  812. {
  813. if (isConstructor)
  814. {
  815. constructors = this.objectType.GetConstructors(bindingFlags);
  816. }
  817. else
  818. {
  819. constructors = this.objectType.GetMethods(bindingFlags);
  820. }
  821. object[] objArray = null;
  822. foreach (MethodBase base3 in constructors)
  823. {
  824. parameters = base3.GetParameters();
  825. if ((parameters.Length == this.arguments.Length) && (isConstructor || string.Equals(base3.Name, this.name, StringComparison.OrdinalIgnoreCase)))
  826. {
  827. objArray = Expander<P, I>.Function<T>.CoerceArguments(args, parameters);
  828. if (objArray != null)
  829. {
  830. base2 = base3;
  831. args = objArray;
  832. break;
  833. }
  834. }
  835. }
  836. }
  837. object obj2 = null;
  838. if ((base2 != null) && (args != null))
  839. {
  840. if (isConstructor)
  841. {
  842. obj2 = ((ConstructorInfo) base2).Invoke(args);
  843. }
  844. else
  845. {
  846. obj2 = ((MethodInfo) base2).Invoke(objectInstance, args);
  847. }
  848. }
  849. else if (!isConstructor)
  850. {
  851. throw ex;
  852. }
  853. if ((obj2 == null) && isConstructor)
  854. {
  855. throw new TargetInvocationException(new MissingMethodException());
  856. }
  857. return obj2;
  858. }
  859. internal string ExpressionRootName
  860. {
  861. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  862. get
  863. {
  864. return this.expressionRootName;
  865. }
  866. }
  867. }
  868. private static class ItemExpander
  869. {
  870. private static bool ExpandItemVectorMatchIntoStringBuilder<S>(Expander<P, I> expander, ExpressionShredder.ItemExpressionCapture match, IItemProvider<S> items, IElementLocation elementLocation, StringBuilder builder, ExpanderOptions options) where S: class, IItem
  871. {
  872. string itemType = match.ItemType;
  873. string str2 = (match.Separator != null) ? match.Separator : ";";
  874. ProjectErrorUtilities.VerifyThrowInvalidProject(!string.IsNullOrEmpty(itemType), elementLocation, "InvalidFunctionPropertyExpression");
  875. ICollection<S> itemsOfType = items.GetItems(itemType);
  876. if (itemsOfType.Count != 0)
  877. {
  878. if (match.Captures == null)
  879. {
  880. foreach (S local in itemsOfType)
  881. {
  882. if ((local.EvaluatedIncludeEscaped.Length > 0) && ((options & ExpanderOptions.BreakOnNotEmpty) != ExpanderOptions.Invalid))
  883. {
  884. return true;
  885. }
  886. builder.Append(local.EvaluatedIncludeEscaped);
  887. builder.Append(str2);
  888. }
  889. }
  890. else
  891. {
  892. Stack<TransformFunction<P, I, S>> transformFunctionStack = Expander<P, I>.ItemExpander.PrepareTransformStackFromMatch<S>(elementLocation, match);
  893. foreach (Tuple<string, S> tuple in Expander<P, I>.ItemExpander.Transform<S>(expander, true, transformFunctionStack, IntrinsicItemFunctions<P, I, S>.GetItemTupleEnumerator(itemsOfType)))
  894. {
  895. if (((tuple.Item1 != null) && (tuple.Item1.Length > 0)) && ((options & ExpanderOptions.BreakOnNotEmpty) != ExpanderOptions.Invalid))
  896. {
  897. return true;
  898. }
  899. if (tuple.Item1 != null)
  900. {
  901. builder.Append(tuple.Item1);
  902. }
  903. builder.Append(str2);
  904. }
  905. }
  906. if (builder.Length > 0)
  907. {
  908. builder.Remove(builder.Length - str2.Length, str2.Length);
  909. }
  910. }
  911. return false;
  912. }
  913. internal static string ExpandItemVectorsIntoString<T>(Expander<P, I> expander, string expression, IItemProvider<T> items, ExpanderOptions options, IElementLocation elementLocation) where T: class, IItem
  914. {
  915. if (((options & ExpanderOptions.ExpandItems) == ExpanderOptions.Invalid) || (expression.Length == 0))
  916. {
  917. return expression;
  918. }
  919. ErrorUtilities.VerifyThrow(items != null, "Cannot expand items without providing items");
  920. List<ExpressionShredder.ItemExpressionCapture> referencedItemExpressions = ExpressionShredder.GetReferencedItemExpressions(expression);
  921. if (referencedItemExpressions == null)
  922. {
  923. return expression;
  924. }
  925. StringBuilder builder = new StringBuilder();
  926. int startIndex = 0;
  927. for (int i = 0; i < referencedItemExpressions.Count; i++)
  928. {
  929. if (referencedItemExpressions[i].Index > startIndex)
  930. {
  931. if ((options & ExpanderOptions.BreakOnNotEmpty) != ExpanderOptions.Invalid)
  932. {
  933. return null;
  934. }
  935. builder.Append(expression, startIndex, referencedItemExpressions[i].Index - startIndex);
  936. }
  937. if (Expander<P, I>.ItemExpander.ExpandItemVectorMatchIntoStringBuilder<T>(expander, referencedItemExpressions[i], items, elementLocation, builder, options))
  938. {
  939. return null;
  940. }
  941. startIndex = referencedItemExpressions[i].Index + referencedItemExpressions[i].Length;
  942. }
  943. builder.Append(expression, startIndex, expression.Length - startIndex);
  944. return OpportunisticIntern.StringBuilderToString(builder);
  945. }
  946. internal static IList<T> ExpandSingleItemVectorExpressionIntoItems<S, T>(Expander<P, I> expander, string expression, IItemProvider<S> items, IItemFactory<S, T> itemFactory, ExpanderOptions options, bool includeNullEntries, out bool isTransformExpression, IElementLocation elementLocation) where S: class, IItem where T: class, IItem
  947. {
  948. isTransformExpression = false;
  949. if (((options & ExpanderOptions.ExpandItems) == ExpanderOptions.Invalid) || (expression.Length == 0))
  950. {
  951. return null;
  952. }
  953. ErrorUtilities.VerifyThrow(items != null, "Cannot expand items without providing items");
  954. List<ExpressionShredder.ItemExpressionCapture> referencedItemExpressions = null;
  955. if (Expander<P, I>.invariantCompareInfo.IndexOf(expression, '@') == -1)
  956. {
  957. return null;
  958. }
  959. referencedItemExpressions = ExpressionShredder.GetReferencedItemExpressions(expression);
  960. if (referencedItemExpressions == null)
  961. {
  962. return null;
  963. }
  964. ExpressionShredder.ItemExpressionCapture match = refere

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