/SHFB/Source/MRefBuilder/CCI/Nodes.cs

# · C# · 18432 lines · 16444 code · 892 blank · 1096 comment · 4706 complexity · 0ba47bd13f8400a94c762348c4ab196d MD5 · raw file

  1. // Copyright Š Microsoft Corporation.
  2. // This source file is subject to the Microsoft Permissive License.
  3. // See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
  4. // All other rights reserved.
  5. // Change history:
  6. // 02/03/2012 - EFW - Fixed Method.ImplicitlyImplementedInterfaceMethods so that it recognizes interface
  7. // member matches when the return type is generic.
  8. // 03/28/2012 - EFW - Fixed TypeNode.Attributes so that it won't get stuck in an endless loop if a type's
  9. // attribute references the type being parsed.
  10. // 04/04/2012 - EFW - Fixed TypeNode.NestedTypes so that it won't get stuck in an endless loop when a type
  11. // contains a nested type that itself implements a nested type from within the containing type.
  12. // 11/30/2012 - EFW - Added updates based on changes submitted by ComponentOne to fix crashes caused by
  13. // obfuscated member names.
  14. // 11/21/2013 - EFW - Cleared out the conditional statements and unused code and updated based on changes to
  15. // ListTemplate.cs.
  16. // 03/14/2014 - EFW - Fixed bug in TypeNode.GetMatchingMethod() reported by SHarwell.
  17. using System.Collections;
  18. using System.Collections.Generic;
  19. using System.Globalization;
  20. using System.Compiler.Metadata;
  21. using System.Diagnostics;
  22. using System.IO;
  23. using System.Text;
  24. using System.Xml;
  25. using BindingFlags = System.Reflection.BindingFlags;
  26. namespace System.Compiler
  27. {
  28. /// <summary>
  29. /// This interface can be used to link an arbitrary source text provider into an IR tree via a DocumentText instance.
  30. /// </summary>
  31. public interface ISourceText
  32. {
  33. /// <summary>
  34. /// The number of characters in the source text.
  35. /// A "character" corresponds to a System.Char which is actually a Unicode UTF16 code point to be precise.
  36. /// </summary>
  37. int Length { get; }
  38. /// <summary>
  39. /// Retrieves a substring from this instance. The substring starts with the character at the specified index and has a specified length.
  40. /// </summary>
  41. string Substring(int startIndex, int length);
  42. /// <summary>
  43. /// Retrieves the character at the given position. The first character is at position zero.
  44. /// </summary>
  45. char this[int position] { get; }
  46. /// <summary>
  47. /// Indicates that the text has been fully scanned and further references to the text are expected to be infrequent.
  48. /// The underlying object can now choose to clear cached information if it comes under resource pressure.
  49. /// </summary>
  50. void MakeCollectible();
  51. }
  52. public unsafe interface ISourceTextBuffer : ISourceText
  53. {
  54. /// <summary>
  55. /// Returns null unless the implementer is based on an ASCII buffer that stays alive as long at the implementer itself.
  56. /// An implementer that returns a non-null value is merely a wrapper to keep the buffer alive. No further methods will
  57. /// be called on the interface in this case.
  58. /// </summary>
  59. byte* Buffer { get; }
  60. }
  61. /// <summary>
  62. /// This class provides a uniform interface to program sources provided in the form of Unicode strings,
  63. /// unsafe pointers to ASCII buffers (as obtained from a memory mapped file, for instance) as well as
  64. /// arbitrary source text providers that implement the ISourceText interface.
  65. /// </summary>
  66. public sealed unsafe class DocumentText
  67. {
  68. /// <summary>
  69. /// If this is not null it is used to obtain 8-bit ASCII characters.
  70. /// </summary>
  71. public byte* AsciiStringPtr;
  72. /// <summary>
  73. /// If this is not null it represents a Unicode string encoded as UTF16.
  74. /// </summary>
  75. public string Source;
  76. /// <summary>
  77. /// If this is not null the object implement ISourceText provides some way to get at individual characters and substrings.
  78. /// </summary>
  79. public ISourceText TextProvider;
  80. /// <summary>
  81. /// The number of characters in the source document.
  82. /// A "character" corresponds to a System.Char which is actually a Unicode UTF16 code point to be precise.
  83. /// </summary>
  84. public int Length;
  85. public DocumentText(string source)
  86. {
  87. if(source == null) { Debug.Assert(false); return; }
  88. this.Source = source;
  89. this.Length = source.Length;
  90. }
  91. public DocumentText(ISourceText textProvider)
  92. {
  93. if(textProvider == null) { Debug.Assert(false); return; }
  94. this.TextProvider = textProvider;
  95. this.Length = textProvider.Length;
  96. }
  97. public unsafe DocumentText(ISourceTextBuffer textProvider)
  98. {
  99. if(textProvider == null) { Debug.Assert(false); return; }
  100. this.TextProvider = textProvider;
  101. this.AsciiStringPtr = textProvider.Buffer;
  102. this.Length = textProvider.Length;
  103. }
  104. /// <summary>
  105. /// Compare this.Substring(offset, length) for equality with str.
  106. /// Call this only if str.Length is known to be equal to length.
  107. /// </summary>
  108. public bool Equals(string str, int position, int length)
  109. { //TODO: (int position, int length, string str)
  110. if(str == null) { Debug.Assert(false); return false; }
  111. if(str.Length != length) { Debug.Assert(false); return false; }
  112. if(position < 0 || position + length > this.Length) { Debug.Assert(false); return false; }
  113. unsafe
  114. {
  115. byte* p = this.AsciiStringPtr;
  116. if(p != null)
  117. {
  118. for(int i = position, j = 0; j < length; i++, j++)
  119. if(((char)*(p + i)) != str[j])
  120. return false;
  121. return true;
  122. }
  123. }
  124. string source = this.Source;
  125. if(source != null)
  126. {
  127. for(int i = position, j = 0; j < length; i++, j++)
  128. if(source[i] != str[j])
  129. return false;
  130. return true;
  131. }
  132. ISourceText myProvider = this.TextProvider;
  133. if(myProvider == null) { Debug.Assert(false); return false; }
  134. for(int i = position, j = 0; j < length; i++, j++)
  135. if(myProvider[i] != str[j])
  136. return false;
  137. return true;
  138. }
  139. /// <summary>
  140. /// Compares the substring of the specified length starting at offset, with the substring in DocumentText starting at textOffset.
  141. /// </summary>
  142. /// <param name="offset">The index of the first character of the substring of this DocumentText.</param>
  143. /// <param name="text">The Document text with the substring being compared to.</param>
  144. /// <param name="textOffset">The index of the first character of the substring of the DocumentText being compared to.</param>
  145. /// <param name="length">The number of characters in the substring being compared.</param>
  146. /// <returns></returns>
  147. public bool Equals(int offset, DocumentText text, int textOffset, int length)
  148. { //TODO: (int position, int length, DocumentText text, int textPosition)
  149. if(offset < 0 || length < 0 || offset + length > this.Length) { Debug.Assert(false); return false; }
  150. if(textOffset < 0 || text == null || textOffset + length > text.Length) { Debug.Assert(false); return false; }
  151. unsafe
  152. {
  153. byte* p = this.AsciiStringPtr;
  154. if(p != null)
  155. {
  156. unsafe
  157. {
  158. byte* q = text.AsciiStringPtr;
  159. if(q != null)
  160. {
  161. for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
  162. if(*(p + i) != *(q + j))
  163. return false;
  164. return true;
  165. }
  166. }
  167. string textSource = text.Source;
  168. if(textSource != null)
  169. {
  170. for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
  171. if(((char)*(p + i)) != textSource[j])
  172. return false;
  173. return true;
  174. }
  175. ISourceText textProvider = text.TextProvider;
  176. if(textProvider == null) { Debug.Assert(false); return false; }
  177. for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
  178. if(((char)*(p + i)) != textProvider[j])
  179. return false;
  180. return true;
  181. }
  182. }
  183. string source = this.Source;
  184. if(source != null)
  185. {
  186. unsafe
  187. {
  188. byte* q = text.AsciiStringPtr;
  189. if(q != null)
  190. {
  191. for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
  192. if(source[i] != (char)*(q + j))
  193. return false;
  194. return true;
  195. }
  196. }
  197. string textSource = text.Source;
  198. if(textSource != null)
  199. {
  200. for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
  201. if(source[i] != textSource[j])
  202. return false;
  203. return true;
  204. }
  205. ISourceText textProvider = text.TextProvider;
  206. if(textProvider == null) { Debug.Assert(false); return false; }
  207. for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
  208. if(source[i] != textProvider[j])
  209. return false;
  210. return true;
  211. }
  212. {
  213. ISourceText myProvider = this.TextProvider;
  214. if(myProvider == null) { Debug.Assert(false); return false; }
  215. unsafe
  216. {
  217. byte* q = text.AsciiStringPtr;
  218. if(q != null)
  219. {
  220. for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
  221. if(myProvider[i] != (char)*(q + j))
  222. return false;
  223. return true;
  224. }
  225. }
  226. string textSource = text.Source;
  227. if(textSource != null)
  228. {
  229. for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
  230. if(myProvider[i] != textSource[j])
  231. return false;
  232. return true;
  233. }
  234. ISourceText textProvider = text.TextProvider;
  235. if(textProvider == null) { Debug.Assert(false); return false; }
  236. for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
  237. if(myProvider[i] != textProvider[j])
  238. return false;
  239. return true;
  240. }
  241. }
  242. /// <summary>
  243. /// Retrieves a substring from this instance. The substring starts at a specified character position and has a specified length.
  244. /// </summary>
  245. public string/*!*/ Substring(int position, int length)
  246. {
  247. if(position < 0 || length < 0 || position + length > this.Length + 1) { Debug.Assert(false); return ""; }
  248. if(position + length > this.Length)
  249. length = this.Length - position; //Allow virtual EOF character to be included in length
  250. if(this.AsciiStringPtr != null)
  251. {
  252. unsafe
  253. {
  254. return new String((sbyte*)this.AsciiStringPtr, position, length, System.Text.Encoding.ASCII);
  255. }
  256. }
  257. else if(this.Source != null)
  258. return this.Source.Substring(position, length);
  259. else if(this.TextProvider != null)
  260. return this.TextProvider.Substring(position, length);
  261. else
  262. {
  263. Debug.Assert(false);
  264. return "";
  265. }
  266. }
  267. /// <summary>
  268. /// Retrieves the character at the given position. The first character is at position zero.
  269. /// </summary>
  270. public char this[int position]
  271. {
  272. get
  273. {
  274. if(position < 0 || position >= this.Length) { Debug.Assert(false); return (char)0; }
  275. if(this.AsciiStringPtr != null)
  276. {
  277. unsafe
  278. {
  279. unchecked
  280. {
  281. return (char)*(this.AsciiStringPtr + position);
  282. }
  283. }
  284. }
  285. else if(this.Source != null)
  286. return this.Source[position];
  287. else if(this.TextProvider != null)
  288. return this.TextProvider[position];
  289. else
  290. {
  291. Debug.Assert(false);
  292. return (char)0;
  293. }
  294. }
  295. }
  296. }
  297. /// <summary>
  298. /// A source document from which an Abstract Syntax Tree has been derived.
  299. /// </summary>
  300. public class Document
  301. {
  302. /// <summary>
  303. /// A Guid that identifies the kind of document to applications such as a debugger. Typically System.Diagnostics.SymbolStore.SymDocumentType.Text.
  304. /// </summary>
  305. public System.Guid DocumentType;
  306. /// <summary>
  307. /// A Guid that identifies the programming language used in the source document. Typically used by a debugger to locate language specific logic.
  308. /// </summary>
  309. public System.Guid Language;
  310. /// <summary>
  311. /// A Guid that identifies the compiler vendor programming language used in the source document. Typically used by a debugger to locate vendor specific logic.
  312. /// </summary>
  313. public System.Guid LanguageVendor;
  314. /// <summary>
  315. /// The line number corresponding to the first character in Text. Typically 1 but can be changed by C# preprocessor directives.
  316. /// </summary>
  317. public int LineNumber;
  318. /// <summary>
  319. /// Indicates that the document contains machine generated source code that should not show up in tools such as debuggers.
  320. /// Can be set by C# preprocessor directives.
  321. /// </summary>
  322. public bool Hidden;
  323. /// <summary>
  324. /// The name of the document. Typically a file name. Can be a full or relative file path, or a URI or some other kind of identifier.
  325. /// </summary>
  326. public string/*!*/ Name;
  327. /// <summary>
  328. /// Contains the source text.
  329. /// </summary>
  330. public DocumentText Text;
  331. public Document()
  332. {
  333. this.Name = "";
  334. //^ base();
  335. }
  336. public Document(string/*!*/ name, int lineNumber, string text, System.Guid documentType, System.Guid language, System.Guid languageVendor)
  337. : this(name, lineNumber, new DocumentText(text), documentType, language, languageVendor)
  338. {
  339. }
  340. public Document(string/*!*/ name, int lineNumber, DocumentText text, System.Guid documentType, System.Guid language, System.Guid languageVendor)
  341. {
  342. this.DocumentType = documentType;
  343. this.Language = language;
  344. this.LanguageVendor = languageVendor;
  345. this.LineNumber = lineNumber;
  346. this.Name = name;
  347. this.Text = text;
  348. //^ base();
  349. }
  350. /// <summary>
  351. /// Maps the given zero based character position to the number of the source line containing the same character.
  352. /// Line number counting starts from the value of LineNumber.
  353. /// </summary>
  354. public virtual int GetLine(int position)
  355. {
  356. int line = 0;
  357. int column = 0;
  358. this.GetPosition(position, out line, out column);
  359. return line + this.LineNumber;
  360. }
  361. /// <summary>
  362. /// Maps the given zero based character position in the entire text to the position of the same character in a source line.
  363. /// Counting within the source line starts at 1.
  364. /// </summary>
  365. public virtual int GetColumn(int position)
  366. {
  367. int line = 0;
  368. int column = 0;
  369. this.GetPosition(position, out line, out column);
  370. return column + 1;
  371. }
  372. /// <summary>
  373. /// Given a startLine, startColum, endLine and endColumn, this returns the corresponding startPos and endPos. In other words it
  374. /// converts a range expression in line and columns to a range expressed as a start and end character position.
  375. /// </summary>
  376. /// <param name="startLine">The number of the line containing the first character. The number of the first line equals this.LineNumber.</param>
  377. /// <param name="startColumn">The position of the first character relative to the start of the line. Counting from 1.</param>
  378. /// <param name="endLine">The number of the line contain the character that immediate follows the last character of the range.</param>
  379. /// <param name="endColumn">The position, in the last line, of the character that immediately follows the last character of the range.</param>
  380. /// <param name="startPos">The position in the entire text of the first character of the range, counting from 0.</param>
  381. /// <param name="endPos">The position in the entire text of the character following the last character of the range.</param>
  382. public virtual void GetOffsets(int startLine, int startColumn, int endLine, int endColumn, out int startPos, out int endPos)
  383. {
  384. lock(this)
  385. {
  386. if(this.lineOffsets == null)
  387. this.ComputeLineOffsets();
  388. //^ assert this.lineOffsets != null;
  389. startPos = this.lineOffsets[startLine - this.LineNumber] + startColumn - 1;
  390. endPos = this.lineOffsets[endLine - this.LineNumber] + endColumn - 1;
  391. }
  392. }
  393. /// <summary>
  394. /// Retrieves a substring from the text of this Document. The substring starts at a specified character position and has a specified length.
  395. /// </summary>
  396. public virtual string Substring(int position, int length)
  397. {
  398. if(this.Text == null)
  399. return null;
  400. return this.Text.Substring(position, length);
  401. }
  402. /// <summary>
  403. /// Counts the number of end of line marker sequences in the given text.
  404. /// </summary>
  405. protected int GetLineCount(string/*!*/ text)
  406. {
  407. int n = text == null ? 0 : text.Length;
  408. int count = 0;
  409. for(int i = 0; i < n; i++)
  410. {
  411. switch(text[i])
  412. {
  413. case '\r':
  414. if(i + 1 < n && text[i + 1] == '\n')
  415. i++;
  416. count++;
  417. break;
  418. case '\n':
  419. case (char)0x2028:
  420. case (char)0x2029:
  421. count++;
  422. break;
  423. }
  424. }
  425. return count;
  426. }
  427. /// <summary>An array of offsets, with offset at index i corresponding to the position of the first character of line i, (counting lines from 0).</summary>
  428. private int[] lineOffsets;
  429. /// <summary>The number of lines in Text.</summary>
  430. private int lines;
  431. /// <summary>
  432. /// Returns the index in this.lineOffsets array such that this.lineOffsets[index] is less than or equal to offset
  433. /// and offset is less than lineOffsets[index+1]
  434. /// </summary>
  435. private int Search(int offset)
  436. {
  437. tryAgain:
  438. int[] lineOffsets = this.lineOffsets;
  439. int lines = this.lines;
  440. if(lineOffsets == null) { Debug.Assert(false); return -1; }
  441. if(offset < 0) { Debug.Assert(false); return -1; }
  442. int mid = 0;
  443. int low = 0;
  444. int high = lines - 1;
  445. while(low < high)
  446. {
  447. mid = (low + high) / 2;
  448. if(lineOffsets[mid] <= offset)
  449. {
  450. if(offset < lineOffsets[mid + 1])
  451. return mid;
  452. else
  453. low = mid + 1;
  454. }
  455. else
  456. high = mid;
  457. }
  458. Debug.Assert(lines == this.lines);
  459. Debug.Assert(lineOffsets[low] <= offset);
  460. Debug.Assert(offset < lineOffsets[low + 1]);
  461. if(lineOffsets != this.lineOffsets)
  462. goto tryAgain;
  463. return low;
  464. }
  465. /// <summary>
  466. /// Maps the given zero based character position in the entire text to a (line, column) pair corresponding to the same position.
  467. /// Counting within the source line starts at 0. Counting source lines start at 0.
  468. /// </summary>
  469. private void GetPosition(int offset, out int line, out int column)
  470. {
  471. line = 0;
  472. column = 0;
  473. if(offset < 0 || this.Text == null || offset > this.Text.Length) { Debug.Assert(false); return; }
  474. lock(this)
  475. {
  476. if(this.lineOffsets == null)
  477. this.ComputeLineOffsets();
  478. if(this.lineOffsets == null) { Debug.Assert(false); return; }
  479. int[] lineOffsets = this.lineOffsets;
  480. int index = this.Search(offset);
  481. Debug.Assert(lineOffsets == this.lineOffsets);
  482. if(index < 0 || index >= this.lineOffsets.Length) { Debug.Assert(false); return; }
  483. Debug.Assert(this.lineOffsets[index] <= offset && offset < this.lineOffsets[index + 1]);
  484. line = index;
  485. column = offset - this.lineOffsets[index];
  486. }
  487. }
  488. /// <summary>
  489. /// Adds the given offset to the this.lineOffsets table as the offset corresponding to the start of line this.lines+1.
  490. /// </summary>
  491. private void AddOffset(int offset)
  492. {
  493. if(this.lineOffsets == null || this.lines < 0) { Debug.Assert(false); return; }
  494. if(this.lines >= this.lineOffsets.Length)
  495. {
  496. int n = this.lineOffsets.Length;
  497. if(n <= 0)
  498. n = 16;
  499. int[] newLineOffsets = new int[n * 2];
  500. Array.Copy(this.lineOffsets, newLineOffsets, this.lineOffsets.Length);
  501. this.lineOffsets = newLineOffsets;
  502. }
  503. this.lineOffsets[this.lines++] = offset;
  504. }
  505. public virtual void InsertOrDeleteLines(int offset, int lineCount)
  506. {
  507. if(lineCount == 0)
  508. return;
  509. if(offset < 0 || this.Text == null || offset > this.Text.Length) { Debug.Assert(false); return; }
  510. lock(this)
  511. {
  512. if(this.lineOffsets == null)
  513. if(this.lineOffsets == null)
  514. this.ComputeLineOffsets();
  515. if(lineCount < 0)
  516. this.DeleteLines(offset, -lineCount);
  517. else
  518. this.InsertLines(offset, lineCount);
  519. }
  520. }
  521. private void DeleteLines(int offset, int lineCount)
  522. //^ requires offset >= 0 && this.Text != null && offset < this.Text.Length && lineCount > 0 && this.lineOffsets != null;
  523. {
  524. Debug.Assert(offset >= 0 && this.Text != null && offset < this.Text.Length && lineCount > 0 && this.lineOffsets != null);
  525. int index = this.Search(offset);
  526. if(index < 0 || index >= this.lines) { Debug.Assert(false); return; }
  527. for(int i = index + 1; i + lineCount < this.lines; i++)
  528. {
  529. this.lineOffsets[i] = this.lineOffsets[i + lineCount];
  530. }
  531. this.lines -= lineCount;
  532. if(this.lines <= index) { Debug.Assert(false); this.lines = index + 1; }
  533. }
  534. private void InsertLines(int offset, int lineCount)
  535. //^ requires offset >= 0 && this.Text != null && offset < this.Text.Length && lineCount > 0 && this.lineOffsets != null;
  536. {
  537. Debug.Assert(offset >= 0 && this.Text != null && offset < this.Text.Length && lineCount > 0 && this.lineOffsets != null);
  538. int index = this.Search(offset);
  539. if(index < 0 || index >= this.lines) { Debug.Assert(false); return; }
  540. int n = this.lineOffsets[this.lines - 1];
  541. for(int i = 0; i < lineCount; i++)
  542. this.AddOffset(++n);
  543. for(int i = lineCount; i > 0; i--)
  544. {
  545. this.lineOffsets[index + i + 1] = this.lineOffsets[index + 1];
  546. }
  547. }
  548. /// <summary>
  549. /// Populates this.lineOffsets with an array of offsets, with offset at index i corresponding to the position of the first
  550. /// character of line i, (counting lines from 0).
  551. /// </summary>
  552. private void ComputeLineOffsets()
  553. //ensures this.lineOffsets != null;
  554. {
  555. if(this.Text == null) { Debug.Assert(false); return; }
  556. int n = this.Text.Length;
  557. this.lineOffsets = new int[n / 10 + 1];
  558. this.lines = 0;
  559. this.AddOffset(0);
  560. for(int i = 0; i < n; i++)
  561. {
  562. switch(this.Text[i])
  563. {
  564. case '\r':
  565. if(i + 1 < n && this.Text[i + 1] == '\n')
  566. i++;
  567. this.AddOffset(i + 1);
  568. break;
  569. case '\n':
  570. case (char)0x2028:
  571. case (char)0x2029:
  572. this.AddOffset(i + 1);
  573. break;
  574. }
  575. }
  576. this.AddOffset(n + 1);
  577. this.AddOffset(n + 2);
  578. }
  579. /// <summary> Add one to this every time a Document instance gets a unique key.</summary>
  580. private static int uniqueKeyCounter;
  581. private int uniqueKey;
  582. /// <summary>
  583. /// An integer that uniquely distinguishes this document instance from every other document instance.
  584. /// This provides an efficient equality test to facilitate hashing.
  585. /// </summary>
  586. public int UniqueKey
  587. {
  588. get
  589. {
  590. if(this.uniqueKey == 0)
  591. {
  592. TryAgain:
  593. int c = Document.uniqueKeyCounter;
  594. int cp1 = c == int.MaxValue ? 1 : c + 1;
  595. if(System.Threading.Interlocked.CompareExchange(ref Document.uniqueKeyCounter, cp1, c) != c)
  596. goto TryAgain;
  597. this.uniqueKey = cp1;
  598. }
  599. return this.uniqueKey;
  600. }
  601. }
  602. }
  603. internal class UnmanagedDocument : Document
  604. {
  605. internal UnmanagedDocument(IntPtr ptrToISymUnmanagedDocument)
  606. {
  607. //^ base();
  608. ISymUnmanagedDocument idoc =
  609. (ISymUnmanagedDocument)System.Runtime.InteropServices.Marshal.GetTypedObjectForIUnknown(ptrToISymUnmanagedDocument, typeof(ISymUnmanagedDocument));
  610. if(idoc != null)
  611. {
  612. try
  613. {
  614. idoc.GetDocumentType(out this.DocumentType);
  615. idoc.GetLanguage(out this.Language);
  616. idoc.GetLanguageVendor(out this.LanguageVendor);
  617. uint capacity = 1024;
  618. uint len = 0;
  619. char[] buffer = new char[capacity];
  620. while(capacity >= 1024)
  621. {
  622. idoc.GetURL(capacity, out len, buffer);
  623. if(len < capacity)
  624. break;
  625. capacity += 1024;
  626. buffer = new char[capacity];
  627. }
  628. if(len > 0)
  629. this.Name = new String(buffer, 0, (int)len - 1);
  630. }
  631. finally
  632. {
  633. System.Runtime.InteropServices.Marshal.ReleaseComObject(idoc);
  634. }
  635. }
  636. this.LineNumber = -1;
  637. this.Text = null;
  638. }
  639. private List<int> lineList = new List<int>();
  640. private List<int> columnList = new List<int>();
  641. public override int GetLine(int offset)
  642. {
  643. return this.lineList[offset];
  644. }
  645. public override int GetColumn(int offset)
  646. {
  647. return this.columnList[offset];
  648. }
  649. public override void GetOffsets(int startLine, int startColumn, int endLine, int endColumn, out int startCol, out int endCol)
  650. {
  651. int i = UnmanagedDocument.BinarySearch(this.lineList, startLine);
  652. List<int> columnList = this.columnList;
  653. startCol = 0;
  654. for(int j = i, n = columnList.Count; j < n; j++)
  655. {
  656. if(columnList[j] >= startColumn) { startCol = j; break; }
  657. }
  658. endCol = 0;
  659. i = UnmanagedDocument.BinarySearch(this.lineList, endLine);
  660. for(int j = i, n = columnList.Count; j < n; j++)
  661. {
  662. if(columnList[j] >= endColumn) { endCol = j; break; }
  663. }
  664. }
  665. private static int BinarySearch(List<int> list, int value)
  666. {
  667. int mid = 0;
  668. int low = 0;
  669. int high = list.Count - 1;
  670. while(low < high)
  671. {
  672. mid = low + (high - low) / 2;
  673. if(list[mid] <= value)
  674. {
  675. if(list[mid + 1] > value)
  676. return mid;
  677. else
  678. low = mid + 1;
  679. }
  680. else
  681. high = mid;
  682. }
  683. return low;
  684. }
  685. public override void InsertOrDeleteLines(int offset, int lineCount)
  686. {
  687. Debug.Assert(false); //Caller should not be modifying an unmanaged document
  688. }
  689. internal int GetOffset(uint line, uint column)
  690. {
  691. this.lineList.Add((int)line);
  692. this.columnList.Add((int)column);
  693. return this.lineList.Count - 1;
  694. }
  695. }
  696. /// <summary>
  697. /// Records a location within a source document that corresponds to an Abstract Syntax Tree node.
  698. /// </summary>
  699. public struct SourceContext
  700. {
  701. /// <summary>The source document within which the AST node is located. Null if the node is not derived from a source document.</summary>
  702. public Document Document;
  703. /// <summary>
  704. /// The zero based index of the first character beyond the last character in the source document that corresponds to the AST node.
  705. /// </summary>
  706. public int EndPos;
  707. /// <summary>
  708. /// The zero based index of the first character in the source document that corresponds to the AST node.
  709. /// </summary>
  710. public int StartPos;
  711. public SourceContext(Document document)
  712. : this(document, 0, document == null ? 0 : (document.Text == null ? 0 : document.Text.Length))
  713. {
  714. }
  715. public SourceContext(Document document, int startPos, int endPos)
  716. {
  717. this.Document = document;
  718. this.StartPos = startPos;
  719. this.EndPos = endPos;
  720. }
  721. public SourceContext(Document/*!*/ document,
  722. int startLine, int startColumn, int endLine, int endColumn)
  723. {
  724. this.Document = document;
  725. this.Document.GetOffsets(startLine, startColumn, endLine, endColumn, out this.StartPos, out this.EndPos);
  726. }
  727. /// <summary>
  728. /// The number (counting from Document.LineNumber) of the line containing the first character in the source document that corresponds to the AST node.
  729. /// </summary>
  730. public int StartLine
  731. {
  732. get
  733. {
  734. if(this.Document == null)
  735. return 0;
  736. return this.Document.GetLine(this.StartPos);
  737. }
  738. }
  739. /// <summary>
  740. /// The number (counting from one) of the line column containing the first character in the source document that corresponds to the AST node.
  741. /// </summary>
  742. public int StartColumn
  743. {
  744. get
  745. {
  746. if(this.Document == null)
  747. return 0;
  748. return this.Document.GetColumn(this.StartPos);
  749. }
  750. }
  751. /// <summary>
  752. /// The number (counting from Document.LineNumber) of the line containing the first character beyond the last character in the source document that corresponds to the AST node.
  753. /// </summary>
  754. public int EndLine
  755. {
  756. get
  757. {
  758. if(this.Document == null || (this.Document.Text == null && !(this.Document is UnmanagedDocument)))
  759. return 0;
  760. if(this.Document.Text != null && this.EndPos >= this.Document.Text.Length)
  761. this.EndPos = this.Document.Text.Length;
  762. return this.Document.GetLine(this.EndPos);
  763. }
  764. }
  765. /// <summary>
  766. /// The number (counting from one) of the line column containing first character beyond the last character in the source document that corresponds to the AST node.
  767. /// </summary>
  768. public int EndColumn
  769. {
  770. get
  771. {
  772. if(this.Document == null || (this.Document.Text == null && !(this.Document is UnmanagedDocument)))
  773. return 0;
  774. if(this.Document.Text != null && this.EndPos >= this.Document.Text.Length)
  775. this.EndPos = this.Document.Text.Length;
  776. return this.Document.GetColumn(this.EndPos);
  777. }
  778. }
  779. /// <summary>
  780. /// Returns true if the line and column is greater than or equal the position of the first character
  781. /// and less than or equal to the position of the last character
  782. /// of the source document that corresponds to the AST node.
  783. /// </summary>
  784. /// <param name="line">A line number(counting from Document.LineNumber)</param>
  785. /// <param name="column">A column number (counting from one)</param>
  786. /// <returns></returns>
  787. public bool Encloses(int line, int column)
  788. {
  789. if(line < this.StartLine || line > this.EndLine)
  790. return false;
  791. if(line == this.StartLine)
  792. return column >= this.StartColumn && (column <= this.EndColumn || line < this.EndLine);
  793. if(line == this.EndLine)
  794. return column <= this.EndColumn;
  795. return true;
  796. }
  797. public bool Encloses(SourceContext sourceContext)
  798. {
  799. return this.StartPos <= sourceContext.StartPos && this.EndPos >= sourceContext.EndPos && this.EndPos > sourceContext.StartPos;
  800. }
  801. /// <summary>
  802. /// The substring of the source document that corresponds to the AST node.
  803. /// </summary>
  804. public string SourceText
  805. {
  806. get
  807. {
  808. if(this.Document == null)
  809. return null;
  810. return this.Document.Substring(this.StartPos, this.EndPos - this.StartPos);
  811. }
  812. }
  813. }
  814. public sealed class MarshallingInformation
  815. {
  816. private string @class;
  817. private string cookie;
  818. private int elementSize;
  819. private NativeType elementType;
  820. private NativeType nativeType;
  821. private int numberOfElements;
  822. private int paramIndex;
  823. private int size;
  824. public MarshallingInformation Clone()
  825. {
  826. return (MarshallingInformation)base.MemberwiseClone();
  827. }
  828. public string Class
  829. {
  830. get { return this.@class; }
  831. set { this.@class = value; }
  832. }
  833. public string Cookie
  834. {
  835. get { return this.cookie; }
  836. set { this.cookie = value; }
  837. }
  838. public int ElementSize
  839. {
  840. get { return this.elementSize; }
  841. set { this.elementSize = value; }
  842. }
  843. public NativeType ElementType
  844. {
  845. get { return this.elementType; }
  846. set { this.elementType = value; }
  847. }
  848. public NativeType NativeType
  849. {
  850. get { return this.nativeType; }
  851. set { this.nativeType = value; }
  852. }
  853. public int NumberOfElements
  854. {
  855. get { return this.numberOfElements; }
  856. set { this.numberOfElements = value; }
  857. }
  858. public int ParamIndex
  859. {
  860. get { return this.paramIndex; }
  861. set { this.paramIndex = value; }
  862. }
  863. public int Size
  864. {
  865. get { return this.size; }
  866. set { this.size = value; }
  867. }
  868. }
  869. public enum NativeType
  870. {
  871. Bool = 0x2, // 4 byte boolean value (true != 0, false == 0)
  872. I1 = 0x3, // 1 byte signed value
  873. U1 = 0x4, // 1 byte unsigned value
  874. I2 = 0x5, // 2 byte signed value
  875. U2 = 0x6, // 2 byte unsigned value
  876. I4 = 0x7, // 4 byte signed value
  877. U4 = 0x8, // 4 byte unsigned value
  878. I8 = 0x9, // 8 byte signed value
  879. U8 = 0xa, // 8 byte unsigned value
  880. R4 = 0xb, // 4 byte floating point
  881. R8 = 0xc, // 8 byte floating point
  882. Currency = 0xf, // A currency
  883. BStr = 0x13, // OLE Unicode BSTR
  884. LPStr = 0x14, // Ptr to SBCS string
  885. LPWStr = 0x15, // Ptr to Unicode string
  886. LPTStr = 0x16, // Ptr to OS preferred (SBCS/Unicode) string
  887. ByValTStr = 0x17, // OS preferred (SBCS/Unicode) inline string (only valid in structs)
  888. IUnknown = 0x19, // COM IUnknown pointer.
  889. IDispatch = 0x1a, // COM IDispatch pointer
  890. Struct = 0x1b, // Structure
  891. Interface = 0x1c, // COM interface
  892. SafeArray = 0x1d, // OLE SafeArray
  893. ByValArray = 0x1e, // Array of fixed size (only valid in structs)
  894. SysInt = 0x1f, // Hardware natural sized signed integer
  895. SysUInt = 0x20,
  896. VBByRefStr = 0x22,
  897. AnsiBStr = 0x23, // OLE BSTR containing SBCS characters
  898. TBStr = 0x24, // Ptr to OS preferred (SBCS/Unicode) BSTR
  899. VariantBool = 0x25, // OLE defined BOOLEAN (2 bytes, true == -1, false == 0)
  900. FunctionPtr = 0x26, // Function pointer
  901. AsAny = 0x28, // Paired with Object type and does runtime marshalling determination
  902. LPArray = 0x2a, // C style array
  903. LPStruct = 0x2b, // Pointer to a structure
  904. CustomMarshaler = 0x2c, // Native type supplied by custom code
  905. Error = 0x2d,
  906. NotSpecified = 0x50,
  907. }
  908. ///0-: Common
  909. ///1000-: HScript
  910. ///2000-: EcmaScript
  911. ///3000-: Zonnon
  912. ///4000-: Comega
  913. ///5000-: X++
  914. ///6000-: Spec#
  915. ///7000-: Sing#
  916. ///8000-: Xaml
  917. ///9000-: C/AL
  918. ///For your range contact hermanv@microsoft.com
  919. public enum NodeType
  920. {
  921. //Dummy
  922. Undefined = 0,
  923. //IL instruction node tags
  924. Add,
  925. Add_Ovf,
  926. Add_Ovf_Un,
  927. And,
  928. Arglist,
  929. Box,
  930. Branch,
  931. Call,
  932. Calli,
  933. Callvirt,
  934. Castclass,
  935. Ceq,
  936. Cgt,
  937. Cgt_Un,
  938. Ckfinite,
  939. Clt,
  940. Clt_Un,
  941. Conv_I,
  942. Conv_I1,
  943. Conv_I2,
  944. Conv_I4,
  945. Conv_I8,
  946. Conv_Ovf_I,
  947. Conv_Ovf_I_Un,
  948. Conv_Ovf_I1,
  949. Conv_Ovf_I1_Un,
  950. Conv_Ovf_I2,
  951. Conv_Ovf_I2_Un,
  952. Conv_Ovf_I4,
  953. Conv_Ovf_I4_Un,
  954. Conv_Ovf_I8,
  955. Conv_Ovf_I8_Un,
  956. Conv_Ovf_U,
  957. Conv_Ovf_U_Un,
  958. Conv_Ovf_U1,
  959. Conv_Ovf_U1_Un,
  960. Conv_Ovf_U2,
  961. Conv_Ovf_U2_Un,
  962. Conv_Ovf_U4,
  963. Conv_Ovf_U4_Un,
  964. Conv_Ovf_U8,
  965. Conv_Ovf_U8_Un,
  966. Conv_R_Un,
  967. Conv_R4,
  968. Conv_R8,
  969. Conv_U,
  970. Conv_U1,
  971. Conv_U2,
  972. Conv_U4,
  973. Conv_U8,
  974. Cpblk,
  975. DebugBreak,
  976. Div,
  977. Div_Un,
  978. Dup,
  979. EndFilter,
  980. EndFinally,
  981. ExceptionHandler,
  982. Initblk,
  983. Isinst,
  984. Jmp,
  985. Ldftn,
  986. Ldlen,
  987. Ldtoken,
  988. Ldvirtftn,
  989. Localloc,
  990. Mkrefany,
  991. Mul,
  992. Mul_Ovf,
  993. Mul_Ovf_Un,
  994. Neg,
  995. Nop,
  996. Not,
  997. Or,
  998. Pop,
  999. ReadOnlyAddressOf,
  1000. Refanytype,
  1001. Refanyval,
  1002. Rem,
  1003. Rem_Un,
  1004. Rethrow,
  1005. Shl,
  1006. Shr,
  1007. Shr_Un,
  1008. Sizeof,
  1009. SkipCheck,
  1010. Sub,
  1011. Sub_Ovf,
  1012. Sub_Ovf_Un,
  1013. SwitchInstruction,
  1014. Throw,
  1015. Unbox,
  1016. UnboxAny,
  1017. Xor,
  1018. //AST tags that are relevant to the binary reader
  1019. AddressDereference,
  1020. AddressOf,
  1021. AssignmentStatement,
  1022. Block,
  1023. Catch,
  1024. Construct,
  1025. ConstructArray,
  1026. Eq,
  1027. ExpressionStatement,
  1028. FaultHandler,
  1029. Filter,
  1030. Finally,
  1031. Ge,
  1032. Gt,
  1033. Identifier,
  1034. Indexer,
  1035. Instruction,
  1036. InterfaceExpression,
  1037. Le,
  1038. Literal,
  1039. LogicalNot,
  1040. Lt,
  1041. MemberBinding,
  1042. NamedArgument,
  1043. Namespace,
  1044. Ne,
  1045. Return,
  1046. This,
  1047. Try,
  1048. //Metadata node tags
  1049. ArrayType,
  1050. @Assembly,
  1051. AssemblyReference,
  1052. Attribute,
  1053. Class,
  1054. ClassParameter,
  1055. DelegateNode,
  1056. EnumNode,
  1057. Event,
  1058. Field,
  1059. FunctionPointer,
  1060. InstanceInitializer,
  1061. Interface,
  1062. Local,
  1063. Method,
  1064. Module,
  1065. ModuleReference,
  1066. OptionalModifier,
  1067. Parameter,
  1068. Pointer,
  1069. Property,
  1070. Reference,
  1071. RequiredModifier,
  1072. SecurityAttribute,
  1073. StaticInitializer,
  1074. Struct,
  1075. TypeParameter,
  1076. // The following NodeType definitions are not required
  1077. // for examining assembly metadata directly from binaries
  1078. //Serialization tags used for values that are not leaf nodes.
  1079. Array,
  1080. BlockReference,
  1081. CompilationParameters,
  1082. Document,
  1083. EndOfRecord,
  1084. Expression,
  1085. Guid,
  1086. List,
  1087. MarshallingInformation,
  1088. Member,
  1089. MemberReference,
  1090. MissingBlockReference,
  1091. MissingExpression,
  1092. MissingMemberReference,
  1093. String,
  1094. StringDictionary,
  1095. TypeNode,
  1096. Uri,
  1097. XmlNode,
  1098. //Source-based AST node tags
  1099. AddEventHandler,
  1100. AliasDefinition,
  1101. AnonymousNestedFunction,
  1102. ApplyToAll,
  1103. ArglistArgumentExpression,
  1104. ArglistExpression,
  1105. ArrayTypeExpression,
  1106. As,
  1107. Assertion,
  1108. AssignmentExpression,
  1109. Assumption,
  1110. Base,
  1111. BlockExpression,
  1112. BoxedTypeExpression,
  1113. ClassExpression,
  1114. CoerceTuple,
  1115. CollectionEnumerator,
  1116. Comma,
  1117. Compilation,
  1118. CompilationUnit,
  1119. CompilationUnitSnippet,
  1120. Conditional,
  1121. ConstructDelegate,
  1122. ConstructFlexArray,
  1123. ConstructIterator,
  1124. ConstructTuple,
  1125. Continue,
  1126. CopyReference,
  1127. CurrentClosure,
  1128. Decrement,
  1129. DefaultValue,
  1130. DoWhile,
  1131. Exit,
  1132. ExplicitCoercion,
  1133. ExpressionSnippet,
  1134. FieldInitializerBlock,
  1135. Fixed,
  1136. FlexArrayTypeExpression,
  1137. For,
  1138. ForEach,
  1139. FunctionDeclaration,
  1140. FunctionTypeExpression,
  1141. Goto,
  1142. GotoCase,
  1143. If,
  1144. ImplicitThis,
  1145. Increment,
  1146. InvariantTypeExpression,
  1147. Is,
  1148. LabeledStatement,
  1149. LocalDeclaration,
  1150. LocalDeclarationsStatement,
  1151. Lock,
  1152. LogicalAnd,
  1153. LogicalOr,
  1154. LRExpression,
  1155. MethodCall,
  1156. NameBinding,
  1157. NonEmptyStreamTypeExpression,
  1158. NonNullableTypeExpression,
  1159. NonNullTypeExpression,
  1160. NullableTypeExpression,
  1161. NullCoalesingExpression,
  1162. OutAddress,
  1163. Parentheses,
  1164. PointerTypeExpression,
  1165. PostfixExpression,
  1166. PrefixExpression,
  1167. QualifiedIdentifer,
  1168. RefAddress,
  1169. ReferenceTypeExpression,
  1170. RefTypeExpression,
  1171. RefValueExpression,
  1172. RemoveEventHandler,
  1173. Repeat,
  1174. ResourceUse,
  1175. SetterValue,
  1176. StackAlloc,
  1177. StatementSnippet,
  1178. StreamTypeExpression,
  1179. Switch,
  1180. SwitchCase,
  1181. SwitchCaseBottom,
  1182. TemplateInstance,
  1183. TupleTypeExpression,
  1184. TypeExpression,
  1185. TypeIntersectionExpression,
  1186. TypeMemberSnippet,
  1187. Typeof,
  1188. TypeReference,
  1189. Typeswitch,
  1190. TypeswitchCase,
  1191. TypeUnionExpression,
  1192. UnaryPlus,
  1193. UsedNamespace,
  1194. VariableDeclaration,
  1195. While,
  1196. Yield,
  1197. //Extended metadata node tags
  1198. ConstrainedType,
  1199. TupleType,
  1200. TypeAlias,
  1201. TypeIntersection,
  1202. TypeUnion,
  1203. //Query node tags
  1204. Composition,
  1205. QueryAggregate,
  1206. QueryAlias,
  1207. QueryAll,
  1208. QueryAny,
  1209. QueryAxis,
  1210. QueryCommit,
  1211. QueryContext,
  1212. QueryDelete,
  1213. QueryDifference,
  1214. QueryDistinct,
  1215. QueryExists,
  1216. QueryFilter,
  1217. QueryGeneratedType,
  1218. QueryGroupBy,
  1219. QueryInsert,
  1220. QueryIntersection,
  1221. QueryIterator,
  1222. QueryJoin,
  1223. QueryLimit,
  1224. QueryOrderBy,
  1225. QueryOrderItem,
  1226. QueryPosition,
  1227. QueryProject,
  1228. QueryQuantifiedExpression,
  1229. QueryRollback,
  1230. QuerySelect,
  1231. QuerySingleton,
  1232. QueryTransact,
  1233. QueryTypeFilter,
  1234. QueryUnion,
  1235. QueryUpdate,
  1236. QueryYielder,
  1237. //Contract node tags
  1238. Acquire,
  1239. Comprehension,
  1240. ComprehensionBinding,
  1241. Ensures,
  1242. EnsuresExceptional,
  1243. EnsuresNormal,
  1244. Iff,
  1245. Implies,
  1246. Invariant,
  1247. LogicalEqual,
  1248. LogicalImply,
  1249. Maplet,
  1250. MethodContract,
  1251. Modelfield,
  1252. ModelfieldContract,
  1253. OldExpression,
  1254. Range,
  1255. Read,
  1256. Requires,
  1257. RequiresOtherwise,
  1258. RequiresPlain,
  1259. TypeContract,
  1260. Write,
  1261. //Node tags for explicit modifiers in front-end
  1262. OptionalModifierTypeExpression,
  1263. RequiredModifierTypeExpression,
  1264. //Temporary node tags
  1265. Count,
  1266. Exists,
  1267. ExistsUnique,
  1268. Forall,
  1269. Max,
  1270. Min,
  1271. Product,
  1272. Sum,
  1273. Quantifier,
  1274. }
  1275. [Flags]
  1276. public enum AssemblyFlags
  1277. {
  1278. None = 0x0000,
  1279. PublicKey = 0x0001,
  1280. Library = 0x0002,
  1281. Platform = 0x0004,
  1282. NowPlatform = 0x0006,
  1283. SideBySideCompatible = 0x0000,
  1284. NonSideBySideCompatible = 0x0010,
  1285. NonSideBySideProcess = 0x0020,
  1286. NonSideBySideMachine = 0x0030,
  1287. CompatibilityMask = 0x00F0,
  1288. Retargetable = 0x0100,
  1289. DisableJITcompileOptimizer = 0x4000,
  1290. EnableJITcompileTracking = 0x8000
  1291. }
  1292. public enum AssemblyHashAlgorithm
  1293. {
  1294. None = 0x0000,
  1295. MD5 = 0x8003,
  1296. SHA1 = 0x8004
  1297. }
  1298. [Flags]
  1299. public enum CallingConventionFlags
  1300. {
  1301. Default = 0x0,
  1302. C = 0x1,
  1303. StandardCall = 0x2,
  1304. ThisCall = 0x3,
  1305. FastCall = 0x4,
  1306. VarArg = 0x5,
  1307. ArgumentConvention = 0x7,
  1308. Generic = 0x10,
  1309. HasThis = 0x20,
  1310. ExplicitThis = 0x40
  1311. }
  1312. [Flags]
  1313. public enum EventFlags
  1314. {
  1315. None = 0x0000,
  1316. SpecialName = 0x0200,
  1317. ReservedMask = 0x0400,
  1318. RTSpecialName = 0x0400,
  1319. Extend = MethodFlags.Extend, // used for languages with type extensions, e.g. Sing#
  1320. }
  1321. [Flags]
  1322. public enum FieldFlags
  1323. {
  1324. None = 0x0000,
  1325. FieldAccessMask = 0x0007,
  1326. CompilerControlled = 0x0000,
  1327. Private = 0x0001,
  1328. FamANDAssem = 0x0002,
  1329. Assembly = 0x0003,
  1330. Family = 0x0004,
  1331. FamORAssem = 0x0005,
  1332. Public = 0x0006,
  1333. Static = 0x0010,
  1334. InitOnly = 0x0020,
  1335. Literal = 0x0040,
  1336. NotSerialized = 0x0080,
  1337. SpecialName = 0x0200,
  1338. PinvokeImpl = 0x2000,
  1339. ReservedMask = 0x9500,
  1340. RTSpecialName = 0x0400,
  1341. HasFieldMarshal = 0x1000,
  1342. HasDefault = 0x8000,
  1343. HasFieldRVA = 0x0100,
  1344. }
  1345. [Flags]
  1346. public enum FileFlags
  1347. {
  1348. ContainsMetaData = 0x0000,
  1349. ContainsNoMetaData = 0x0001
  1350. }
  1351. [Flags]
  1352. public enum TypeParameterFlags
  1353. {
  1354. NonVariant = 0x0000,
  1355. Covariant = 0x0001,
  1356. Contravariant = 0x0002,
  1357. VarianceMask = 0x0003,
  1358. NoSpecialConstraint = 0x0000,
  1359. ReferenceTypeConstraint = 0x0004,
  1360. ValueTypeConstraint = 0x0008,
  1361. DefaultConstructorConstraint = 0x0010,
  1362. SpecialConstraintMask = 0x001C,
  1363. }
  1364. [Flags]
  1365. public enum MethodImplFlags
  1366. {
  1367. CodeTypeMask = 0x0003,
  1368. IL = 0x0000,
  1369. Native = 0x0001,
  1370. OPTIL = 0x0002,
  1371. Runtime = 0x0003,
  1372. ManagedMask = 0x0004,
  1373. Unmanaged = 0x0004,
  1374. Managed = 0x0000,
  1375. ForwardRef = 0x0010,
  1376. PreserveSig = 0x0080,
  1377. InternalCall = 0x1000,
  1378. Synchronized = 0x0020,
  1379. NoInlining = 0x0008,
  1380. MaxMethodImplVal = 0xffff
  1381. }
  1382. [Flags]
  1383. public enum MethodFlags
  1384. {
  1385. MethodAccessMask = 0x0007,
  1386. CompilerControlled = 0x0000,
  1387. Private = 0x0001,
  1388. FamANDAssem = 0x0002,
  1389. Assembly = 0x0003,
  1390. Family = 0x0004,
  1391. FamORAssem = 0x0005,
  1392. Public = 0x0006,
  1393. Static = 0x0010,
  1394. Final = 0x0020,
  1395. Virtual = 0x0040,
  1396. HideBySig = 0x0080,
  1397. VtableLayoutMask = 0x0100,
  1398. ReuseSlot = 0x0000,
  1399. NewSlot = 0x0100,
  1400. CheckAccessOnOverride = 0x0200,
  1401. Abstract = 0x0400,
  1402. SpecialName = 0x0800,
  1403. PInvokeImpl = 0x2000,
  1404. UnmanagedExport = 0xd000,
  1405. ReservedMask = 0xd000,
  1406. RTSpecialName = 0x1000,
  1407. HasSecurity = 0x4000,
  1408. RequireSecObject = 0x8000,
  1409. Extend = 0x01000000, // used for languages with type extensions, e.g. Sing#
  1410. }
  1411. public enum ModuleKind
  1412. {
  1413. ConsoleApplication,
  1414. WindowsApplication,
  1415. DynamicallyLinkedLibrary,
  1416. ManifestResourceFile,
  1417. UnmanagedDynamicallyLinkedLibrary
  1418. }
  1419. [Flags]
  1420. public enum ParameterFlags
  1421. {
  1422. None = 0x0000,
  1423. In = 0x0001,
  1424. Out = 0x0002,
  1425. Optional = 0x0010,
  1426. ReservedMask = 0xf000,
  1427. HasDefault = 0x1000,
  1428. HasFieldMarshal = 0x2000
  1429. }
  1430. [Flags]
  1431. public enum PEKindFlags
  1432. {
  1433. ILonly = 0x0001,
  1434. Requires32bits = 0x0002,
  1435. Requires64bits = 0x0004,
  1436. AMD = 0x0008
  1437. }
  1438. [Flags]
  1439. public enum PInvokeFlags
  1440. {
  1441. None = 0x0000,
  1442. NoMangle = 0x0001,
  1443. BestFitDisabled = 0x0020,
  1444. BestFitEnabled = 0x0010,
  1445. BestFitUseAsm = 0x0000,
  1446. BestFitMask = 0x0030,
  1447. CharSetMask = 0x0006,
  1448. CharSetNotSpec = 0x0000,
  1449. CharSetAns = 0x0002,
  1450. CharSetUnicode = 0x0004,
  1451. CharSetAuto = 0x0006,
  1452. SupportsLastError = 0x0040,
  1453. CallingConvMask = 0x0700,
  1454. CallConvWinapi = 0x0100,
  1455. CallConvCdecl = 0x0200,
  1456. CallConvStdcall = 0x0300,
  1457. CallConvThiscall = 0x0400,
  1458. CallConvFastcall = 0x0500,
  1459. ThrowOnUnmappableCharMask = 0x3000,
  1460. ThrowOnUnmappableCharEnabled = 0x1000,
  1461. ThrowOnUnmappableCharDisabled = 0x2000,
  1462. ThrowOnUnmappableCharUseAsm = 0x0000
  1463. }
  1464. [Flags]
  1465. public enum PropertyFlags
  1466. {
  1467. None = 0x0000,
  1468. SpecialName = 0x0200,
  1469. ReservedMask = 0xf400,
  1470. RTSpecialName = 0x0400,
  1471. Extend = MethodFlags.Extend, // used for languages with type extensions, e.g. Sing#
  1472. }
  1473. public enum PESection
  1474. {
  1475. Text,
  1476. SData,
  1477. TLS
  1478. };
  1479. [Flags]
  1480. public enum TypeFlags
  1481. {
  1482. None = 0x00000000,
  1483. VisibilityMask = 0x00000007,
  1484. NotPublic = 0x00000000,
  1485. Public = 0x00000001,
  1486. NestedPublic = 0x00000002,
  1487. NestedPrivate = 0x00000003,
  1488. NestedFamily = 0x00000004,
  1489. NestedAssembly = 0x00000005,
  1490. NestedFamANDAssem = 0x00000006,
  1491. NestedFamORAssem = 0x00000007,
  1492. LayoutMask = 0x00000018,
  1493. AutoLayout = 0x00000000,
  1494. SequentialLayout = 0x00000008,
  1495. ExplicitLayout = 0x00000010,
  1496. ClassSemanticsMask = 0x00000020,
  1497. Class = 0x00000000,
  1498. Interface = 0x00000020,
  1499. LayoutOverridden = 0x00000040, // even AutoLayout can be explicit or implicit
  1500. Abstract = 0x00000080,
  1501. Sealed = 0x00000100,
  1502. SpecialName = 0x00000400,
  1503. Import = 0x00001000,
  1504. Serializable = 0x00002000,
  1505. StringFormatMask = 0x00030000,
  1506. AnsiClass = 0x00000000,
  1507. UnicodeClass = 0x00010000,
  1508. AutoClass = 0x00020000,
  1509. BeforeFieldInit = 0x00100000,
  1510. ReservedMask = 0x00040800,
  1511. RTSpecialName = 0x00000800,
  1512. HasSecurity = 0x00040000,
  1513. Forwarder = 0x00200000, //The type is a stub left behind for backwards compatibility. References to this type are forwarded to another type by the CLR.
  1514. Extend = 0x01000000, // used for languages with type extensions, e.g. Sing#
  1515. }
  1516. public sealed class TrivialHashtable
  1517. {
  1518. struct HashEntry
  1519. {
  1520. public int Key;
  1521. public object Value;
  1522. }
  1523. private HashEntry[]/*!*/ entries;
  1524. private int count;
  1525. public TrivialHashtable()
  1526. {
  1527. this.entries = new HashEntry[16];
  1528. //this.count = 0;
  1529. }
  1530. private TrivialHashtable(HashEntry[]/*!*/ entries, int count)
  1531. {
  1532. this.entries = entries;
  1533. this.count = count;
  1534. }
  1535. public TrivialHashtable(int expectedEntries)
  1536. {
  1537. int initialSize = 16;
  1538. expectedEntries <<= 1;
  1539. while(initialSize < expectedEntries && initialSize > 0)
  1540. initialSize <<= 1;
  1541. if(initialSize < 0)
  1542. initialSize = 16;
  1543. this.entries = new HashEntry[initialSize];
  1544. //this.count = 0;
  1545. }
  1546. public int Count
  1547. {
  1548. get
  1549. {
  1550. return this.count;
  1551. }
  1552. }
  1553. private void Expand()
  1554. {
  1555. HashEntry[] oldEntries = this.entries;
  1556. int n = oldEntries.Length;
  1557. int m = n * 2;
  1558. if(m <= 0)
  1559. return;
  1560. HashEntry[] entries = new HashEntry[m];
  1561. int count = 0;
  1562. for(int i = 0; i < n; i++)
  1563. {
  1564. int key = oldEntries[i].Key;
  1565. if(key <= 0)
  1566. continue; //No entry (0) or deleted entry (-1)
  1567. object value = oldEntries[i].Value;
  1568. Debug.Assert(value != null);
  1569. int j = key & (m - 1);
  1570. int k = entries[j].Key;
  1571. while(true)
  1572. {
  1573. if(k == 0)
  1574. {
  1575. entries[j].Value = value;
  1576. entries[j].Key = key;
  1577. count++;
  1578. break;
  1579. }
  1580. j++;
  1581. if(j >= m)
  1582. j = 0;
  1583. k = entries[j].Key;
  1584. }
  1585. }
  1586. this.entries = entries;
  1587. this.count = count;
  1588. }
  1589. public object this[int key]
  1590. {
  1591. get
  1592. {
  1593. if(key <= 0)
  1594. throw new ArgumentException(ExceptionStrings.KeyNeedsToBeGreaterThanZero, "key");
  1595. HashEntry[] entries = this.entries;
  1596. int n = entries.Length;
  1597. int i = key & (n - 1);
  1598. int k = entries[i].Key;
  1599. object result = null;
  1600. while(true)
  1601. {
  1602. if(k == key) { result = entries[i].Value; break; }
  1603. if(k == 0)
  1604. break;
  1605. i++;
  1606. if(i >= n)
  1607. i = 0;
  1608. k = entries[i].Key;
  1609. }
  1610. return result;
  1611. }
  1612. set
  1613. {
  1614. if(key <= 0)
  1615. throw new ArgumentException(ExceptionStrings.KeyNeedsToBeGreaterThanZero, "key");
  1616. HashEntry[] entries = this.entries;
  1617. int n = entries.Length;
  1618. int i = key & (n - 1);
  1619. int k = entries[i].Key;
  1620. while(true)
  1621. {
  1622. if(k == key || k == 0)
  1623. {
  1624. entries[i].Value = value;
  1625. if(k == 0)
  1626. {
  1627. if(value == null) { return; }
  1628. entries[i].Key = key;
  1629. if(++this.count > n / 2)
  1630. this.Expand();
  1631. return;
  1632. }
  1633. if(value == null)
  1634. entries[i].Key = -1;
  1635. return;
  1636. }
  1637. i++;
  1638. if(i >= n)
  1639. i = 0;
  1640. k = entries[i].Key;
  1641. }
  1642. }
  1643. }
  1644. public TrivialHashtable Clone()
  1645. {
  1646. HashEntry[] clonedEntries = (HashEntry[])this.entries.Clone();
  1647. //^ assume clonedEntries != null;
  1648. return new TrivialHashtable(clonedEntries, this.count);
  1649. }
  1650. }
  1651. public sealed class TrivialHashtableUsingWeakReferences
  1652. {
  1653. struct HashEntry
  1654. {
  1655. public int Key;
  1656. public WeakReference Value;
  1657. }
  1658. private HashEntry[]/*!*/ entries;
  1659. private int count;
  1660. public TrivialHashtableUsingWeakReferences()
  1661. {
  1662. this.entries = new HashEntry[16];
  1663. //this.count = 0;
  1664. }
  1665. private TrivialHashtableUsingWeakReferences(HashEntry[]/*!*/ entries, int count)
  1666. {
  1667. this.entries = entries;
  1668. this.count = count;
  1669. }
  1670. public TrivialHashtableUsingWeakReferences(int expectedEntries)
  1671. {
  1672. int initialSize = 16;
  1673. expectedEntries <<= 1;
  1674. while(initialSize < expectedEntries && initialSize > 0)
  1675. initialSize <<= 1;
  1676. if(initialSize < 0)
  1677. initialSize = 16;
  1678. this.entries = new HashEntry[initialSize];
  1679. //this.count = 0;
  1680. }
  1681. public int Count
  1682. {
  1683. get
  1684. {
  1685. return this.count;
  1686. }
  1687. }
  1688. private void Expand()
  1689. {
  1690. HashEntry[] oldEntries = this.entries;
  1691. int n = oldEntries.Length;
  1692. int m = n * 2;
  1693. if(m <= 0)
  1694. return;
  1695. HashEntry[] entries = new HashEntry[m];
  1696. int count = 0;
  1697. for(int i = 0; i < n; i++)
  1698. {
  1699. int key = oldEntries[i].Key;
  1700. if(key <= 0)
  1701. continue; //No entry (0) or deleted entry (-1)
  1702. WeakReference value = oldEntries[i].Value;
  1703. Debug.Assert(value != null);
  1704. if(value == null || !value.IsAlive)
  1705. continue; //Collected entry.
  1706. int j = key & (m - 1);
  1707. int k = entries[j].Key;
  1708. while(true)
  1709. {
  1710. if(k == 0)
  1711. {
  1712. entries[j].Value = value;
  1713. entries[j].Key = key;
  1714. count++;
  1715. break;
  1716. }
  1717. j++;
  1718. if(j >= m)
  1719. j = 0;
  1720. k = entries[j].Key;
  1721. }
  1722. }
  1723. this.entries = entries;
  1724. this.count = count;
  1725. }
  1726. private void Contract()
  1727. {
  1728. HashEntry[] oldEntries = this.entries;
  1729. int n = oldEntries.Length;
  1730. int m = n / 2;
  1731. if(m < 16)
  1732. return;
  1733. HashEntry[] entries = new HashEntry[m];
  1734. int count = 0;
  1735. for(int i = 0; i < n; i++)
  1736. {
  1737. int key = oldEntries[i].Key;
  1738. if(key <= 0)
  1739. continue; //No entry (0) or deleted entry (-1)
  1740. WeakReference value = oldEntries[i].Value;
  1741. Debug.Assert(value != null);
  1742. if(value == null || !value.IsAlive)
  1743. continue; //Collected entry.
  1744. int j = key & (m - 1);
  1745. int k = entries[j].Key;
  1746. while(true)
  1747. {
  1748. if(k == 0)
  1749. {
  1750. entries[j].Value = value;
  1751. entries[j].Key = key;
  1752. count++;
  1753. break;
  1754. }
  1755. j++;
  1756. if(j >= m)
  1757. j = 0;
  1758. k = entries[j].Key;
  1759. }
  1760. }
  1761. this.entries = entries;
  1762. this.count = count;
  1763. }
  1764. private void WeedOutCollectedEntries()
  1765. {
  1766. HashEntry[] oldEntries = this.entries;
  1767. int n = oldEntries.Length;
  1768. HashEntry[] entries = new HashEntry[n];
  1769. int count = 0;
  1770. for(int i = 0; i < n; i++)
  1771. {
  1772. int key = oldEntries[i].Key;
  1773. if(key <= 0)
  1774. continue; //No entry (0) or deleted entry (-1)
  1775. WeakReference value = oldEntries[i].Value;
  1776. Debug.Assert(value != null);
  1777. if(value == null || !value.IsAlive)
  1778. continue; //Collected entry.
  1779. int j = key & (n - 1);
  1780. int k = entries[j].Key;
  1781. while(true)
  1782. {
  1783. if(k == 0)
  1784. {
  1785. entries[j].Value = value;
  1786. entries[j].Key = key;
  1787. count++;
  1788. break;
  1789. }
  1790. j++;
  1791. if(j >= n)
  1792. j = 0;
  1793. k = entries[j].Key;
  1794. }
  1795. }
  1796. this.entries = entries;
  1797. this.count = count;
  1798. }
  1799. public object this[int key]
  1800. {
  1801. get
  1802. {
  1803. if(key <= 0)
  1804. throw new ArgumentException(ExceptionStrings.KeyNeedsToBeGreaterThanZero, "key");
  1805. HashEntry[] entries = this.entries;
  1806. int n = entries.Length;
  1807. int i = key & (n - 1);
  1808. int k = entries[i].Key;
  1809. object result = null;
  1810. while(true)
  1811. {
  1812. if(k == key)
  1813. {
  1814. WeakReference wref = entries[i].Value;
  1815. if(wref == null) { Debug.Assert(false); return null; }
  1816. result = wref.Target;
  1817. if(result != null)
  1818. return result;
  1819. this.WeedOutCollectedEntries();
  1820. while(this.count < n / 4 && n > 16) { this.Contract(); n = this.entries.Length; }
  1821. return null;
  1822. }
  1823. if(k == 0)
  1824. break;
  1825. i++;
  1826. if(i >= n)
  1827. i = 0;
  1828. k = entries[i].Key;
  1829. }
  1830. return result;
  1831. }
  1832. set
  1833. {
  1834. if(key <= 0)
  1835. throw new ArgumentException(ExceptionStrings.KeyNeedsToBeGreaterThanZero, "key");
  1836. HashEntry[] entries = this.entries;
  1837. int n = entries.Length;
  1838. int i = key & (n - 1);
  1839. int k = entries[i].Key;
  1840. while(true)
  1841. {
  1842. if(k == key || k == 0)
  1843. {
  1844. if(value == null)
  1845. entries[i].Value = null;
  1846. else
  1847. entries[i].Value = new WeakReference(value);
  1848. if(k == 0)
  1849. {
  1850. if(value == null)
  1851. return;
  1852. entries[i].Key = key;
  1853. if(++this.count > n / 2)
  1854. {
  1855. this.Expand(); //Could decrease this.count because of collected entries being deleted
  1856. while(this.count < n / 4 && n > 16) { this.Contract(); n = this.entries.Length; }
  1857. }
  1858. return;
  1859. }
  1860. if(value == null)
  1861. entries[i].Key = -1;
  1862. return;
  1863. }
  1864. i++;
  1865. if(i >= n)
  1866. i = 0;
  1867. k = entries[i].Key;
  1868. }
  1869. }
  1870. }
  1871. public TrivialHashtableUsingWeakReferences Clone()
  1872. {
  1873. HashEntry[] clonedEntries = (HashEntry[])this.entries.Clone();
  1874. //^ assume clonedEntries != null;
  1875. return new TrivialHashtableUsingWeakReferences(clonedEntries, this.count);
  1876. }
  1877. }
  1878. public interface IUniqueKey
  1879. {
  1880. int UniqueId { get; }
  1881. }
  1882. /// <summary>
  1883. /// A node in an Abstract Syntax Tree.
  1884. /// </summary>
  1885. public abstract class Node : IUniqueKey
  1886. {
  1887. public bool IsErroneous;
  1888. /// <summary>
  1889. /// The region in the source code that contains the concrete syntax corresponding to this node in the Abstract Syntax Tree.
  1890. /// </summary>
  1891. public SourceContext SourceContext;
  1892. #if DEBUG
  1893. public string DebugLabel; // useful for debugging.
  1894. #endif
  1895. protected Node(NodeType nodeType)
  1896. {
  1897. this.NodeType = nodeType;
  1898. }
  1899. private NodeType nodeType;
  1900. /// <summary>
  1901. /// A scalar tag that identifies the concrete type of the node. This is provided to allow efficient type membership tests that
  1902. /// facilitate tree traversal.
  1903. /// </summary>
  1904. public NodeType NodeType
  1905. {
  1906. get { return this.nodeType; }
  1907. set { this.nodeType = value; }
  1908. }
  1909. private static int uniqueKeyCounter;
  1910. private int uniqueKey;
  1911. /// <summary>
  1912. /// An integer that uniquely identifies this node. This provides an efficient equality test to facilitate hashing.
  1913. /// Do not override this.
  1914. /// </summary>
  1915. public virtual int UniqueKey
  1916. {
  1917. get
  1918. {
  1919. if(this.uniqueKey == 0)
  1920. {
  1921. TryAgain:
  1922. int c = Node.uniqueKeyCounter;
  1923. int cp1 = c + 17;
  1924. if(cp1 <= 0)
  1925. cp1 = 1000000;
  1926. if(System.Threading.Interlocked.CompareExchange(ref Node.uniqueKeyCounter, cp1, c) != c)
  1927. goto TryAgain;
  1928. this.uniqueKey = cp1;
  1929. }
  1930. return this.uniqueKey;
  1931. }
  1932. }
  1933. /// <summary>
  1934. /// Makes a shallow copy of the node.
  1935. /// </summary>
  1936. /// <returns>A shallow copy of the node</returns>
  1937. public virtual Node/*!*/ Clone()
  1938. {
  1939. Node result = (Node)this.MemberwiseClone();
  1940. result.uniqueKey = 0;
  1941. return result;
  1942. }
  1943. public virtual object GetVisitorFor(object/*!*/ callingVisitor, string/*!*/ visitorClassName)
  1944. {
  1945. if(callingVisitor == null || visitorClassName == null) { Debug.Fail(""); return null; }
  1946. return Node.GetVisitorFor(this.GetType(), callingVisitor, visitorClassName);
  1947. }
  1948. private static Hashtable VisitorTypeFor; //contains weak references
  1949. private static Object GetVisitorFor(System.Type/*!*/ nodeType, object/*!*/ callingVisitor, string/*!*/ visitorClassName)
  1950. {
  1951. if(nodeType == null || callingVisitor == null || visitorClassName == null) { Debug.Fail(""); return null; }
  1952. if(Node.VisitorTypeFor == null)
  1953. Node.VisitorTypeFor = new Hashtable();
  1954. string customVisitorClassName = visitorClassName;
  1955. if(visitorClassName.IndexOf('.') < 0)
  1956. customVisitorClassName = nodeType.Namespace + "." + visitorClassName;
  1957. if(customVisitorClassName == callingVisitor.GetType().FullName)
  1958. {
  1959. Debug.Assert(false); //This must be a bug, the calling visitor is the one that should handle the nodeType
  1960. return null;
  1961. }
  1962. System.Reflection.AssemblyName visitorAssemblyName = null;
  1963. System.Reflection.Assembly assembly = null;
  1964. WeakReference wref = (WeakReference)Node.VisitorTypeFor[customVisitorClassName];
  1965. Type visitorType = wref == null ? null : (System.Type)wref.Target;
  1966. if(visitorType == typeof(object))
  1967. return null;
  1968. string callerDirectory = null;
  1969. if(visitorType == null)
  1970. {
  1971. assembly = nodeType.Assembly;
  1972. if(assembly == null)
  1973. return null;
  1974. visitorType = assembly.GetType(customVisitorClassName, false);
  1975. }
  1976. if(visitorType == null)
  1977. {
  1978. //^ assert assembly != null;
  1979. if(assembly.Location == null)
  1980. return null;
  1981. callerDirectory = Path.GetDirectoryName(assembly.Location);
  1982. visitorAssemblyName = new System.Reflection.AssemblyName();
  1983. visitorAssemblyName.Name = "Visitors";
  1984. visitorAssemblyName.CodeBase = "file:///" + Path.Combine(callerDirectory, "Visitors.dll");
  1985. try
  1986. {
  1987. assembly = System.Reflection.Assembly.Load(visitorAssemblyName);
  1988. }
  1989. catch { }
  1990. if(assembly != null)
  1991. visitorType = assembly.GetType(customVisitorClassName, false);
  1992. if(visitorType == null)
  1993. {
  1994. visitorAssemblyName.Name = customVisitorClassName;
  1995. visitorAssemblyName.CodeBase = "file:///" + Path.Combine(callerDirectory, customVisitorClassName + ".dll");
  1996. try
  1997. {
  1998. assembly = System.Reflection.Assembly.Load(visitorAssemblyName);
  1999. }
  2000. catch { }
  2001. if(assembly != null)
  2002. visitorType = assembly.GetType(customVisitorClassName, false);
  2003. }
  2004. }
  2005. if(visitorType == null)
  2006. {
  2007. //Put fake entry into hash table to short circuit future lookups
  2008. visitorType = typeof(object);
  2009. assembly = nodeType.Assembly;
  2010. }
  2011. if(assembly != null)
  2012. { //Only happens if there was a cache miss
  2013. lock(Node.VisitorTypeFor)
  2014. {
  2015. Node.VisitorTypeFor[customVisitorClassName] = new WeakReference(visitorType);
  2016. }
  2017. }
  2018. if(visitorType == typeof(object))
  2019. return null;
  2020. try
  2021. {
  2022. return System.Activator.CreateInstance(visitorType, new object[] { callingVisitor });
  2023. }
  2024. catch { }
  2025. return null;
  2026. }
  2027. int IUniqueKey.UniqueId { get { return this.UniqueKey; } }
  2028. }
  2029. public abstract class ErrorNode : Node
  2030. {
  2031. public int Code;
  2032. public string[] MessageParameters;
  2033. protected ErrorNode(int code, params string[] messageParameters)
  2034. : base(NodeType.Undefined)
  2035. {
  2036. this.Code = code;
  2037. this.MessageParameters = messageParameters;
  2038. }
  2039. public virtual string GetErrorNumber()
  2040. {
  2041. return this.Code.ToString("0000");
  2042. }
  2043. public string GetMessage()
  2044. {
  2045. return this.GetMessage(null);
  2046. }
  2047. public abstract string GetMessage(System.Globalization.CultureInfo culture);
  2048. public virtual string GetMessage(string key, System.Resources.ResourceManager rm, System.Globalization.CultureInfo culture)
  2049. {
  2050. if(rm == null || key == null)
  2051. return null;
  2052. string localizedString = rm.GetString(key, culture);
  2053. if(localizedString == null)
  2054. localizedString = key;
  2055. string[] messageParameters = this.MessageParameters;
  2056. if(messageParameters == null || messageParameters.Length == 0)
  2057. return localizedString;
  2058. return string.Format(localizedString, messageParameters);
  2059. }
  2060. public abstract int Severity
  2061. {
  2062. get;
  2063. }
  2064. public static int GetCountAtSeverity(ErrorNodeList errors, int minSeverity, int maxSeverity)
  2065. {
  2066. if(errors == null)
  2067. return 0;
  2068. int n = 0;
  2069. for(int i = 0; i < errors.Count; i++)
  2070. {
  2071. ErrorNode e = errors[i];
  2072. if(e == null)
  2073. continue;
  2074. int s = e.Severity;
  2075. if(minSeverity <= s && s <= maxSeverity)
  2076. n++;
  2077. }
  2078. return n;
  2079. }
  2080. }
  2081. public class Expose : Statement
  2082. {
  2083. public Expression Instance;
  2084. public Block Body;
  2085. public bool IsLocal;
  2086. public Expose(NodeType nodeType)
  2087. : base(nodeType)
  2088. {
  2089. }
  2090. }
  2091. public class Acquire : Statement
  2092. {
  2093. public bool ReadOnly;
  2094. public Statement Target;
  2095. public Expression Condition;
  2096. public Expression ConditionFunction;
  2097. public Block Body;
  2098. public BlockScope ScopeForTemporaryVariable;
  2099. public Acquire()
  2100. : base(NodeType.Acquire)
  2101. {
  2102. }
  2103. }
  2104. public class Expression : Node
  2105. {
  2106. private TypeNode type;
  2107. public Expression(NodeType nodeType)
  2108. : base(nodeType)
  2109. {
  2110. }
  2111. public Expression(NodeType nodeType, TypeNode type)
  2112. : base(nodeType)
  2113. {
  2114. this.type = type;
  2115. }
  2116. public virtual TypeNode Type
  2117. {
  2118. get { return this.type; }
  2119. set { this.type = value; }
  2120. }
  2121. }
  2122. public class ExpressionSnippet : Expression
  2123. {
  2124. public IParserFactory ParserFactory;
  2125. public ExpressionSnippet()
  2126. : base(NodeType.ExpressionSnippet)
  2127. {
  2128. }
  2129. public ExpressionSnippet(IParserFactory parserFactory, SourceContext sctx)
  2130. : base(NodeType.ExpressionSnippet)
  2131. {
  2132. this.ParserFactory = parserFactory;
  2133. this.SourceContext = sctx;
  2134. }
  2135. }
  2136. public class MemberBinding : Expression
  2137. {
  2138. private int alignment;
  2139. private Member boundMember;
  2140. public Expression BoundMemberExpression;
  2141. private Expression targetObject;
  2142. private bool @volatile;
  2143. public MemberBinding()
  2144. : base(NodeType.MemberBinding)
  2145. {
  2146. }
  2147. public MemberBinding(Expression targetObject, Member/*!*/ boundMember)
  2148. : this(targetObject, boundMember, false, -1)
  2149. {
  2150. if(boundMember is Field)
  2151. this.Volatile = ((Field)boundMember).IsVolatile;
  2152. }
  2153. public MemberBinding(Expression targetObject, Member/*!*/ boundMember, Expression boundMemberExpression)
  2154. : this(targetObject, boundMember, false, -1)
  2155. {
  2156. if(boundMember is Field)
  2157. this.Volatile = ((Field)boundMember).IsVolatile;
  2158. this.BoundMemberExpression = boundMemberExpression;
  2159. }
  2160. public MemberBinding(Expression targetObject, Member/*!*/ boundMember, SourceContext sctx)
  2161. : this(targetObject, boundMember, false, -1)
  2162. {
  2163. if(boundMember is Field)
  2164. this.Volatile = ((Field)boundMember).IsVolatile;
  2165. this.SourceContext = sctx;
  2166. }
  2167. public MemberBinding(Expression targetObject, Member/*!*/ boundMember, SourceContext sctx, Expression boundMemberExpression)
  2168. : this(targetObject, boundMember, false, -1)
  2169. {
  2170. if(boundMember is Field)
  2171. this.Volatile = ((Field)boundMember).IsVolatile;
  2172. this.SourceContext = sctx;
  2173. this.BoundMemberExpression = boundMemberExpression;
  2174. }
  2175. public MemberBinding(Expression targetObject, Member/*!*/ boundMember, bool @volatile, int alignment)
  2176. : base(NodeType.MemberBinding)
  2177. {
  2178. Debug.Assert(boundMember != null);
  2179. this.alignment = alignment;
  2180. this.boundMember = boundMember;
  2181. this.targetObject = targetObject;
  2182. this.@volatile = @volatile;
  2183. switch(boundMember.NodeType)
  2184. {
  2185. case NodeType.Field:
  2186. this.Type = ((Field)boundMember).Type;
  2187. break;
  2188. case NodeType.Method:
  2189. this.Type = ((Method)boundMember).ReturnType;
  2190. break;
  2191. case NodeType.Event:
  2192. this.Type = ((Event)boundMember).HandlerType;
  2193. break;
  2194. default:
  2195. this.Type = boundMember as TypeNode;
  2196. break;
  2197. }
  2198. }
  2199. public int Alignment
  2200. {
  2201. get { return this.alignment; }
  2202. set { this.alignment = value; }
  2203. }
  2204. public Member BoundMember
  2205. {
  2206. get { return this.boundMember; }
  2207. set { this.boundMember = value; }
  2208. }
  2209. public Expression TargetObject
  2210. {
  2211. get { return this.targetObject; }
  2212. set { this.targetObject = value; }
  2213. }
  2214. public bool Volatile
  2215. {
  2216. get { return this.@volatile; }
  2217. set { this.@volatile = value; }
  2218. }
  2219. }
  2220. public class AddressDereference : Expression
  2221. {
  2222. private Expression address;
  2223. private int alignment;
  2224. private bool isVolatile;
  2225. public enum ExplicitOp { None = 0, Star, Arrow }
  2226. private ExplicitOp explicitOperation; // was explicit in source (* or ->)
  2227. public AddressDereference()
  2228. : base(NodeType.AddressDereference)
  2229. {
  2230. }
  2231. public AddressDereference(Expression address, TypeNode type)
  2232. : this(address, type, false, -1)
  2233. {
  2234. }
  2235. public AddressDereference(Expression address, TypeNode type, SourceContext sctx)
  2236. : this(address, type, false, -1, sctx)
  2237. {
  2238. }
  2239. public AddressDereference(Expression address, TypeNode type, bool isVolatile, int alignment)
  2240. : base(NodeType.AddressDereference)
  2241. {
  2242. this.address = address;
  2243. this.alignment = alignment;
  2244. this.Type = type;
  2245. this.isVolatile = isVolatile;
  2246. }
  2247. public AddressDereference(Expression address, TypeNode type, bool Volatile, int alignment, SourceContext sctx)
  2248. : base(NodeType.AddressDereference)
  2249. {
  2250. this.address = address;
  2251. this.alignment = alignment;
  2252. this.Type = type;
  2253. this.isVolatile = Volatile;
  2254. this.SourceContext = sctx;
  2255. }
  2256. public Expression Address
  2257. {
  2258. get { return this.address; }
  2259. set { this.address = value; }
  2260. }
  2261. public int Alignment
  2262. {
  2263. get { return this.alignment; }
  2264. set { this.alignment = value; }
  2265. }
  2266. public bool Volatile
  2267. {
  2268. get { return this.isVolatile; }
  2269. set { this.isVolatile = value; }
  2270. }
  2271. public bool Explicit
  2272. {
  2273. get { return this.explicitOperation != ExplicitOp.None; }
  2274. }
  2275. public ExplicitOp ExplicitOperator
  2276. {
  2277. get { return this.explicitOperation; }
  2278. set { this.explicitOperation = value; }
  2279. }
  2280. }
  2281. public class UnaryExpression : Expression
  2282. {
  2283. private Expression operand;
  2284. public UnaryExpression()
  2285. : base(NodeType.Nop)
  2286. {
  2287. }
  2288. public UnaryExpression(Expression operand, NodeType nodeType)
  2289. : base(nodeType)
  2290. {
  2291. this.Operand = operand;
  2292. }
  2293. public UnaryExpression(Expression operand, NodeType nodeType, SourceContext sctx)
  2294. : base(nodeType)
  2295. {
  2296. this.operand = operand;
  2297. this.SourceContext = sctx;
  2298. }
  2299. public UnaryExpression(Expression operand, NodeType nodeType, TypeNode type)
  2300. : base(nodeType)
  2301. {
  2302. this.operand = operand;
  2303. this.Type = type;
  2304. }
  2305. public UnaryExpression(Expression operand, NodeType nodeType, TypeNode type, SourceContext sctx)
  2306. : base(nodeType)
  2307. {
  2308. this.operand = operand;
  2309. this.Type = type;
  2310. this.SourceContext = sctx;
  2311. }
  2312. public Expression Operand
  2313. {
  2314. get { return this.operand; }
  2315. set { this.operand = value; }
  2316. }
  2317. }
  2318. public class PrefixExpression : Expression
  2319. {
  2320. public Expression Expression;
  2321. public NodeType Operator;
  2322. public Method OperatorOverload;
  2323. public PrefixExpression()
  2324. : base(NodeType.PrefixExpression)
  2325. {
  2326. }
  2327. public PrefixExpression(Expression expression, NodeType Operator, SourceContext sourceContext)
  2328. : base(NodeType.PrefixExpression)
  2329. {
  2330. this.Expression = expression;
  2331. this.Operator = Operator;
  2332. this.SourceContext = sourceContext;
  2333. }
  2334. }
  2335. public class PostfixExpression : Expression
  2336. {
  2337. public Expression Expression;
  2338. public NodeType Operator;
  2339. public Method OperatorOverload;
  2340. public PostfixExpression()
  2341. : base(NodeType.PostfixExpression)
  2342. {
  2343. }
  2344. public PostfixExpression(Expression expression, NodeType Operator, SourceContext sourceContext)
  2345. : base(NodeType.PostfixExpression)
  2346. {
  2347. this.Expression = expression;
  2348. this.Operator = Operator;
  2349. this.SourceContext = sourceContext;
  2350. }
  2351. }
  2352. public class BinaryExpression : Expression
  2353. {
  2354. private Expression operand1;
  2355. private Expression operand2;
  2356. public BinaryExpression()
  2357. : base(NodeType.Nop)
  2358. {
  2359. }
  2360. public BinaryExpression(Expression operand1, Expression operand2, NodeType nodeType)
  2361. : base(nodeType)
  2362. {
  2363. this.operand1 = operand1;
  2364. this.operand2 = operand2;
  2365. }
  2366. public BinaryExpression(Expression operand1, Expression operand2, NodeType nodeType, TypeNode resultType)
  2367. : base(nodeType)
  2368. {
  2369. this.operand1 = operand1;
  2370. this.operand2 = operand2;
  2371. this.Type = resultType;
  2372. }
  2373. public BinaryExpression(Expression operand1, Expression operand2, NodeType nodeType, SourceContext ctx)
  2374. : base(nodeType)
  2375. {
  2376. this.operand1 = operand1;
  2377. this.operand2 = operand2;
  2378. this.SourceContext = ctx;
  2379. }
  2380. public BinaryExpression(Expression operand1, Expression operand2, NodeType nodeType, TypeNode resultType, SourceContext ctx)
  2381. : base(nodeType)
  2382. {
  2383. this.operand1 = operand1;
  2384. this.operand2 = operand2;
  2385. this.Type = resultType;
  2386. this.SourceContext = ctx;
  2387. }
  2388. public Expression Operand1
  2389. {
  2390. get { return this.operand1; }
  2391. set { this.operand1 = value; }
  2392. }
  2393. public Expression Operand2
  2394. {
  2395. get { return this.operand2; }
  2396. set { this.operand2 = value; }
  2397. }
  2398. }
  2399. public class TernaryExpression : Expression
  2400. {
  2401. private Expression operand1;
  2402. private Expression operand2;
  2403. private Expression operand3;
  2404. public TernaryExpression()
  2405. : base(NodeType.Nop)
  2406. {
  2407. }
  2408. public TernaryExpression(Expression operand1, Expression operand2, Expression operand3, NodeType nodeType, TypeNode resultType)
  2409. : base(nodeType)
  2410. {
  2411. this.operand1 = operand1;
  2412. this.operand2 = operand2;
  2413. this.operand3 = operand3;
  2414. this.Type = resultType;
  2415. }
  2416. public Expression Operand1
  2417. {
  2418. get { return this.operand1; }
  2419. set { this.operand1 = value; }
  2420. }
  2421. public Expression Operand2
  2422. {
  2423. get { return this.operand2; }
  2424. set { this.operand2 = value; }
  2425. }
  2426. public Expression Operand3
  2427. {
  2428. get { return this.operand3; }
  2429. set { this.operand3 = value; }
  2430. }
  2431. }
  2432. public abstract class NaryExpression : Expression
  2433. {
  2434. public ExpressionList Operands;
  2435. protected NaryExpression()
  2436. : base(NodeType.Nop)
  2437. {
  2438. }
  2439. protected NaryExpression(ExpressionList operands, NodeType nodeType)
  2440. : base(nodeType)
  2441. {
  2442. this.Operands = operands;
  2443. }
  2444. }
  2445. public class ApplyToAll : BinaryExpression
  2446. {
  2447. public Local ElementLocal;
  2448. public Method ResultIterator;
  2449. public ApplyToAll()
  2450. : base(null, null, NodeType.ApplyToAll)
  2451. {
  2452. }
  2453. public ApplyToAll(Expression operand1, Expression operand2)
  2454. : base(operand1, operand2, NodeType.ApplyToAll)
  2455. {
  2456. }
  2457. public ApplyToAll(Expression operand1, Expression operand2, SourceContext ctx)
  2458. : base(operand1, operand2, NodeType.ApplyToAll)
  2459. {
  2460. this.SourceContext = ctx;
  2461. }
  2462. }
  2463. public class NamedArgument : Expression
  2464. {
  2465. private bool isCustomAttributeProperty;
  2466. private Identifier name;
  2467. private Expression value;
  2468. private bool valueIsBoxed;
  2469. public NamedArgument()
  2470. : base(NodeType.NamedArgument)
  2471. {
  2472. }
  2473. public NamedArgument(Identifier name, Expression value)
  2474. : base(NodeType.NamedArgument)
  2475. {
  2476. this.Name = name;
  2477. this.Value = value;
  2478. }
  2479. public NamedArgument(Identifier name, Expression value, SourceContext ctx)
  2480. : base(NodeType.NamedArgument)
  2481. {
  2482. this.Name = name;
  2483. this.Value = value;
  2484. this.SourceContext = ctx;
  2485. }
  2486. public bool IsCustomAttributeProperty
  2487. { //TODO: rename this to IsProperty
  2488. get { return this.isCustomAttributeProperty; }
  2489. set { this.isCustomAttributeProperty = value; }
  2490. }
  2491. public Identifier Name
  2492. {
  2493. get { return this.name; }
  2494. set { this.name = value; }
  2495. }
  2496. public Expression Value
  2497. {
  2498. get { return this.value; }
  2499. set { this.value = value; }
  2500. }
  2501. public bool ValueIsBoxed
  2502. {
  2503. get { return this.valueIsBoxed; }
  2504. set { this.valueIsBoxed = value; }
  2505. }
  2506. }
  2507. /// <summary>
  2508. /// This an Expression wrapper for compile time constants. It is assumed to be correct by construction.
  2509. /// In Normalized IR, the wrapped value must be a primitive numeric type or an enum or a string or null.
  2510. /// If used in custom attributes, types are also allowed as well as single dimensional arrays of other allowed types.
  2511. /// If the wrapped value is null, any reference type is allowed, except in custom attributes, where it must be Type or String.
  2512. /// </summary>
  2513. public class Literal : Expression
  2514. {
  2515. private object value;
  2516. public bool TypeWasExplicitlySpecifiedInSource;
  2517. public Expression SourceExpression;
  2518. public Literal()
  2519. : base(NodeType.Literal)
  2520. {
  2521. }
  2522. public Literal(object Value)
  2523. : base(NodeType.Literal)
  2524. {
  2525. this.value = Value;
  2526. }
  2527. public Literal(object value, TypeNode type)
  2528. : base(NodeType.Literal)
  2529. {
  2530. this.value = value;
  2531. this.Type = type;
  2532. }
  2533. public Literal(object value, TypeNode type, SourceContext sourceContext)
  2534. : base(NodeType.Literal)
  2535. {
  2536. this.value = value;
  2537. this.SourceContext = sourceContext;
  2538. this.Type = type;
  2539. }
  2540. /// <summary>
  2541. /// Holds the wrapped compile time constant value.
  2542. /// </summary>
  2543. public object Value
  2544. {
  2545. get { return this.value; }
  2546. }
  2547. public override string ToString()
  2548. {
  2549. if(this.Value == null)
  2550. return "Literal for null";
  2551. return this.Value.ToString();
  2552. }
  2553. }
  2554. public class This : Parameter
  2555. {
  2556. public This()
  2557. {
  2558. this.NodeType = NodeType.This;
  2559. this.Name = StandardIds.This;
  2560. }
  2561. public This(TypeNode type)
  2562. {
  2563. this.NodeType = NodeType.This;
  2564. this.Name = StandardIds.This;
  2565. this.Type = type;
  2566. }
  2567. public bool IsCtorCall = false;
  2568. public This(SourceContext sctx, bool isCtorCall)
  2569. {
  2570. this.NodeType = NodeType.This;
  2571. this.Name = StandardIds.This;
  2572. this.SourceContext = sctx;
  2573. this.IsCtorCall = isCtorCall;
  2574. }
  2575. public This(TypeNode type, SourceContext sctx)
  2576. {
  2577. this.NodeType = NodeType.This;
  2578. this.Name = StandardIds.This;
  2579. this.Type = type;
  2580. this.SourceContext = sctx;
  2581. }
  2582. public override bool Equals(object obj)
  2583. {
  2584. ThisBinding binding = obj as ThisBinding;
  2585. return obj == this || binding != null && binding.BoundThis == this;
  2586. }
  2587. public override int GetHashCode()
  2588. {
  2589. return base.GetHashCode();
  2590. }
  2591. }
  2592. public class ThisBinding : This, IUniqueKey
  2593. {
  2594. public This/*!*/ BoundThis;
  2595. public ThisBinding(This/*!*/ boundThis, SourceContext sctx)
  2596. {
  2597. if(boundThis == null)
  2598. throw new ArgumentNullException("boundThis");
  2599. this.BoundThis = boundThis;
  2600. this.SourceContext = sctx;
  2601. this.Type = boundThis.Type;
  2602. this.Name = boundThis.Name;
  2603. this.TypeExpression = boundThis.TypeExpression;
  2604. this.Attributes = boundThis.Attributes;
  2605. this.DefaultValue = boundThis.DefaultValue;
  2606. this.Flags = boundThis.Flags;
  2607. this.MarshallingInformation = boundThis.MarshallingInformation;
  2608. this.DeclaringMethod = boundThis.DeclaringMethod;
  2609. this.ParameterListIndex = boundThis.ParameterListIndex;
  2610. this.ArgumentListIndex = boundThis.ArgumentListIndex;
  2611. //^ base();
  2612. }
  2613. public override int GetHashCode()
  2614. {
  2615. return this.BoundThis.GetHashCode();
  2616. }
  2617. public override bool Equals(object obj)
  2618. {
  2619. ThisBinding pb = obj as ThisBinding;
  2620. if(pb != null)
  2621. return this.BoundThis.Equals(pb.BoundThis);
  2622. else
  2623. return this.BoundThis.Equals(obj);
  2624. }
  2625. int IUniqueKey.UniqueId
  2626. {
  2627. get { return this.BoundThis.UniqueKey; }
  2628. }
  2629. /// <summary>
  2630. /// Must forward type to underlying binding, since ThisBindings get built at times when
  2631. /// the bound This node does not have its final type yet.
  2632. /// </summary>
  2633. public override TypeNode Type
  2634. {
  2635. get
  2636. {
  2637. return BoundThis.Type;
  2638. }
  2639. set
  2640. {
  2641. BoundThis.Type = value;
  2642. }
  2643. }
  2644. }
  2645. public class Base : Expression
  2646. {
  2647. /// <summary>
  2648. /// When the source uses the C# compatibility mode, base calls cannot be put after non-null
  2649. /// field initialization, but must be put before the body. But the user can specify where
  2650. /// the base ctor call should be performed by using "base;" as a marker. During parsing
  2651. /// this flag is set so the right code transformations can be performed at code generation.
  2652. /// </summary>
  2653. public bool UsedAsMarker;
  2654. public bool IsCtorCall = false;
  2655. public Base()
  2656. : base(NodeType.Base)
  2657. {
  2658. }
  2659. public Base(SourceContext sctx, bool isCtorCall)
  2660. : base(NodeType.Base)
  2661. {
  2662. this.SourceContext = sctx;
  2663. this.IsCtorCall = isCtorCall;
  2664. }
  2665. }
  2666. public class ImplicitThis : Expression
  2667. {
  2668. public int LexLevel;
  2669. public Class MostNestedScope;
  2670. public ImplicitThis()
  2671. : base(NodeType.ImplicitThis)
  2672. {
  2673. }
  2674. public ImplicitThis(Class mostNestedScope, int lexLevel)
  2675. : base(NodeType.ImplicitThis)
  2676. {
  2677. this.LexLevel = lexLevel;
  2678. this.MostNestedScope = mostNestedScope;
  2679. }
  2680. }
  2681. public class CurrentClosure : Expression
  2682. {
  2683. public Method Method;
  2684. public CurrentClosure()
  2685. : base(NodeType.CurrentClosure)
  2686. {
  2687. }
  2688. public CurrentClosure(Method method, TypeNode type)
  2689. : base(NodeType.CurrentClosure)
  2690. {
  2691. this.Method = method;
  2692. this.Type = type;
  2693. }
  2694. public CurrentClosure(Method method, TypeNode type, SourceContext sctx)
  2695. : base(NodeType.CurrentClosure)
  2696. {
  2697. this.Method = method;
  2698. this.Type = type;
  2699. this.SourceContext = sctx;
  2700. }
  2701. }
  2702. public class SetterValue : Expression
  2703. {
  2704. public SetterValue()
  2705. : base(NodeType.SetterValue)
  2706. {
  2707. }
  2708. }
  2709. public class Identifier : Expression
  2710. {
  2711. private int hashCode;
  2712. internal int length;
  2713. private string name;
  2714. private int offset;
  2715. private DocumentText text;
  2716. public Identifier Prefix;
  2717. /// <summary>An identifier with the empty string ("") as its value.</summary>
  2718. public static readonly Identifier/*!*/ Empty = new Identifier("");
  2719. private Identifier(DocumentText/*!*/ text, int offset, int length)
  2720. : base(NodeType.Identifier)
  2721. {
  2722. this.text = text;
  2723. this.offset = offset;
  2724. this.length = length;
  2725. ulong hcode = 0;
  2726. for(int i = offset, n = length + i; i < n; i++)
  2727. {
  2728. char ch = text[i];
  2729. hcode = hcode * 17 + ch;
  2730. }
  2731. this.hashCode = ((int)hcode) & int.MaxValue;
  2732. }
  2733. public static Identifier/*!*/ For(SourceContext sctx)
  2734. {
  2735. DocumentText text = null;
  2736. if(sctx.Document != null)
  2737. text = sctx.Document.Text;
  2738. if(text == null)
  2739. text = new DocumentText("");
  2740. Identifier id = new Identifier(text, sctx.StartPos, sctx.EndPos - sctx.StartPos);
  2741. id.SourceContext = sctx;
  2742. return id;
  2743. }
  2744. public Identifier(string name)
  2745. : base(NodeType.Identifier)
  2746. {
  2747. if(name == null)
  2748. name = "";
  2749. this.name = name;
  2750. int n = this.length = name.Length;
  2751. ulong hcode = 0;
  2752. for(int i = 0; i < n; i++)
  2753. {
  2754. char ch = name[i];
  2755. hcode = hcode * 17 + ch;
  2756. }
  2757. this.hashCode = ((int)hcode) & int.MaxValue;
  2758. }
  2759. public Identifier(string name, SourceContext sctx)
  2760. : this(name)
  2761. {
  2762. this.SourceContext = sctx;
  2763. }
  2764. public static Identifier/*!*/ For(string/*!*/ name)
  2765. {
  2766. return new Identifier(name);
  2767. }
  2768. private unsafe Identifier(byte* pointer, int offset)
  2769. : base(NodeType.Identifier)
  2770. {
  2771. this.offset = offset;
  2772. bool isASCII = true;
  2773. int length = 0;
  2774. ulong hcode = 0;
  2775. for(int i = offset; ; i++)
  2776. {
  2777. byte b = *(pointer + i);
  2778. if(b == 0)
  2779. break;
  2780. if((b & 0x80) != 0)
  2781. isASCII = false;
  2782. hcode = hcode * 17 + b;
  2783. length++;
  2784. }
  2785. if(isASCII)
  2786. {
  2787. this.hashCode = ((int)hcode) & int.MaxValue;
  2788. this.length = length;
  2789. this.name = new string((sbyte*)pointer, offset, length, Encoding.ASCII);
  2790. return;
  2791. }
  2792. hcode = 0;
  2793. string name = this.name = new string((sbyte*)pointer, offset, length, Encoding.UTF8);
  2794. for(int i = 0, n = this.length = name.Length; i < n; i++)
  2795. {
  2796. char ch = name[i];
  2797. hcode = hcode * 17 + ch;
  2798. }
  2799. this.hashCode = ((int)hcode) & int.MaxValue;
  2800. }
  2801. /// <summary>
  2802. /// Use when pointer+offset points to a null terminated string of UTF8 code points.
  2803. /// </summary>
  2804. internal unsafe static Identifier/*!*/ For(byte* pointer, int offset)
  2805. {
  2806. //TODO: first look for identifier in cache
  2807. return new Identifier(pointer, offset);
  2808. }
  2809. private unsafe Identifier(byte* pointer, uint length)
  2810. : base(NodeType.Identifier)
  2811. {
  2812. //this.offset = 0;
  2813. this.length = (int)length;
  2814. ulong hcode = 0;
  2815. for(uint i = 0; i < length; i++)
  2816. {
  2817. byte b = *(pointer + i);
  2818. if((b & 0x80) != 0)
  2819. goto doUTF8decoding;
  2820. hcode = hcode * 17 + b;
  2821. }
  2822. this.hashCode = ((int)hcode) & int.MaxValue;
  2823. this.name = new string((sbyte*)pointer, 0, this.length, Encoding.ASCII);
  2824. return;
  2825. doUTF8decoding:
  2826. string name = this.name = new string((sbyte*)pointer, 0, this.length, Encoding.UTF8);
  2827. for(int i = 0, n = this.length = name.Length; i < n; i++)
  2828. {
  2829. char ch = name[i];
  2830. hcode = hcode * 17 + ch;
  2831. }
  2832. this.hashCode = ((int)hcode) & int.MaxValue;
  2833. }
  2834. /// <summary>
  2835. /// Use when pointer points to a string of UTF8 code points of a given length
  2836. /// </summary>
  2837. internal unsafe static Identifier/*!*/ For(byte* pointer, uint length)
  2838. {
  2839. //TODO: first look for identifier in cache
  2840. return new Identifier(pointer, length);
  2841. }
  2842. private static readonly object/*!*/ Lock = new object();
  2843. private struct CanonicalIdentifier
  2844. {
  2845. internal string/*!*/ Name;
  2846. internal int UniqueIdKey;
  2847. internal int HashCode;
  2848. internal CanonicalIdentifier(string/*!*/ name, int uniqueIdKey, int hashCode)
  2849. {
  2850. this.Name = name;
  2851. this.UniqueIdKey = uniqueIdKey;
  2852. this.HashCode = hashCode;
  2853. }
  2854. }
  2855. private static CanonicalIdentifier[]/*!*/ HashTable = new CanonicalIdentifier[16 * 1024];
  2856. private static int count;
  2857. private int GetUniqueIdKey()
  2858. {
  2859. lock(Identifier.Lock)
  2860. {
  2861. int hcode = this.hashCode;
  2862. CanonicalIdentifier[] hTable = Identifier.HashTable;
  2863. int length = hTable.Length;
  2864. int i = hcode % length;
  2865. CanonicalIdentifier id = hTable[i];
  2866. while(id.Name != null)
  2867. {
  2868. if(this.HasSameNameAs(id))
  2869. return id.UniqueIdKey;
  2870. i = (i + 1) % length;
  2871. id = hTable[i];
  2872. }
  2873. int count = Identifier.count;
  2874. int countp1 = count + 1;
  2875. Identifier.count = countp1;
  2876. string name = this.Name; //Get a local copy of the name and drop any reference to a DocumentText instance
  2877. hTable[i] = new CanonicalIdentifier(name, countp1, hcode);
  2878. if(countp1 > length / 2)
  2879. Rehash(); //Threshold exceeded, need to rehash
  2880. return countp1;
  2881. }
  2882. }
  2883. private unsafe bool HasSameNameAs(CanonicalIdentifier id)
  2884. {
  2885. int myLength = this.length;
  2886. int idLength = id.Name.Length;
  2887. if(myLength != idLength)
  2888. return false;
  2889. string myName = this.name;
  2890. string idName = id.Name;
  2891. if(myName == null)
  2892. {
  2893. int myOffset = this.offset;
  2894. if(this.text != null && this.text.Equals(idName, myOffset, myLength))
  2895. {
  2896. this.name = idName;
  2897. this.text = null;
  2898. return true;
  2899. }
  2900. return false;
  2901. }
  2902. return myName == idName;
  2903. }
  2904. public string/*!*/ Name
  2905. { //TODO: need a better name for this property
  2906. get
  2907. {
  2908. if(this.name != null)
  2909. return this.name;
  2910. lock(this)
  2911. {
  2912. if(this.name != null)
  2913. return this.name;
  2914. //^ assume this.text != null;
  2915. int length = this.length;
  2916. int offset = this.offset;
  2917. this.name = this.text.Substring(offset, length);
  2918. this.text = null;
  2919. return this.name;
  2920. }
  2921. }
  2922. }
  2923. private static void Rehash()
  2924. {
  2925. CanonicalIdentifier[] hTable = Identifier.HashTable;
  2926. int n = hTable.Length;
  2927. int n2 = n * 2;
  2928. CanonicalIdentifier[] newhTable = new CanonicalIdentifier[n2];
  2929. for(int i = 0; i < n; i++)
  2930. {
  2931. CanonicalIdentifier id = hTable[i];
  2932. if(id.Name == null)
  2933. continue;
  2934. int j = id.HashCode % n2;
  2935. CanonicalIdentifier id2 = newhTable[j];
  2936. while(id2.Name != null)
  2937. {
  2938. j = (j + 1) % n2;
  2939. id2 = newhTable[j];
  2940. }
  2941. newhTable[j] = id;
  2942. }
  2943. Identifier.HashTable = newhTable;
  2944. }
  2945. public override string/*!*/ ToString()
  2946. {
  2947. if(this.Prefix != null)
  2948. return this.Prefix.Name + ":" + this.Name;
  2949. if(this.Name == null)
  2950. return "";
  2951. return this.Name;
  2952. }
  2953. private int uniqueIdKey;
  2954. /// <summary>
  2955. /// Returns an integer that is the same for every Identifier instance that has the same string value, and that is different from
  2956. /// every other identifier instance that has a different string value. Useful for efficient equality tests when hashing identifiers.
  2957. /// </summary>
  2958. public int UniqueIdKey
  2959. {
  2960. get
  2961. {
  2962. int result = this.uniqueIdKey;
  2963. if(result != 0)
  2964. return result;
  2965. return this.uniqueIdKey = this.GetUniqueIdKey();
  2966. }
  2967. }
  2968. [Obsolete("Use Identifier.UniqueIdKey instead")]
  2969. public new int UniqueKey
  2970. {
  2971. get
  2972. {
  2973. int result = this.uniqueIdKey;
  2974. if(result != 0)
  2975. return result;
  2976. return this.uniqueIdKey = this.GetUniqueIdKey();
  2977. }
  2978. }
  2979. }
  2980. public class QualifiedIdentifier : Expression
  2981. {
  2982. public Identifier Identifier;
  2983. public Expression Qualifier;
  2984. public Expression BoundMember;
  2985. public bool QualifierIsNamespace;
  2986. public QualifiedIdentifier()
  2987. : base(NodeType.QualifiedIdentifer)
  2988. {
  2989. }
  2990. public QualifiedIdentifier(Expression qualifier, Identifier identifier)
  2991. : base(NodeType.QualifiedIdentifer)
  2992. {
  2993. this.Identifier = identifier;
  2994. this.Qualifier = qualifier;
  2995. }
  2996. public QualifiedIdentifier(Expression qualifier, Identifier identifier, SourceContext sourceContext)
  2997. : base(NodeType.QualifiedIdentifer)
  2998. {
  2999. this.Identifier = identifier;
  3000. this.Qualifier = qualifier;
  3001. this.SourceContext = sourceContext;
  3002. }
  3003. public QualifiedIdentifier(Expression qualifier, Identifier identifier, SourceContext sourceContext, bool qualifierIsNamespace)
  3004. : base(NodeType.QualifiedIdentifer)
  3005. {
  3006. this.Identifier = identifier;
  3007. this.Qualifier = qualifier;
  3008. this.SourceContext = sourceContext;
  3009. this.QualifierIsNamespace = qualifierIsNamespace;
  3010. }
  3011. public override string/*!*/ ToString()
  3012. {
  3013. string str = this.Identifier == null ? "" : this.Identifier.ToString();
  3014. if(this.Qualifier == null)
  3015. return str;
  3016. string separator = this.QualifierIsNamespace ? "::" : "+";
  3017. return this.Qualifier.ToString() + separator + str;
  3018. }
  3019. }
  3020. public class Quantifier : Expression
  3021. {
  3022. public NodeType QuantifierType;
  3023. public TypeNode SourceType; // the type of elements the quantifier consumes
  3024. public Comprehension Comprehension;
  3025. public Quantifier()
  3026. : base(NodeType.Quantifier)
  3027. {
  3028. }
  3029. public Quantifier(Comprehension comprehension)
  3030. : base(NodeType.Quantifier)
  3031. {
  3032. this.Comprehension = comprehension;
  3033. }
  3034. public Quantifier(NodeType t, Comprehension comprehension)
  3035. : base(NodeType.Quantifier)
  3036. {
  3037. this.QuantifierType = t;
  3038. this.Comprehension = comprehension;
  3039. }
  3040. }
  3041. public enum ComprehensionBindingMode { In, Gets };
  3042. public class ComprehensionBinding : Expression
  3043. {
  3044. public ComprehensionBindingMode Mode = ComprehensionBindingMode.In;
  3045. public TypeNode TargetVariableType;
  3046. public TypeNode TargetVariableTypeExpression;
  3047. public Expression TargetVariable;
  3048. public TypeNode AsTargetVariableType;
  3049. public TypeNode AsTargetVariableTypeExpression;
  3050. public Expression SourceEnumerable;
  3051. public BlockScope ScopeForTemporaryVariables;
  3052. public ComprehensionBinding()
  3053. : base(NodeType.ComprehensionBinding)
  3054. {
  3055. }
  3056. }
  3057. public enum ComprehensionMode { Reduction, Comprehension };
  3058. // {1,2,3} ==> Comprehension with BindingsAndFilters = null and Elements = [1,2,3]
  3059. // i.e., for a "display", there are no bindings and the elements have one entry per value in the comprehension
  3060. // { int x in A, P(x); T(x); default } ==> Comprehension with BindingsAndFilters = [int x in A, P(x)] and Elements = [T(x), default]
  3061. // i.e., for "true" comprehensions, the list of elements will always have either one or two elements (two if there is a default)
  3062. public class Comprehension : Expression
  3063. {
  3064. public ComprehensionMode Mode = ComprehensionMode.Comprehension;
  3065. public ExpressionList BindingsAndFilters;
  3066. public ExpressionList Elements;
  3067. public Node nonEnumerableTypeCtor; // used only when the comprehension should generate code for an IList, e.g.
  3068. public Method AddMethod; // used only when the comprehension should generate code for an IList, e.g.
  3069. public TypeNode TemporaryHackToHoldType;
  3070. public Comprehension()
  3071. : base(NodeType.Comprehension)
  3072. {
  3073. }
  3074. public bool IsDisplay
  3075. {
  3076. get
  3077. {
  3078. return this.BindingsAndFilters == null;
  3079. }
  3080. }
  3081. }
  3082. public class NameBinding : Expression
  3083. {
  3084. public Identifier Identifier;
  3085. public MemberList BoundMembers;
  3086. public Expression BoundMember;
  3087. public int LexLevel;
  3088. public Class MostNestedScope;
  3089. public NameBinding()
  3090. : base(NodeType.NameBinding)
  3091. {
  3092. }
  3093. public NameBinding(Identifier identifier, MemberList boundMembers)
  3094. : base(NodeType.NameBinding)
  3095. {
  3096. this.Identifier = identifier;
  3097. this.BoundMembers = boundMembers;
  3098. }
  3099. public NameBinding(Identifier identifier, MemberList boundMembers, SourceContext sctx)
  3100. : base(NodeType.NameBinding)
  3101. {
  3102. this.Identifier = identifier;
  3103. this.BoundMembers = boundMembers;
  3104. this.SourceContext = sctx;
  3105. }
  3106. public NameBinding(Identifier identifier, MemberList boundMembers, Class mostNestedScope, int lexLevel)
  3107. : base(NodeType.NameBinding)
  3108. {
  3109. this.Identifier = identifier;
  3110. this.BoundMembers = boundMembers;
  3111. this.LexLevel = lexLevel;
  3112. this.MostNestedScope = mostNestedScope;
  3113. }
  3114. public NameBinding(Identifier identifier, MemberList boundMembers, Class mostNestedScope, int lexLevel, SourceContext sctx)
  3115. : base(NodeType.NameBinding)
  3116. {
  3117. this.Identifier = identifier;
  3118. this.BoundMembers = boundMembers;
  3119. this.LexLevel = lexLevel;
  3120. this.MostNestedScope = mostNestedScope;
  3121. this.SourceContext = sctx;
  3122. }
  3123. public override string ToString()
  3124. {
  3125. return this.Identifier == null ? "" : this.Identifier.ToString();
  3126. }
  3127. }
  3128. public class TemplateInstance : Expression
  3129. {
  3130. public Expression Expression;
  3131. public TypeNodeList TypeArguments;
  3132. public TypeNodeList TypeArgumentExpressions;
  3133. public bool IsMethodTemplate;
  3134. public MemberList BoundMembers;
  3135. public TemplateInstance()
  3136. : this(null, null)
  3137. {
  3138. }
  3139. public TemplateInstance(Expression expression, TypeNodeList typeArguments)
  3140. : base(NodeType.TemplateInstance)
  3141. {
  3142. this.Expression = expression;
  3143. this.TypeArguments = typeArguments;
  3144. }
  3145. }
  3146. public class StackAlloc : Expression
  3147. {
  3148. public TypeNode ElementType;
  3149. public TypeNode ElementTypeExpression;
  3150. public Expression NumberOfElements;
  3151. public StackAlloc()
  3152. : base(NodeType.StackAlloc)
  3153. {
  3154. }
  3155. public StackAlloc(TypeNode elementType, Expression numberOfElements, SourceContext sctx)
  3156. : base(NodeType.StackAlloc)
  3157. {
  3158. this.ElementType = this.ElementTypeExpression = elementType;
  3159. this.NumberOfElements = numberOfElements;
  3160. this.SourceContext = sctx;
  3161. }
  3162. }
  3163. public class MethodCall : NaryExpression
  3164. {
  3165. private Expression callee;
  3166. private TypeNode constraint;
  3167. private bool isTailCall;
  3168. public Expression CalleeExpression;
  3169. public bool GiveErrorIfSpecialNameMethod;
  3170. public bool ArgumentListIsIncomplete;
  3171. public MethodCall()
  3172. {
  3173. this.NodeType = NodeType.MethodCall;
  3174. }
  3175. public MethodCall(Expression callee, ExpressionList arguments)
  3176. : base(arguments, NodeType.MethodCall)
  3177. {
  3178. this.callee = this.CalleeExpression = callee;
  3179. this.isTailCall = false;
  3180. }
  3181. public MethodCall(Expression callee, ExpressionList arguments, NodeType typeOfCall)
  3182. : base(arguments, typeOfCall)
  3183. {
  3184. this.callee = callee;
  3185. this.CalleeExpression = callee;
  3186. //this.isTailCall = false;
  3187. }
  3188. public MethodCall(Expression callee, ExpressionList arguments, NodeType typeOfCall, TypeNode resultType)
  3189. : this(callee, arguments, typeOfCall)
  3190. {
  3191. this.Type = resultType;
  3192. }
  3193. public MethodCall(Expression callee, ExpressionList arguments, NodeType typeOfCall, TypeNode resultType, SourceContext sctx)
  3194. : this(callee, arguments, typeOfCall, resultType)
  3195. {
  3196. this.SourceContext = sctx;
  3197. }
  3198. public Expression Callee
  3199. {
  3200. get { return this.callee; }
  3201. set { this.callee = value; }
  3202. }
  3203. public bool IsTailCall
  3204. {
  3205. get { return this.isTailCall; }
  3206. set { this.isTailCall = value; }
  3207. }
  3208. public TypeNode Constraint
  3209. {
  3210. get { return this.constraint; }
  3211. set { this.constraint = value; }
  3212. }
  3213. }
  3214. public class Construct : NaryExpression
  3215. {
  3216. private Expression constructor;
  3217. public Expression Owner;
  3218. public Construct()
  3219. {
  3220. this.NodeType = NodeType.Construct;
  3221. }
  3222. public Construct(Expression constructor, ExpressionList arguments)
  3223. : base(arguments, NodeType.Construct)
  3224. {
  3225. this.constructor = constructor;
  3226. }
  3227. public Construct(Expression constructor, ExpressionList arguments, SourceContext sctx)
  3228. : base(arguments, NodeType.Construct)
  3229. {
  3230. this.constructor = constructor;
  3231. this.SourceContext = sctx;
  3232. }
  3233. public Construct(Expression constructor, ExpressionList arguments, TypeNode type)
  3234. : base(arguments, NodeType.Construct)
  3235. {
  3236. this.constructor = constructor;
  3237. this.Type = type;
  3238. }
  3239. public Construct(Expression constructor, ExpressionList arguments, TypeNode type, SourceContext sctx)
  3240. : base(arguments, NodeType.Construct)
  3241. {
  3242. this.constructor = constructor;
  3243. this.Type = type;
  3244. this.SourceContext = sctx;
  3245. }
  3246. public Expression Constructor
  3247. {
  3248. get { return this.constructor; }
  3249. set { this.constructor = value; }
  3250. }
  3251. }
  3252. public class ConstructArray : NaryExpression
  3253. {
  3254. private TypeNode elementType;
  3255. private int rank;
  3256. public TypeNode ElementTypeExpression;
  3257. public ExpressionList Initializers;
  3258. public Expression Owner;
  3259. public ConstructArray()
  3260. {
  3261. this.NodeType = NodeType.ConstructArray;
  3262. this.rank = 1;
  3263. }
  3264. public ConstructArray(TypeNode elementType, ExpressionList sizes, ExpressionList initializers)
  3265. : base(sizes, NodeType.ConstructArray)
  3266. {
  3267. this.elementType = elementType;
  3268. this.Operands = sizes;
  3269. this.rank = sizes == null ? 1 : sizes.Count;
  3270. this.Initializers = initializers;
  3271. }
  3272. public ConstructArray(TypeNode elementType, ExpressionList initializers)
  3273. : base(null, NodeType.ConstructArray)
  3274. {
  3275. this.elementType = elementType;
  3276. this.Initializers = initializers;
  3277. this.rank = 1;
  3278. if(elementType != null)
  3279. this.Type = elementType.GetArrayType(1);
  3280. }
  3281. public ConstructArray(TypeNode elementType, int rank, ExpressionList initializers)
  3282. : base(null, NodeType.ConstructArray)
  3283. {
  3284. this.elementType = elementType;
  3285. this.Initializers = initializers;
  3286. this.rank = rank;
  3287. if(elementType != null)
  3288. this.Type = elementType.GetArrayType(1);
  3289. }
  3290. public TypeNode ElementType
  3291. {
  3292. get { return this.elementType; }
  3293. set { this.elementType = value; }
  3294. }
  3295. public int Rank
  3296. {
  3297. get { return this.rank; }
  3298. set { this.rank = value; }
  3299. }
  3300. }
  3301. public class ConstructFlexArray : NaryExpression
  3302. {
  3303. public TypeNode ElementType;
  3304. public TypeNode ElementTypeExpression;
  3305. public ExpressionList Initializers;
  3306. public ConstructFlexArray()
  3307. {
  3308. this.NodeType = NodeType.ConstructFlexArray;
  3309. }
  3310. public ConstructFlexArray(TypeNode elementType, ExpressionList sizes, ExpressionList initializers)
  3311. : base(sizes, NodeType.ConstructFlexArray)
  3312. {
  3313. this.ElementType = elementType;
  3314. this.Operands = sizes;
  3315. this.Initializers = initializers;
  3316. }
  3317. }
  3318. public class ConstructDelegate : Expression
  3319. {
  3320. public TypeNode DelegateType;
  3321. public TypeNode DelegateTypeExpression;
  3322. public Identifier MethodName;
  3323. public Expression TargetObject;
  3324. public ConstructDelegate()
  3325. : base(NodeType.ConstructDelegate)
  3326. {
  3327. }
  3328. public ConstructDelegate(TypeNode delegateType, Expression targetObject, Identifier methodName)
  3329. : base(NodeType.ConstructDelegate)
  3330. {
  3331. this.DelegateType = delegateType;
  3332. this.MethodName = methodName;
  3333. this.TargetObject = targetObject;
  3334. }
  3335. public ConstructDelegate(TypeNode delegateType, Expression targetObject, Identifier methodName, SourceContext sctx)
  3336. : base(NodeType.ConstructDelegate)
  3337. {
  3338. this.DelegateType = delegateType;
  3339. this.MethodName = methodName;
  3340. this.TargetObject = targetObject;
  3341. this.SourceContext = sctx;
  3342. }
  3343. }
  3344. public class ConstructIterator : Expression
  3345. {
  3346. public Class State;
  3347. public Block Body;
  3348. public TypeNode ElementType;
  3349. public ConstructIterator()
  3350. : base(NodeType.ConstructIterator)
  3351. {
  3352. }
  3353. public ConstructIterator(Class state, Block body, TypeNode elementType, TypeNode type)
  3354. : base(NodeType.ConstructIterator)
  3355. {
  3356. this.State = state;
  3357. this.Body = body;
  3358. this.ElementType = elementType;
  3359. this.Type = type;
  3360. }
  3361. }
  3362. public class ConstructTuple : Expression
  3363. {
  3364. public FieldList Fields;
  3365. public ConstructTuple()
  3366. : base(NodeType.ConstructTuple)
  3367. {
  3368. }
  3369. }
  3370. public class CoerceTuple : ConstructTuple
  3371. {
  3372. public Expression OriginalTuple;
  3373. public Local Temp;
  3374. public CoerceTuple()
  3375. {
  3376. this.NodeType = NodeType.CoerceTuple;
  3377. }
  3378. }
  3379. public class Indexer : NaryExpression
  3380. {
  3381. public Property CorrespondingDefaultIndexedProperty;
  3382. public bool ArgumentListIsIncomplete;
  3383. public Indexer()
  3384. {
  3385. this.NodeType = NodeType.Indexer;
  3386. }
  3387. public Indexer(Expression @object, ExpressionList arguments)
  3388. : base(arguments, NodeType.Indexer)
  3389. {
  3390. this.@object = @object;
  3391. }
  3392. public Indexer(Expression Object, ExpressionList arguments, SourceContext sctx)
  3393. : base(arguments, NodeType.Indexer)
  3394. {
  3395. this.@object = Object;
  3396. this.SourceContext = sctx;
  3397. }
  3398. public Indexer(Expression Object, ExpressionList arguments, TypeNode elementType)
  3399. : base(arguments, NodeType.Indexer)
  3400. {
  3401. this.@object = Object;
  3402. this.elementType = this.Type = elementType;
  3403. }
  3404. public Indexer(Expression Object, ExpressionList arguments, TypeNode elementType, SourceContext sctx)
  3405. : base(arguments, NodeType.Indexer)
  3406. {
  3407. this.@object = Object;
  3408. this.elementType = this.Type = elementType;
  3409. this.SourceContext = sctx;
  3410. }
  3411. private Expression @object;
  3412. public Expression Object
  3413. {
  3414. get { return this.@object; }
  3415. set { this.@object = value; }
  3416. }
  3417. private TypeNode elementType;
  3418. /// <summary>
  3419. /// This type is normally expected to be the same the value of Type. However, if the indexer applies to an array of enums, then
  3420. /// Type will be the enum type and ElementType will be the underlying type of the enum.
  3421. /// </summary>
  3422. public TypeNode ElementType
  3423. {
  3424. get { return this.elementType; }
  3425. set { this.elementType = value; }
  3426. }
  3427. }
  3428. public class CollectionEnumerator : Expression
  3429. {
  3430. public Expression Collection;
  3431. public Method DefaultIndexerGetter;
  3432. public Method LengthPropertyGetter;
  3433. public Method GetEnumerator;
  3434. public Method MoveNext;
  3435. public Method GetCurrent;
  3436. public Local ElementLocal;
  3437. public Expression ElementCoercion;
  3438. public CollectionEnumerator()
  3439. : base(NodeType.CollectionEnumerator)
  3440. {
  3441. }
  3442. }
  3443. /// <summary>
  3444. /// An expression that is used on the left hand as well as the right hand side of an assignment statement. For example, e in (e += 1).
  3445. /// </summary>
  3446. public class LRExpression : Expression
  3447. {
  3448. public Expression Expression;
  3449. public LRExpression(Expression/*!*/ expression) : base(NodeType.LRExpression)
  3450. {
  3451. this.Expression = expression;
  3452. this.Type = expression.Type;
  3453. }
  3454. }
  3455. public class AssignmentExpression : Expression
  3456. {
  3457. public Statement AssignmentStatement;
  3458. public AssignmentExpression()
  3459. : base(NodeType.AssignmentExpression)
  3460. {
  3461. }
  3462. public AssignmentExpression(AssignmentStatement assignment)
  3463. : base(NodeType.AssignmentExpression)
  3464. {
  3465. this.AssignmentStatement = assignment;
  3466. }
  3467. }
  3468. public class BlockExpression : Expression
  3469. {
  3470. public Block Block;
  3471. public BlockExpression()
  3472. : base(NodeType.BlockExpression)
  3473. {
  3474. }
  3475. public BlockExpression(Block block)
  3476. : base(NodeType.BlockExpression)
  3477. {
  3478. this.Block = block;
  3479. }
  3480. public BlockExpression(Block block, TypeNode type)
  3481. : base(NodeType.BlockExpression)
  3482. {
  3483. this.Block = block;
  3484. this.Type = type;
  3485. }
  3486. public BlockExpression(Block block, TypeNode type, SourceContext sctx)
  3487. : base(NodeType.BlockExpression)
  3488. {
  3489. this.Block = block;
  3490. this.Type = type;
  3491. this.SourceContext = sctx;
  3492. }
  3493. }
  3494. public class AnonymousNestedFunction : Expression
  3495. {
  3496. public ParameterList Parameters;
  3497. public Block Body;
  3498. public Method Method;
  3499. public Expression Invocation;
  3500. public AnonymousNestedFunction()
  3501. : base(NodeType.AnonymousNestedFunction)
  3502. {
  3503. }
  3504. public AnonymousNestedFunction(ParameterList parameters, Block body)
  3505. : base(NodeType.AnonymousNestedFunction)
  3506. {
  3507. this.Parameters = parameters;
  3508. this.Body = body;
  3509. }
  3510. public AnonymousNestedFunction(ParameterList parameters, Block body, SourceContext sctx)
  3511. : base(NodeType.AnonymousNestedFunction)
  3512. {
  3513. this.Parameters = parameters;
  3514. this.Body = body;
  3515. this.SourceContext = sctx;
  3516. }
  3517. }
  3518. public class Instruction : Node
  3519. {
  3520. private OpCode opCode;
  3521. private int offset;
  3522. private object value;
  3523. public Instruction()
  3524. : base(NodeType.Instruction)
  3525. {
  3526. }
  3527. public Instruction(OpCode opCode, int offset)
  3528. : this(opCode, offset, null)
  3529. {
  3530. }
  3531. public Instruction(OpCode opCode, int offset, object value)
  3532. : base(NodeType.Instruction)
  3533. {
  3534. this.opCode = opCode;
  3535. this.offset = offset;
  3536. this.value = value;
  3537. }
  3538. /// <summary>The actual value of the opcode</summary>
  3539. public OpCode OpCode
  3540. {
  3541. get { return this.opCode; }
  3542. set { this.opCode = value; }
  3543. }
  3544. /// <summary>The offset from the start of the instruction stream of a method</summary>
  3545. public int Offset
  3546. {
  3547. get { return this.offset; }
  3548. set { this.offset = value; }
  3549. }
  3550. /// <summary>Immediate data such as a string, the address of a branch target, or a metadata reference, such as a Field</summary>
  3551. public object Value
  3552. {
  3553. get { return this.value; }
  3554. set { this.value = value; }
  3555. }
  3556. }
  3557. public class Statement : Node
  3558. {
  3559. public Statement(NodeType nodeType)
  3560. : base(nodeType)
  3561. {
  3562. }
  3563. public Statement(NodeType nodeType, SourceContext sctx)
  3564. : base(nodeType)
  3565. {
  3566. this.SourceContext = sctx;
  3567. }
  3568. }
  3569. public class Block : Statement
  3570. {
  3571. private StatementList statements;
  3572. public bool Checked;
  3573. public bool SuppressCheck;
  3574. public bool HasLocals;
  3575. public bool IsUnsafe;
  3576. public BlockScope Scope;
  3577. public Block()
  3578. : base(NodeType.Block)
  3579. {
  3580. }
  3581. public Block(StatementList statements)
  3582. : base(NodeType.Block)
  3583. {
  3584. this.statements = statements;
  3585. }
  3586. public Block(StatementList statements, SourceContext sourceContext)
  3587. : base(NodeType.Block)
  3588. {
  3589. this.SourceContext = sourceContext;
  3590. this.statements = statements;
  3591. }
  3592. public Block(StatementList statements, bool Checked, bool SuppressCheck, bool IsUnsafe)
  3593. : base(NodeType.Block)
  3594. {
  3595. this.Checked = Checked;
  3596. this.IsUnsafe = IsUnsafe;
  3597. this.SuppressCheck = SuppressCheck;
  3598. this.statements = statements;
  3599. }
  3600. public Block(StatementList statements, SourceContext sourceContext, bool Checked, bool SuppressCheck, bool IsUnsafe)
  3601. : base(NodeType.Block)
  3602. {
  3603. this.Checked = Checked;
  3604. this.IsUnsafe = IsUnsafe;
  3605. this.SuppressCheck = SuppressCheck;
  3606. this.SourceContext = sourceContext;
  3607. this.statements = statements;
  3608. }
  3609. public override string ToString()
  3610. {
  3611. return "B#" + this.UniqueKey.ToString();
  3612. }
  3613. public StatementList Statements
  3614. {
  3615. get { return this.statements; }
  3616. set { this.statements = value; }
  3617. }
  3618. }
  3619. public class LabeledStatement : Block
  3620. {
  3621. public Identifier Label;
  3622. public Statement Statement;
  3623. public LabeledStatement()
  3624. {
  3625. this.NodeType = NodeType.LabeledStatement;
  3626. }
  3627. }
  3628. public class FunctionDeclaration : Statement
  3629. {
  3630. public Identifier Name;
  3631. public ParameterList Parameters;
  3632. public TypeNode ReturnType;
  3633. public TypeNode ReturnTypeExpression;
  3634. public Block Body;
  3635. public Method Method;
  3636. public FunctionDeclaration()
  3637. : base(NodeType.FunctionDeclaration)
  3638. {
  3639. }
  3640. public FunctionDeclaration(Identifier name, ParameterList parameters, TypeNode returnType, Block body)
  3641. : base(NodeType.FunctionDeclaration)
  3642. {
  3643. this.Name = name;
  3644. this.Parameters = parameters;
  3645. this.ReturnType = returnType;
  3646. this.Body = body;
  3647. }
  3648. }
  3649. public class Assertion : Statement
  3650. {
  3651. public Expression Condition;
  3652. public Assertion()
  3653. : base(NodeType.Assertion)
  3654. {
  3655. }
  3656. public Assertion(Expression condition)
  3657. : base(NodeType.Assertion)
  3658. {
  3659. this.Condition = condition;
  3660. }
  3661. }
  3662. public class Assumption : Statement
  3663. {
  3664. public Expression Condition;
  3665. public Assumption()
  3666. : base(NodeType.Assumption)
  3667. {
  3668. }
  3669. public Assumption(Expression condition)
  3670. : base(NodeType.Assumption)
  3671. {
  3672. this.Condition = condition;
  3673. }
  3674. }
  3675. public class AssignmentStatement : Statement
  3676. {
  3677. private NodeType @operator;
  3678. private Expression source;
  3679. private Expression target;
  3680. public Method OperatorOverload;
  3681. ///<summary>A Type two which both operands must be coerced before carrying out the operation (if any).</summary>
  3682. public TypeNode UnifiedType;
  3683. public AssignmentStatement()
  3684. : base(NodeType.AssignmentStatement)
  3685. {
  3686. this.Operator = NodeType.Nop;
  3687. }
  3688. public AssignmentStatement(Expression target, Expression source)
  3689. : this(target, source, NodeType.Nop)
  3690. {
  3691. }
  3692. public AssignmentStatement(Expression target, Expression source, SourceContext context)
  3693. : this(target, source, NodeType.Nop)
  3694. {
  3695. this.SourceContext = context;
  3696. }
  3697. public AssignmentStatement(Expression target, Expression source, NodeType @operator)
  3698. : base(NodeType.AssignmentStatement)
  3699. {
  3700. this.target = target;
  3701. this.source = source;
  3702. this.@operator = @operator;
  3703. }
  3704. public AssignmentStatement(Expression target, Expression source, NodeType Operator, SourceContext context)
  3705. : this(target, source, Operator)
  3706. {
  3707. this.SourceContext = context;
  3708. }
  3709. public NodeType Operator
  3710. {
  3711. get { return this.@operator; }
  3712. set { this.@operator = value; }
  3713. }
  3714. public Expression Source
  3715. {
  3716. get { return this.source; }
  3717. set { this.source = value; }
  3718. }
  3719. public Expression Target
  3720. {
  3721. get { return this.target; }
  3722. set { this.target = value; }
  3723. }
  3724. }
  3725. public class ExpressionStatement : Statement
  3726. {
  3727. private Expression expression;
  3728. public ExpressionStatement()
  3729. : base(NodeType.ExpressionStatement)
  3730. {
  3731. }
  3732. public ExpressionStatement(Expression expression)
  3733. : base(NodeType.ExpressionStatement)
  3734. {
  3735. this.Expression = expression;
  3736. }
  3737. public ExpressionStatement(Expression expression, SourceContext sctx)
  3738. : base(NodeType.ExpressionStatement)
  3739. {
  3740. this.Expression = expression;
  3741. this.SourceContext = sctx;
  3742. }
  3743. public Expression Expression
  3744. {
  3745. get { return this.expression; }
  3746. set { this.expression = value; }
  3747. }
  3748. }
  3749. public class Branch : Statement
  3750. {
  3751. private Expression condition;
  3752. private bool leavesExceptionBlock;
  3753. internal bool shortOffset;
  3754. private Block target;
  3755. public bool BranchIfUnordered;
  3756. public Branch()
  3757. : base(NodeType.Branch)
  3758. {
  3759. }
  3760. public Branch(Expression condition, Block target)
  3761. : this(condition, target, false, false, false)
  3762. {
  3763. }
  3764. public Branch(Expression condition, Block target, SourceContext sourceContext)
  3765. : this(condition, target, false, false, false)
  3766. {
  3767. this.SourceContext = sourceContext;
  3768. }
  3769. public Branch(Expression condition, Block target, SourceContext sourceContext, bool unordered)
  3770. : this(condition, target, false, false, false)
  3771. {
  3772. this.BranchIfUnordered = unordered;
  3773. this.SourceContext = sourceContext;
  3774. }
  3775. public Branch(Expression condition, Block target, bool shortOffset, bool unordered, bool leavesExceptionBlock)
  3776. : base(NodeType.Branch)
  3777. {
  3778. this.BranchIfUnordered = unordered;
  3779. this.condition = condition;
  3780. this.leavesExceptionBlock = leavesExceptionBlock;
  3781. this.shortOffset = shortOffset;
  3782. this.target = target;
  3783. }
  3784. public Expression Condition
  3785. {
  3786. get { return this.condition; }
  3787. set { this.condition = value; }
  3788. }
  3789. public bool LeavesExceptionBlock
  3790. {
  3791. get { return this.leavesExceptionBlock; }
  3792. set { this.leavesExceptionBlock = value; }
  3793. }
  3794. public bool ShortOffset
  3795. {
  3796. get { return this.shortOffset; }
  3797. set { this.shortOffset = value; }
  3798. }
  3799. public Block Target
  3800. {
  3801. get { return this.target; }
  3802. set { this.target = value; }
  3803. }
  3804. }
  3805. public class Return : ExpressionStatement
  3806. {
  3807. public Return() : base()
  3808. {
  3809. this.NodeType = NodeType.Return;
  3810. }
  3811. public Return(Expression expression) : base(expression)
  3812. {
  3813. this.NodeType = NodeType.Return;
  3814. }
  3815. public Return(SourceContext sctx)
  3816. : base()
  3817. {
  3818. this.NodeType = NodeType.Return;
  3819. this.SourceContext = sctx;
  3820. }
  3821. public Return(Expression expression, SourceContext sctx)
  3822. : base(expression)
  3823. {
  3824. this.NodeType = NodeType.Return;
  3825. this.SourceContext = sctx;
  3826. }
  3827. }
  3828. public class Yield : ExpressionStatement
  3829. {
  3830. public Yield()
  3831. : base()
  3832. {
  3833. this.NodeType = NodeType.Yield;
  3834. }
  3835. public Yield(Expression expression)
  3836. : base(expression)
  3837. {
  3838. this.NodeType = NodeType.Yield;
  3839. }
  3840. public Yield(Expression expression, SourceContext sctx)
  3841. : base(expression)
  3842. {
  3843. this.NodeType = NodeType.Yield;
  3844. this.SourceContext = sctx;
  3845. }
  3846. }
  3847. public class Try : Statement
  3848. {
  3849. private CatchList catchers;
  3850. private FilterList filters;
  3851. private FaultHandlerList faultHandlers;
  3852. private Finally finallyClause;
  3853. private Block tryBlock;
  3854. public Try()
  3855. : base(NodeType.Try)
  3856. {
  3857. }
  3858. public Try(Block tryBlock, CatchList catchers, FilterList filters, FaultHandlerList faultHandlers, Finally Finally)
  3859. : base(NodeType.Try)
  3860. {
  3861. this.catchers = catchers;
  3862. this.faultHandlers = faultHandlers;
  3863. this.filters = filters;
  3864. this.finallyClause = Finally;
  3865. this.tryBlock = tryBlock;
  3866. }
  3867. public CatchList Catchers
  3868. {
  3869. get { return this.catchers; }
  3870. set { this.catchers = value; }
  3871. }
  3872. public FilterList Filters
  3873. {
  3874. get { return this.filters; }
  3875. set { this.filters = value; }
  3876. }
  3877. public FaultHandlerList FaultHandlers
  3878. {
  3879. get { return this.faultHandlers; }
  3880. set { this.faultHandlers = value; }
  3881. }
  3882. public Finally Finally
  3883. {
  3884. get { return this.finallyClause; }
  3885. set { this.finallyClause = value; }
  3886. }
  3887. public Block TryBlock
  3888. {
  3889. get { return this.tryBlock; }
  3890. set { this.tryBlock = value; }
  3891. }
  3892. }
  3893. public class Catch : Statement
  3894. {
  3895. private Block block;
  3896. private TypeNode type;
  3897. private Expression variable;
  3898. public TypeNode TypeExpression;
  3899. public Catch()
  3900. : base(NodeType.Catch)
  3901. {
  3902. }
  3903. public Catch(Block block, Expression variable, TypeNode type)
  3904. : base(NodeType.Catch)
  3905. {
  3906. this.block = block;
  3907. this.variable = variable;
  3908. this.type = type;
  3909. }
  3910. public Block Block
  3911. {
  3912. get { return this.block; }
  3913. set { this.block = value; }
  3914. }
  3915. public TypeNode Type
  3916. {
  3917. get { return this.type; }
  3918. set { this.type = value; }
  3919. }
  3920. public Expression Variable
  3921. {
  3922. get { return this.variable; }
  3923. set { this.variable = value; }
  3924. }
  3925. }
  3926. public class Finally : Statement
  3927. {
  3928. private Block block;
  3929. public Finally()
  3930. : base(NodeType.Finally)
  3931. {
  3932. }
  3933. public Finally(Block block)
  3934. : base(NodeType.Finally)
  3935. {
  3936. this.block = block;
  3937. }
  3938. public Block Block
  3939. {
  3940. get { return this.block; }
  3941. set { this.block = value; }
  3942. }
  3943. }
  3944. public class EndFinally : Statement
  3945. {
  3946. public EndFinally()
  3947. : base(NodeType.EndFinally)
  3948. {
  3949. }
  3950. }
  3951. public class Filter : Statement
  3952. {
  3953. private Block block;
  3954. private Expression expression;
  3955. public Filter()
  3956. : base(NodeType.Filter)
  3957. {
  3958. }
  3959. public Filter(Block block, Expression expression)
  3960. : base(NodeType.Filter)
  3961. {
  3962. this.block = block;
  3963. this.expression = expression;
  3964. }
  3965. public Block Block
  3966. {
  3967. get { return this.block; }
  3968. set { this.block = value; }
  3969. }
  3970. public Expression Expression
  3971. {
  3972. get { return this.expression; }
  3973. set { this.expression = value; }
  3974. }
  3975. }
  3976. public class EndFilter : Statement
  3977. {
  3978. private Expression value;
  3979. public EndFilter()
  3980. : base(NodeType.EndFilter)
  3981. {
  3982. }
  3983. public EndFilter(Expression value)
  3984. : base(NodeType.EndFilter)
  3985. {
  3986. this.value = value;
  3987. }
  3988. public Expression Value
  3989. {
  3990. get { return this.value; }
  3991. set { this.value = value; }
  3992. }
  3993. }
  3994. public class FaultHandler : Statement
  3995. {
  3996. private Block block;
  3997. public FaultHandler()
  3998. : base(NodeType.FaultHandler)
  3999. {
  4000. }
  4001. public FaultHandler(Block block)
  4002. : base(NodeType.FaultHandler)
  4003. {
  4004. this.block = block;
  4005. }
  4006. public Block Block
  4007. {
  4008. get { return this.block; }
  4009. set { this.block = value; }
  4010. }
  4011. }
  4012. public class Throw : Statement
  4013. {
  4014. private Expression expression;
  4015. public Throw()
  4016. : base(NodeType.Throw)
  4017. {
  4018. }
  4019. public Throw(Expression expression)
  4020. : base(NodeType.Throw)
  4021. {
  4022. this.expression = expression;
  4023. }
  4024. public Throw(Expression expression, SourceContext context)
  4025. : base(NodeType.Throw)
  4026. {
  4027. this.expression = expression;
  4028. this.SourceContext = context;
  4029. }
  4030. public Expression Expression
  4031. {
  4032. get { return this.expression; }
  4033. set { this.expression = value; }
  4034. }
  4035. }
  4036. public class If : Statement
  4037. {
  4038. public Expression Condition;
  4039. public Block TrueBlock;
  4040. public Block FalseBlock;
  4041. public SourceContext ConditionContext;
  4042. public SourceContext ElseContext;
  4043. public SourceContext EndIfContext;
  4044. public If()
  4045. : base(NodeType.If)
  4046. {
  4047. }
  4048. public If(Expression condition, Block trueBlock, Block falseBlock)
  4049. : base(NodeType.If)
  4050. {
  4051. this.Condition = condition;
  4052. if(condition != null)
  4053. this.ConditionContext = condition.SourceContext;
  4054. this.TrueBlock = trueBlock;
  4055. this.FalseBlock = falseBlock;
  4056. }
  4057. }
  4058. public class For : Statement
  4059. {
  4060. public Block Body;
  4061. public Expression Condition;
  4062. public StatementList Incrementer;
  4063. public StatementList Initializer;
  4064. public ExpressionList Invariants;
  4065. public For()
  4066. : base(NodeType.For)
  4067. {
  4068. }
  4069. public For(StatementList initializer, Expression condition, StatementList incrementer, Block body)
  4070. : base(NodeType.For)
  4071. {
  4072. this.Body = body;
  4073. this.Condition = condition;
  4074. this.Incrementer = incrementer;
  4075. this.Initializer = initializer;
  4076. }
  4077. }
  4078. public class ForEach : Statement
  4079. {
  4080. public Block Body;
  4081. public Expression SourceEnumerable;
  4082. public BlockScope ScopeForTemporaryVariables;
  4083. public Expression TargetVariable;
  4084. public TypeNode TargetVariableType;
  4085. public TypeNode TargetVariableTypeExpression;
  4086. public Expression InductionVariable;
  4087. public ExpressionList Invariants;
  4088. public bool StatementTerminatesNormallyIfEnumerableIsNull = true;
  4089. public bool StatementTerminatesNormallyIfEnumeratorIsNull = true;
  4090. public ForEach()
  4091. : base(NodeType.ForEach)
  4092. {
  4093. }
  4094. public ForEach(TypeNode targetVariableType, Expression targetVariable, Expression sourceEnumerable, Block body)
  4095. : base(NodeType.ForEach)
  4096. {
  4097. this.TargetVariable = targetVariable;
  4098. this.TargetVariableType = targetVariableType;
  4099. this.SourceEnumerable = sourceEnumerable;
  4100. this.Body = body;
  4101. }
  4102. }
  4103. public class Exit : Statement
  4104. {
  4105. public Literal Level;
  4106. public Exit()
  4107. : base(NodeType.Exit)
  4108. {
  4109. }
  4110. public Exit(Literal level)
  4111. : base(NodeType.Exit)
  4112. {
  4113. this.Level = level;
  4114. }
  4115. }
  4116. public class Continue : Statement
  4117. {
  4118. public Literal Level;
  4119. public Continue()
  4120. : base(NodeType.Continue)
  4121. {
  4122. }
  4123. public Continue(Literal level)
  4124. : base(NodeType.Continue)
  4125. {
  4126. this.Level = level;
  4127. }
  4128. }
  4129. public class Switch : Statement
  4130. {
  4131. public SwitchCaseList Cases;
  4132. public Expression Expression;
  4133. public Local Nullable;
  4134. public Expression NullableExpression;
  4135. public BlockScope Scope;
  4136. public Switch()
  4137. : base(NodeType.Switch)
  4138. {
  4139. }
  4140. public Switch(Expression expression, SwitchCaseList cases)
  4141. : base(NodeType.Switch)
  4142. {
  4143. this.Cases = cases;
  4144. this.Expression = expression;
  4145. }
  4146. }
  4147. public class SwitchCase : Node
  4148. {
  4149. public Block Body;
  4150. public Expression Label;
  4151. public SwitchCase()
  4152. : base(NodeType.SwitchCase)
  4153. {
  4154. }
  4155. public SwitchCase(Expression label, Block body)
  4156. : base(NodeType.SwitchCase)
  4157. {
  4158. this.Body = body;
  4159. this.Label = label;
  4160. }
  4161. }
  4162. public class GotoCase : Statement
  4163. {
  4164. public Expression CaseLabel;
  4165. public GotoCase(Expression caseLabel)
  4166. : base(NodeType.GotoCase)
  4167. {
  4168. this.CaseLabel = caseLabel;
  4169. }
  4170. }
  4171. public class SwitchInstruction : Statement
  4172. {
  4173. private Expression expression;
  4174. private BlockList targets;
  4175. public SwitchInstruction()
  4176. : base(NodeType.SwitchInstruction)
  4177. {
  4178. }
  4179. public SwitchInstruction(Expression expression, BlockList targets)
  4180. : base(NodeType.SwitchInstruction)
  4181. {
  4182. this.expression = expression;
  4183. this.targets = targets;
  4184. }
  4185. public Expression Expression
  4186. {
  4187. get { return this.expression; }
  4188. set { this.expression = value; }
  4189. }
  4190. public BlockList Targets
  4191. {
  4192. get { return this.targets; }
  4193. set { this.targets = value; }
  4194. }
  4195. }
  4196. public class Typeswitch : Statement
  4197. {
  4198. public TypeswitchCaseList Cases;
  4199. public Expression Expression;
  4200. public Typeswitch()
  4201. : base(NodeType.Typeswitch)
  4202. {
  4203. }
  4204. public Typeswitch(Expression expression, TypeswitchCaseList cases)
  4205. : base(NodeType.Typeswitch)
  4206. {
  4207. this.Cases = cases;
  4208. this.Expression = expression;
  4209. }
  4210. }
  4211. public class TypeswitchCase : Node
  4212. {
  4213. public Block Body;
  4214. public TypeNode LabelType;
  4215. public TypeNode LabelTypeExpression;
  4216. public Expression LabelVariable;
  4217. public TypeswitchCase()
  4218. : base(NodeType.TypeswitchCase)
  4219. {
  4220. }
  4221. public TypeswitchCase(TypeNode labelType, Expression labelVariable, Block body)
  4222. : base(NodeType.TypeswitchCase)
  4223. {
  4224. this.Body = body;
  4225. this.LabelType = labelType;
  4226. this.LabelVariable = labelVariable;
  4227. }
  4228. }
  4229. public class While : Statement
  4230. {
  4231. public Expression Condition;
  4232. public ExpressionList Invariants;
  4233. public Block Body;
  4234. public While()
  4235. : base(NodeType.While)
  4236. {
  4237. }
  4238. public While(Expression condition, Block body)
  4239. : base(NodeType.While)
  4240. {
  4241. this.Condition = condition;
  4242. this.Body = body;
  4243. }
  4244. }
  4245. public class DoWhile : Statement
  4246. {
  4247. public Expression Condition;
  4248. public ExpressionList Invariants;
  4249. public Block Body;
  4250. public DoWhile()
  4251. : base(NodeType.DoWhile)
  4252. {
  4253. }
  4254. public DoWhile(Expression condition, Block body)
  4255. : base(NodeType.DoWhile)
  4256. {
  4257. this.Condition = condition;
  4258. this.Body = body;
  4259. }
  4260. }
  4261. public class Repeat : Statement
  4262. {
  4263. public Expression Condition;
  4264. public Block Body;
  4265. public Repeat()
  4266. : base(NodeType.Repeat)
  4267. {
  4268. }
  4269. public Repeat(Expression condition, Block body)
  4270. : base(NodeType.Repeat)
  4271. {
  4272. this.Condition = condition;
  4273. this.Body = body;
  4274. }
  4275. }
  4276. public class Fixed : Statement
  4277. {
  4278. public Statement Declarators;
  4279. public Block Body;
  4280. public BlockScope ScopeForTemporaryVariables;
  4281. public Fixed()
  4282. : base(NodeType.Fixed)
  4283. {
  4284. }
  4285. }
  4286. public class Lock : Statement
  4287. {
  4288. public Expression Guard;
  4289. public Block Body;
  4290. public BlockScope ScopeForTemporaryVariable;
  4291. public Lock()
  4292. : base(NodeType.Lock)
  4293. {
  4294. }
  4295. }
  4296. public class ResourceUse : Statement
  4297. {
  4298. public Statement ResourceAcquisition;
  4299. public Block Body;
  4300. public BlockScope ScopeForTemporaryVariable;
  4301. public ResourceUse()
  4302. : base(NodeType.ResourceUse)
  4303. {
  4304. }
  4305. }
  4306. public class Goto : Statement
  4307. {
  4308. public Identifier TargetLabel;
  4309. public Goto()
  4310. : base(NodeType.Goto)
  4311. {
  4312. }
  4313. public Goto(Identifier targetLabel)
  4314. : base(NodeType.Goto)
  4315. {
  4316. this.TargetLabel = targetLabel;
  4317. }
  4318. }
  4319. public class VariableDeclaration : Statement
  4320. {
  4321. public Expression Initializer;
  4322. public Identifier Name;
  4323. public TypeNode Type;
  4324. public TypeNode TypeExpression;
  4325. public Field Field;
  4326. public VariableDeclaration()
  4327. : base(NodeType.VariableDeclaration)
  4328. {
  4329. }
  4330. public VariableDeclaration(Identifier name, TypeNode type, Expression initializer)
  4331. : base(NodeType.VariableDeclaration)
  4332. {
  4333. this.Initializer = initializer;
  4334. this.Name = name;
  4335. this.Type = type;
  4336. }
  4337. }
  4338. public class LocalDeclaration : Node
  4339. {
  4340. public Field Field;
  4341. public Identifier Name;
  4342. public Expression InitialValue;
  4343. /// <summary>
  4344. /// Used when converting a declaration with initializer into an assignment statement.
  4345. /// Usually Nop, but could be set to CopyReference to avoid dereferencing on either side.
  4346. /// </summary>
  4347. public NodeType AssignmentNodeType = NodeType.Nop;
  4348. public LocalDeclaration()
  4349. : base(NodeType.LocalDeclaration)
  4350. {
  4351. }
  4352. public LocalDeclaration(Identifier name, Expression initialValue)
  4353. : base(NodeType.LocalDeclaration)
  4354. {
  4355. this.Name = name;
  4356. this.InitialValue = initialValue;
  4357. }
  4358. public LocalDeclaration(Identifier name, Expression initialValue, NodeType assignmentNodeType)
  4359. : base(NodeType.LocalDeclaration)
  4360. {
  4361. this.Name = name;
  4362. this.InitialValue = initialValue;
  4363. this.AssignmentNodeType = assignmentNodeType;
  4364. }
  4365. }
  4366. public class LocalDeclarationsStatement : Statement
  4367. {
  4368. public bool Constant;
  4369. public bool InitOnly;
  4370. public TypeNode Type;
  4371. public TypeNode TypeExpression;
  4372. public LocalDeclarationList Declarations;
  4373. public LocalDeclarationsStatement()
  4374. : base(NodeType.LocalDeclarationsStatement)
  4375. {
  4376. }
  4377. public LocalDeclarationsStatement(LocalDeclaration ldecl, TypeNode type)
  4378. : base(NodeType.LocalDeclarationsStatement)
  4379. {
  4380. Declarations = new LocalDeclarationList();
  4381. Declarations.Add(ldecl);
  4382. this.Type = type;
  4383. }
  4384. }
  4385. public class StatementSnippet : Statement
  4386. {
  4387. public IParserFactory ParserFactory;
  4388. public StatementSnippet()
  4389. : base(NodeType.StatementSnippet)
  4390. {
  4391. }
  4392. public StatementSnippet(IParserFactory parserFactory, SourceContext sctx)
  4393. : base(NodeType.StatementSnippet)
  4394. {
  4395. this.ParserFactory = parserFactory;
  4396. this.SourceContext = sctx;
  4397. }
  4398. }
  4399. /// <summary>
  4400. /// Associates an identifier with a type or a namespace or a Uri or a list of assemblies.
  4401. /// In C# alias identifiers are used as root identifiers in qualified expressions, or as identifier prefixes.
  4402. /// </summary>
  4403. public class AliasDefinition : Node
  4404. {
  4405. /// <summary>The identifier that serves as an alias for the type, namespace, Uri or list of assemblies.</summary>
  4406. public Identifier Alias;
  4407. /// <summary>The list of assemblies being aliased.</summary>
  4408. public AssemblyReferenceList AliasedAssemblies;
  4409. /// <summary>The expression that was (or should be) resolved into a type, namespace or Uri.</summary>
  4410. public Expression AliasedExpression;
  4411. /// <summary>The namespace being aliased.</summary>
  4412. public Identifier AliasedNamespace;
  4413. /// <summary>A reference to the type being aliased.</summary>
  4414. public TypeReference AliasedType;
  4415. /// <summary>The Uri being aliased.</summary>
  4416. public Identifier AliasedUri;
  4417. /// <summary>
  4418. /// If an alias definition conflicts with a type definition and this causes an ambiguity, the conflicting type is stored here
  4419. /// by the code that detects the ambiguity. A later visitor is expected to report an error if this is not null.
  4420. /// </summary>
  4421. public TypeNode ConflictingType;
  4422. public bool RestrictToInterfaces;
  4423. public bool RestrictToClassesAndInterfaces;
  4424. public AliasDefinition()
  4425. : base(NodeType.AliasDefinition)
  4426. {
  4427. }
  4428. public AliasDefinition(Identifier alias, Expression aliasedExpression)
  4429. : base(NodeType.AliasDefinition)
  4430. {
  4431. this.Alias = alias;
  4432. this.AliasedExpression = aliasedExpression;
  4433. }
  4434. public AliasDefinition(Identifier alias, Expression aliasedExpression, SourceContext sctx)
  4435. : base(NodeType.AliasDefinition)
  4436. {
  4437. this.Alias = alias;
  4438. this.AliasedExpression = aliasedExpression;
  4439. this.SourceContext = sctx;
  4440. }
  4441. }
  4442. public class UsedNamespace : Node
  4443. {
  4444. public Identifier Namespace;
  4445. public Identifier URI;
  4446. public UsedNamespace()
  4447. : base(NodeType.UsedNamespace)
  4448. {
  4449. }
  4450. public UsedNamespace(Identifier Namespace)
  4451. : base(NodeType.UsedNamespace)
  4452. {
  4453. this.Namespace = Namespace;
  4454. }
  4455. public UsedNamespace(Identifier Namespace, SourceContext sctx)
  4456. : base(NodeType.UsedNamespace)
  4457. {
  4458. this.Namespace = Namespace;
  4459. this.SourceContext = sctx;
  4460. }
  4461. }
  4462. public class ExceptionHandler : Node
  4463. {
  4464. private NodeType handlerType;
  4465. private Block tryStartBlock;
  4466. private Block blockAfterTryEnd;
  4467. private Block handlerStartBlock;
  4468. private Block blockAfterHandlerEnd;
  4469. private Block filterExpression;
  4470. private TypeNode filterType;
  4471. public ExceptionHandler()
  4472. : base(NodeType.ExceptionHandler)
  4473. {
  4474. }
  4475. public NodeType HandlerType
  4476. {
  4477. get { return this.handlerType; }
  4478. set { this.handlerType = value; }
  4479. }
  4480. public Block TryStartBlock
  4481. {
  4482. get { return this.tryStartBlock; }
  4483. set { this.tryStartBlock = value; }
  4484. }
  4485. public Block BlockAfterTryEnd
  4486. {
  4487. get { return this.blockAfterTryEnd; }
  4488. set { this.blockAfterTryEnd = value; }
  4489. }
  4490. public Block HandlerStartBlock
  4491. {
  4492. get { return this.handlerStartBlock; }
  4493. set { this.handlerStartBlock = value; }
  4494. }
  4495. public Block BlockAfterHandlerEnd
  4496. {
  4497. get { return this.blockAfterHandlerEnd; }
  4498. set { this.blockAfterHandlerEnd = value; }
  4499. }
  4500. public Block FilterExpression
  4501. {
  4502. get { return this.filterExpression; }
  4503. set { this.filterExpression = value; }
  4504. }
  4505. public TypeNode FilterType
  4506. {
  4507. get { return this.filterType; }
  4508. set { this.filterType = value; }
  4509. }
  4510. }
  4511. public class AttributeNode : Node
  4512. {
  4513. public bool IsPseudoAttribute;
  4514. public AttributeNode()
  4515. : base(NodeType.Attribute)
  4516. {
  4517. }
  4518. public AttributeNode(Expression constructor, ExpressionList expressions)
  4519. : base(NodeType.Attribute)
  4520. {
  4521. this.constructor = constructor;
  4522. this.expressions = expressions;
  4523. this.target = AttributeTargets.All;
  4524. }
  4525. public AttributeNode(Expression constructor, ExpressionList expressions, AttributeTargets target)
  4526. : base(NodeType.Attribute)
  4527. {
  4528. this.constructor = constructor;
  4529. this.expressions = expressions;
  4530. this.target = target;
  4531. }
  4532. private Expression constructor;
  4533. public Expression Constructor
  4534. {
  4535. get { return this.constructor; }
  4536. set { this.constructor = value; }
  4537. }
  4538. private ExpressionList expressions;
  4539. /// <summary>
  4540. /// Invariant: positional arguments occur first and in order in the expression list. Named arguments
  4541. /// follow positional arguments in any order.
  4542. /// </summary>
  4543. public ExpressionList Expressions
  4544. {
  4545. get { return this.expressions; }
  4546. set { this.expressions = value; }
  4547. }
  4548. private AttributeTargets target;
  4549. public AttributeTargets Target
  4550. {
  4551. get { return this.target; }
  4552. set { this.target = value; }
  4553. }
  4554. private bool allowMultiple;
  4555. public virtual bool AllowMultiple
  4556. {
  4557. get
  4558. {
  4559. if(this.usageAttribute == null)
  4560. this.GetUsageInformation();
  4561. return this.allowMultiple;
  4562. }
  4563. set
  4564. {
  4565. this.allowMultiple = value;
  4566. }
  4567. }
  4568. private bool inherited;
  4569. public virtual bool Inherited
  4570. {
  4571. get
  4572. {
  4573. if(this.usageAttribute == null)
  4574. this.GetUsageInformation();
  4575. return this.inherited;
  4576. }
  4577. set
  4578. {
  4579. this.inherited = value;
  4580. }
  4581. }
  4582. private AttributeTargets validOn;
  4583. public virtual AttributeTargets ValidOn
  4584. {
  4585. get
  4586. {
  4587. if(this.usageAttribute == null)
  4588. this.GetUsageInformation();
  4589. return this.validOn;
  4590. }
  4591. set
  4592. {
  4593. this.validOn = value;
  4594. }
  4595. }
  4596. private TypeNode type;
  4597. public virtual TypeNode Type
  4598. {
  4599. get
  4600. {
  4601. if(this.type == null)
  4602. {
  4603. MemberBinding mb = this.Constructor as MemberBinding;
  4604. Member cons = mb == null ? null : mb.BoundMember;
  4605. this.type = cons == null ? null : cons.DeclaringType;
  4606. }
  4607. return this.type;
  4608. }
  4609. set
  4610. {
  4611. this.type = value;
  4612. }
  4613. }
  4614. private AttributeNode usageAttribute;
  4615. private void GetUsageInformation()
  4616. {
  4617. AttributeNode attr = null;
  4618. TypeNode attrType = this.Type;
  4619. while(attrType != null)
  4620. {
  4621. attr = attrType.GetAttribute(SystemTypes.AttributeUsageAttribute);
  4622. if(attr != null)
  4623. break;
  4624. attrType = attrType.BaseType;
  4625. }
  4626. if(attr == null)
  4627. {
  4628. this.usageAttribute = AttributeNode.DoesNotExist;
  4629. return;
  4630. }
  4631. ExpressionList args = attr.Expressions;
  4632. if(args == null || args.Count < 1)
  4633. return;
  4634. Literal lit = args[0] as Literal;
  4635. if(lit == null || !(lit.Value is int))
  4636. return;
  4637. //^ assert lit.Value != null;
  4638. this.validOn = (AttributeTargets)(int)lit.Value;
  4639. for(int i = 1, n = args.Count; i < n; i++)
  4640. {
  4641. NamedArgument narg = args[i] as NamedArgument;
  4642. if(narg == null || narg.Name == null)
  4643. continue;
  4644. lit = narg.Value as Literal;
  4645. if(lit == null)
  4646. continue;
  4647. if(narg.Name.UniqueIdKey == StandardIds.AllowMultiple.UniqueIdKey)
  4648. {
  4649. if(lit.Value == null || !(lit.Value is bool))
  4650. continue;
  4651. this.allowMultiple = (bool)lit.Value;
  4652. }
  4653. else if(narg.Name.UniqueIdKey == StandardIds.Inherited.UniqueIdKey)
  4654. {
  4655. if(lit.Value == null || !(lit.Value is bool))
  4656. continue;
  4657. this.inherited = (bool)lit.Value;
  4658. }
  4659. }
  4660. }
  4661. public static readonly AttributeNode DoesNotExist = new AttributeNode();
  4662. public virtual System.Attribute GetRuntimeAttribute()
  4663. {
  4664. MemberBinding mb = this.Constructor as MemberBinding;
  4665. if(mb == null)
  4666. return null;
  4667. InstanceInitializer constr = mb.BoundMember as InstanceInitializer;
  4668. if(constr == null)
  4669. return null;
  4670. ParameterList parameters = constr.Parameters;
  4671. int paramCount = parameters == null ? 0 : parameters.Count;
  4672. object[] argumentValues = new object[paramCount];
  4673. ExpressionList argumentExpressions = this.Expressions;
  4674. int exprCount = argumentExpressions == null ? 0 : argumentExpressions.Count;
  4675. for(int i = 0, j = 0; i < paramCount; i++)
  4676. {
  4677. if(j >= exprCount)
  4678. return null;
  4679. //^ assert argumentExpressions != null;
  4680. Expression argExpr = argumentExpressions[j++];
  4681. Literal lit = argExpr as Literal;
  4682. if(lit == null)
  4683. continue;
  4684. argumentValues[i] = this.GetCoercedLiteralValue(lit.Type, lit.Value);
  4685. }
  4686. System.Attribute attr = this.ConstructAttribute(constr, argumentValues);
  4687. if(attr == null)
  4688. return null;
  4689. for(int i = 0; i < exprCount; i++)
  4690. {
  4691. //^ assert argumentExpressions != null;
  4692. NamedArgument namedArg = argumentExpressions[i] as NamedArgument;
  4693. if(namedArg == null)
  4694. continue;
  4695. if(namedArg.Name == null)
  4696. continue;
  4697. Literal lit = namedArg.Value as Literal;
  4698. if(lit == null)
  4699. continue;
  4700. object val = this.GetCoercedLiteralValue(lit.Type, lit.Value);
  4701. if(namedArg.IsCustomAttributeProperty)
  4702. {
  4703. TypeNode t = constr.DeclaringType;
  4704. while(t != null)
  4705. {
  4706. Property prop = t.GetProperty(namedArg.Name);
  4707. if(prop != null)
  4708. {
  4709. this.SetAttributeProperty(prop, attr, val);
  4710. t = null;
  4711. }
  4712. else
  4713. t = t.BaseType;
  4714. }
  4715. }
  4716. else
  4717. {
  4718. TypeNode t = constr.DeclaringType;
  4719. while(t != null)
  4720. {
  4721. Field f = constr.DeclaringType.GetField(namedArg.Name);
  4722. if(f != null)
  4723. {
  4724. System.Reflection.FieldInfo fieldInfo = f.GetFieldInfo();
  4725. if(fieldInfo != null)
  4726. fieldInfo.SetValue(attr, val);
  4727. t = null;
  4728. }
  4729. else
  4730. t = t.BaseType;
  4731. }
  4732. }
  4733. }
  4734. return attr;
  4735. }
  4736. /// <summary>
  4737. /// Gets the value of the literal coercing literals of TypeNode, EnumNode, TypeNode[], and EnumNode[] as needed.
  4738. /// </summary>
  4739. /// <param name="type">A TypeNode representing the type of the literal</param>
  4740. /// <param name="value">The value of the literal</param>
  4741. /// <returns>An object that has been coerced to the appropriate runtime type</returns>
  4742. protected object GetCoercedLiteralValue(TypeNode type, object value)
  4743. {
  4744. if(type == null || value == null)
  4745. return null;
  4746. switch(type.typeCode)
  4747. {
  4748. case ElementType.Class:
  4749. return ((TypeNode)value).GetRuntimeType();
  4750. case ElementType.ValueType:
  4751. return System.Enum.ToObject(type.GetRuntimeType(), value);
  4752. case ElementType.SzArray:
  4753. return this.GetCoercedArrayLiteral((ArrayType)type, (Array)value);
  4754. default:
  4755. Literal lit = value as Literal;
  4756. if(lit != null && type == CoreSystemTypes.Object && lit.Type is EnumNode)
  4757. return this.GetCoercedLiteralValue(lit.Type, lit.Value);
  4758. break;
  4759. }
  4760. return value;
  4761. }
  4762. /// <summary>
  4763. /// Gets the array literal in arrayValue coercing TypeNode[] and EnumNode[] as needed.
  4764. /// </summary>
  4765. /// <param name="arrayType">A TypeNode representing the array type</param>
  4766. /// <param name="arrayValue">The value of the array literal to coerce</param>
  4767. /// <returns>An Array object that has been coerced to the appropriate runtime type</returns>
  4768. protected Array GetCoercedArrayLiteral(ArrayType arrayType, Array arrayValue)
  4769. {
  4770. if(arrayType == null)
  4771. return null;
  4772. if(arrayValue == null)
  4773. return null;
  4774. // Multi-dimensional arrays are not legal in attribute instances according section 17.1.3 of the C# 1.0 spec
  4775. if(arrayValue.Rank != 1)
  4776. return null;
  4777. TypeNode elemType = arrayType.ElementType;
  4778. if(elemType.typeCode != ElementType.ValueType && elemType.typeCode != ElementType.Class)
  4779. return arrayValue;
  4780. int arraySize = arrayValue.GetLength(0);
  4781. Type et = elemType.GetRuntimeType();
  4782. if(et == null)
  4783. return null;
  4784. Array val = Array.CreateInstance(et, arraySize);
  4785. for(int i = 0; i < arraySize; i++)
  4786. val.SetValue(this.GetCoercedLiteralValue(elemType, arrayValue.GetValue(i)), i);
  4787. return val;
  4788. }
  4789. private void SetAttributeProperty(Property/*!*/ prop, System.Attribute attr, object val)
  4790. {
  4791. //This could execute partially trusted code, so set up a very restrictive execution environment
  4792. //TODO: skip this if the attribute is from a trusted assembly
  4793. System.Reflection.PropertyInfo propInfo = prop.GetPropertyInfo();
  4794. if(propInfo == null)
  4795. return;
  4796. //Because we invoke the setter through reflection, a stack walk is performed. The following two commented-out statements
  4797. //would cause the stack walk to fail.
  4798. //For now, we will run the setter in full trust until we work around this.
  4799. //For VS2005 and later, we will construct a DynamicMethod, wrap it in a delegate, and invoke that.
  4800. //System.Security.PermissionSet perm = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None);
  4801. //perm.PermitOnly();
  4802. try
  4803. {
  4804. propInfo.SetValue(attr, val, null);
  4805. }
  4806. catch { }
  4807. }
  4808. private System.Attribute ConstructAttribute(InstanceInitializer/*!*/ constr, object[] argumentValues)
  4809. {
  4810. //This could execute partially trusted code, so set up a very restrictive execution environment
  4811. //TODO: skip this if the attribute is from a trusted assembly
  4812. System.Reflection.ConstructorInfo consInfo = constr.GetConstructorInfo();
  4813. if(consInfo == null)
  4814. return null;
  4815. //Because we invoke the constructor through reflection, a stack walk is performed. The following two commented-out statements
  4816. //would cause the stack walk to fail.
  4817. //For VS2003 and earlier, we will run the constructor in full trust.
  4818. //For VS2005 and later, we will construct a DynamicMethod, wrap it in a delegate, and invoke that.
  4819. //System.Security.PermissionSet perm = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None);
  4820. //perm.PermitOnly();
  4821. try
  4822. {
  4823. return consInfo.Invoke(argumentValues) as System.Attribute;
  4824. }
  4825. catch { }
  4826. return null;
  4827. }
  4828. public Expression GetPositionalArgument(int position)
  4829. {
  4830. if(this.Expressions == null || this.Expressions.Count <= position)
  4831. return null;
  4832. Expression e = this.Expressions[position];
  4833. NamedArgument na = e as NamedArgument;
  4834. if(na != null)
  4835. return null;
  4836. return e;
  4837. }
  4838. public Expression GetNamedArgument(Identifier name)
  4839. {
  4840. if(name == null || this.Expressions == null)
  4841. return null;
  4842. foreach(Expression e in this.Expressions)
  4843. {
  4844. NamedArgument na = e as NamedArgument;
  4845. if(na == null)
  4846. continue;
  4847. if(na.Name == null)
  4848. continue;
  4849. if(na.Name.UniqueIdKey == name.UniqueIdKey)
  4850. return na.Value;
  4851. }
  4852. return null;
  4853. }
  4854. }
  4855. public class SecurityAttribute : Node
  4856. {
  4857. public SecurityAttribute()
  4858. : base(NodeType.SecurityAttribute)
  4859. {
  4860. }
  4861. private System.Security.Permissions.SecurityAction action;
  4862. public System.Security.Permissions.SecurityAction Action
  4863. {
  4864. get { return this.action; }
  4865. set { this.action = value; }
  4866. }
  4867. private AttributeList permissionAttributes;
  4868. public AttributeList PermissionAttributes
  4869. {
  4870. get { return this.permissionAttributes; }
  4871. set { this.permissionAttributes = value; }
  4872. }
  4873. protected string serializedPermissions;
  4874. public string SerializedPermissions
  4875. {
  4876. get
  4877. {
  4878. if(this.serializedPermissions == null && this.PermissionAttributes != null)
  4879. {
  4880. lock(this)
  4881. {
  4882. if(this.serializedPermissions != null)
  4883. return this.serializedPermissions;
  4884. System.Security.PermissionSet permissions = this.Permissions;
  4885. if(permissions == null)
  4886. return null;
  4887. System.Security.SecurityElement xml = permissions.ToXml();
  4888. if(xml == null)
  4889. return null;
  4890. this.serializedPermissions = xml.ToString();
  4891. //TODO: if the target platform is different from the host platform, replace references to host platform
  4892. //assemblies with references to target platform assemblies
  4893. }
  4894. }
  4895. return this.serializedPermissions;
  4896. }
  4897. set
  4898. {
  4899. this.serializedPermissions = value;
  4900. }
  4901. }
  4902. protected System.Security.PermissionSet permissions;
  4903. public System.Security.PermissionSet Permissions
  4904. {
  4905. get
  4906. {
  4907. if(this.permissions == null)
  4908. {
  4909. lock(this)
  4910. {
  4911. if(this.permissions != null)
  4912. return this.permissions;
  4913. System.Security.PermissionSet permissions = null;
  4914. if(this.PermissionAttributes != null)
  4915. {
  4916. permissions = this.InstantiatePermissionAttributes();
  4917. }
  4918. else if(this.serializedPermissions != null)
  4919. {
  4920. permissions = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None);
  4921. permissions.FromXml(this.GetSecurityElement());
  4922. }
  4923. this.permissions = permissions;
  4924. }
  4925. }
  4926. return this.permissions;
  4927. }
  4928. set
  4929. {
  4930. this.permissions = value;
  4931. }
  4932. }
  4933. protected System.Security.SecurityElement GetSecurityElement()
  4934. {
  4935. return System.Security.SecurityElement.FromString(this.serializedPermissions);
  4936. }
  4937. protected System.Security.PermissionSet InstantiatePermissionAttributes()
  4938. {
  4939. System.Security.PermissionSet permissions = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None);
  4940. AttributeList permissionAttributes = this.PermissionAttributes;
  4941. for(int i = 0, n = permissionAttributes == null ? 0 : permissionAttributes.Count; i < n; i++)
  4942. {
  4943. //^ assert permissionAttributes != null;
  4944. object result = this.GetPermissionOrSetOfPermissionsFromAttribute(permissionAttributes[i]);
  4945. if(result == null)
  4946. continue;
  4947. if(result is System.Security.PermissionSet)
  4948. permissions = permissions.Union((System.Security.PermissionSet)result);
  4949. else
  4950. {
  4951. System.Security.IPermission permission = result as System.Security.IPermission;
  4952. if(permission == null)
  4953. continue;
  4954. permissions.AddPermission(permission);
  4955. }
  4956. }
  4957. return permissions;
  4958. }
  4959. protected object GetPermissionOrSetOfPermissionsFromAttribute(AttributeNode attr)
  4960. {
  4961. if(attr == null)
  4962. return null;
  4963. System.Security.Permissions.SecurityAttribute secAttr = attr.GetRuntimeAttribute() as System.Security.Permissions.SecurityAttribute;
  4964. if(secAttr == null)
  4965. return null;
  4966. System.Security.Permissions.PermissionSetAttribute pSetAttr = secAttr as System.Security.Permissions.PermissionSetAttribute;
  4967. if(pSetAttr != null)
  4968. return pSetAttr.CreatePermissionSet();
  4969. else
  4970. return this.CreatePermission(secAttr);
  4971. }
  4972. private System.Security.IPermission CreatePermission(System.Security.Permissions.SecurityAttribute/*!*/ secAttr)
  4973. {
  4974. //This could execute partially trusted code, so set up a very restrictive execution environment
  4975. System.Security.PermissionSet perm = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None);
  4976. //TODO: add permissions if the attribute is from a trusted assembly
  4977. perm.PermitOnly();
  4978. try
  4979. {
  4980. return secAttr.CreatePermission();
  4981. }
  4982. catch { }
  4983. return null;
  4984. }
  4985. }
  4986. public struct Resource
  4987. {
  4988. private bool isPublic;
  4989. private string name;
  4990. private Module definingModule;
  4991. private byte[] data;
  4992. public bool IsPublic
  4993. {
  4994. get { return this.isPublic; }
  4995. set { this.isPublic = value; }
  4996. }
  4997. public string Name
  4998. {
  4999. get { return this.name; }
  5000. set { this.name = value; }
  5001. }
  5002. public Module DefiningModule
  5003. {
  5004. get { return this.definingModule; }
  5005. set { this.definingModule = value; }
  5006. }
  5007. public byte[] Data
  5008. {
  5009. get { return this.data; }
  5010. set { this.data = value; }
  5011. }
  5012. }
  5013. public struct Win32Resource
  5014. {
  5015. private string typeName;
  5016. private int typeId;
  5017. private string name;
  5018. private int id;
  5019. private int languageId;
  5020. private int codePage;
  5021. private byte[] data;
  5022. public string TypeName
  5023. {
  5024. get { return this.typeName; }
  5025. set { this.typeName = value; }
  5026. }
  5027. public int TypeId
  5028. {
  5029. get { return this.typeId; }
  5030. set { this.typeId = value; }
  5031. }
  5032. public string Name
  5033. {
  5034. get { return this.name; }
  5035. set { this.name = value; }
  5036. }
  5037. public int Id
  5038. {
  5039. get { return this.id; }
  5040. set { this.id = value; }
  5041. }
  5042. public int LanguageId
  5043. {
  5044. get { return this.languageId; }
  5045. set { this.languageId = value; }
  5046. }
  5047. public int CodePage
  5048. {
  5049. get { return this.codePage; }
  5050. set { this.codePage = value; }
  5051. }
  5052. public byte[] Data
  5053. {
  5054. get { return this.data; }
  5055. set { this.data = value; }
  5056. }
  5057. }
  5058. public class Module : Node, IDisposable
  5059. {
  5060. internal Reader reader;
  5061. public delegate void TypeNodeListProvider(Module/*!*/ module);
  5062. protected TypeNodeListProvider provideTypeNodeList;
  5063. public delegate TypeNode TypeNodeProvider(Identifier/*!*/ @namespace, Identifier/*!*/ name);
  5064. protected TypeNodeProvider provideTypeNode;
  5065. protected TrivialHashtable namespaceTable = new TrivialHashtable();
  5066. protected NamespaceList namespaceList;
  5067. protected int savedTypesLength;
  5068. public delegate void CustomAttributeProvider(Module/*!*/ module);
  5069. protected CustomAttributeProvider provideCustomAttributes;
  5070. public delegate void ResourceProvider(Module/*!*/ module);
  5071. protected ResourceProvider provideResources;
  5072. public delegate AssemblyNode AssemblyReferenceResolver(AssemblyReference/*!*/ assemblyReference, Module/*!*/ referencingModule);
  5073. public event AssemblyReferenceResolver AssemblyReferenceResolution;
  5074. public event AssemblyReferenceResolver AssemblyReferenceResolutionAfterProbingFailed;
  5075. public delegate void PostAssemblyLoadProcessor(AssemblyNode loadedAssembly);
  5076. public event PostAssemblyLoadProcessor AfterAssemblyLoad;
  5077. public delegate XmlDocument DocumentationResolver(Module referencingModule);
  5078. public event DocumentationResolver DocumentationResolution = null;
  5079. public bool IsNormalized;
  5080. internal int FileAlignment = 512;
  5081. internal readonly static object GlobalLock = new object();
  5082. public Module() : base(NodeType.Module)
  5083. {
  5084. this.IsNormalized = false;
  5085. }
  5086. public Module(TypeNodeProvider provider, TypeNodeListProvider listProvider, CustomAttributeProvider provideCustomAttributes, ResourceProvider provideResources)
  5087. : base(NodeType.Module)
  5088. {
  5089. this.provideCustomAttributes = provideCustomAttributes;
  5090. this.provideResources = provideResources;
  5091. this.provideTypeNode = provider;
  5092. this.provideTypeNodeList = listProvider;
  5093. this.IsNormalized = true;
  5094. }
  5095. public virtual void Dispose()
  5096. {
  5097. if(this.reader != null)
  5098. this.reader.Dispose();
  5099. this.reader = null;
  5100. ModuleReferenceList mrefs = this.moduleReferences;
  5101. for(int i = 0, n = mrefs == null ? 0 : mrefs.Count; i < n; i++)
  5102. {
  5103. //^ assert mrefs != null;
  5104. ModuleReference mr = mrefs[i];
  5105. if(mr != null && mr.Module == null)
  5106. continue;
  5107. mr.Module.Dispose();
  5108. }
  5109. this.moduleReferences = null;
  5110. GC.SuppressFinalize(this);
  5111. }
  5112. private AssemblyReferenceList assemblyReferences;
  5113. public AssemblyReferenceList AssemblyReferences
  5114. {
  5115. get { return this.assemblyReferences; }
  5116. set { this.assemblyReferences = value; }
  5117. }
  5118. private AssemblyNode containingAssembly;
  5119. /// <summary>The assembly, if any, that includes this module in its ModuleReferences.</summary>
  5120. public AssemblyNode ContainingAssembly
  5121. {
  5122. get { return this.containingAssembly; }
  5123. set { this.containingAssembly = value; }
  5124. }
  5125. private string directory;
  5126. public string Directory
  5127. {
  5128. get { return this.directory; }
  5129. set { this.directory = value; }
  5130. }
  5131. private AssemblyHashAlgorithm hashAlgorithm = AssemblyHashAlgorithm.SHA1;
  5132. public AssemblyHashAlgorithm HashAlgorithm
  5133. {
  5134. get { return this.hashAlgorithm; }
  5135. set { this.hashAlgorithm = value; }
  5136. }
  5137. private byte[] hashValue;
  5138. public byte[] HashValue
  5139. {
  5140. get { return this.hashValue; }
  5141. set { this.hashValue = value; }
  5142. }
  5143. private ModuleKind kind;
  5144. /// <summary>An enumeration that indicates if the module is an executable, library or resource, and so on.</summary>
  5145. public ModuleKind Kind
  5146. {
  5147. get { return this.kind; }
  5148. set { this.kind = value; }
  5149. }
  5150. private string location;
  5151. /// <summary>The path of the file from which this module or assembly was loaded or will be stored in.</summary>
  5152. public string Location
  5153. {
  5154. get { return this.location; }
  5155. set { this.location = value; }
  5156. }
  5157. private System.Guid mvid;
  5158. public System.Guid Mvid
  5159. {
  5160. get { return this.mvid; }
  5161. set { this.mvid = value; }
  5162. }
  5163. private string targetRuntimeVersion;
  5164. /// <summary>Identifies the version of the CLR that is required to load this module or assembly.</summary>
  5165. public string TargetRuntimeVersion
  5166. {
  5167. get { return this.targetRuntimeVersion; }
  5168. set { this.targetRuntimeVersion = value; }
  5169. }
  5170. private int linkerMajorVersion = 6;
  5171. public int LinkerMajorVersion
  5172. {
  5173. get { return this.linkerMajorVersion; }
  5174. set { this.linkerMajorVersion = value; }
  5175. }
  5176. private int linkerMinorVersion;
  5177. public int LinkerMinorVersion
  5178. {
  5179. get { return this.linkerMinorVersion; }
  5180. set { this.linkerMinorVersion = value; }
  5181. }
  5182. private int metadataFormatMajorVersion;
  5183. public int MetadataFormatMajorVersion
  5184. {
  5185. get { return this.metadataFormatMajorVersion; }
  5186. set { this.metadataFormatMajorVersion = value; }
  5187. }
  5188. private int metadataFormatMinorVersion;
  5189. public int MetadataFormatMinorVersion
  5190. {
  5191. get { return this.metadataFormatMinorVersion; }
  5192. set { this.metadataFormatMinorVersion = value; }
  5193. }
  5194. private string name;
  5195. /// <summary>The name of the module or assembly. Includes the file extension if the module is not an assembly.</summary>
  5196. public string Name
  5197. {
  5198. get { return this.name; }
  5199. set { this.name = value; }
  5200. }
  5201. private PEKindFlags peKind = PEKindFlags.ILonly;
  5202. public PEKindFlags PEKind
  5203. {
  5204. get { return this.peKind; }
  5205. set { this.peKind = value; }
  5206. }
  5207. private bool trackDebugData;
  5208. public bool TrackDebugData
  5209. {
  5210. get { return this.trackDebugData; }
  5211. set { this.trackDebugData = value; }
  5212. }
  5213. private ArrayList metadataImportErrors;
  5214. /// <summary>
  5215. /// If any exceptions were encountered while reading in this module, they are recorded here. Since reading is lazy,
  5216. /// this list can grow dynamically during the use of a module.
  5217. /// </summary>
  5218. public ArrayList MetadataImportErrors
  5219. {
  5220. get { return this.metadataImportErrors; }
  5221. set { this.metadataImportErrors = value; }
  5222. }
  5223. protected AttributeList attributes;
  5224. /// <summary>
  5225. /// The attributes associated with this module or assembly. This corresponds to C# custom attributes with the assembly or module target specifier.
  5226. /// </summary>
  5227. public virtual AttributeList Attributes
  5228. {
  5229. get
  5230. {
  5231. if(this.attributes != null)
  5232. return this.attributes;
  5233. if(this.provideCustomAttributes != null)
  5234. {
  5235. lock(Module.GlobalLock)
  5236. {
  5237. if(this.attributes == null)
  5238. this.provideCustomAttributes(this);
  5239. }
  5240. }
  5241. else
  5242. this.attributes = new AttributeList();
  5243. return this.attributes;
  5244. }
  5245. set
  5246. {
  5247. this.attributes = value;
  5248. }
  5249. }
  5250. protected SecurityAttributeList securityAttributes;
  5251. /// <summary>
  5252. /// Declarative security for the module or assembly.
  5253. /// </summary>
  5254. public virtual SecurityAttributeList SecurityAttributes
  5255. {
  5256. get
  5257. {
  5258. if(this.securityAttributes != null)
  5259. return this.securityAttributes;
  5260. if(this.provideCustomAttributes != null)
  5261. {
  5262. AttributeList dummy = this.Attributes; //As a side effect, this.securityAttributes gets populated
  5263. if(dummy != null)
  5264. dummy = null;
  5265. }
  5266. else
  5267. this.securityAttributes = new SecurityAttributeList();
  5268. return this.securityAttributes;
  5269. }
  5270. set
  5271. {
  5272. this.securityAttributes = value;
  5273. }
  5274. }
  5275. /// <summary>The source code, if any, corresponding to the value in Documentation.</summary>
  5276. public Node DocumentationNode;
  5277. protected XmlDocument documentation;
  5278. /// <summary>An XML Document Object Model for a document containing all of the documentation comments applicable to members
  5279. /// defined in this module.</summary>
  5280. public virtual XmlDocument Documentation
  5281. {
  5282. get
  5283. {
  5284. XmlDocument documentation = this.documentation;
  5285. if(documentation != null)
  5286. return documentation;
  5287. if(this.DocumentationResolution != null)
  5288. documentation = this.documentation = this.DocumentationResolution(this);
  5289. if(documentation != null)
  5290. return documentation;
  5291. XmlDocument doc = null;
  5292. if(this.Directory != null && this.Name != null)
  5293. {
  5294. string fileName = this.Name + ".xml";
  5295. System.Globalization.CultureInfo cc = System.Globalization.CultureInfo.CurrentUICulture;
  5296. while(cc != null && cc != System.Globalization.CultureInfo.InvariantCulture)
  5297. {
  5298. doc = this.ProbeForXmlDocumentation(this.Directory, cc.Name, fileName);
  5299. if(doc != null)
  5300. break;
  5301. cc = cc.Parent;
  5302. }
  5303. if(doc == null)
  5304. doc = this.ProbeForXmlDocumentation(this.Directory, null, fileName);
  5305. }
  5306. if(doc == null)
  5307. doc = new XmlDocument();
  5308. return this.documentation = doc;
  5309. }
  5310. set
  5311. {
  5312. this.documentation = value;
  5313. }
  5314. }
  5315. public virtual XmlDocument ProbeForXmlDocumentation(string dir, string subDir, string fileName)
  5316. {
  5317. try
  5318. {
  5319. if(dir == null || fileName == null)
  5320. return null;
  5321. if(subDir != null)
  5322. dir = Path.Combine(dir, subDir);
  5323. string docFileName = Path.Combine(dir, fileName);
  5324. if(File.Exists(docFileName))
  5325. {
  5326. XmlDocument doc = new XmlDocument();
  5327. using(TextReader reader = File.OpenText(docFileName))
  5328. {
  5329. doc.Load(reader);
  5330. return doc;
  5331. }
  5332. }
  5333. }
  5334. catch(Exception e)
  5335. {
  5336. if(this.MetadataImportErrors == null)
  5337. this.MetadataImportErrors = new ArrayList();
  5338. this.MetadataImportErrors.Add(e);
  5339. }
  5340. return null;
  5341. }
  5342. protected internal static readonly Method NoSuchMethod = new Method();
  5343. protected Method entryPoint;
  5344. /// <summary>If this module is an executable, this method is the one that gets called to start the execution of managed code.</summary>
  5345. public virtual Method EntryPoint
  5346. {
  5347. get
  5348. {
  5349. if(this.entryPoint == null)
  5350. {
  5351. if(this.provideCustomAttributes != null)
  5352. {
  5353. AttributeList dummy = this.Attributes; //Gets the entry point as a side effect
  5354. if(dummy != null)
  5355. dummy = null;
  5356. }
  5357. else
  5358. this.entryPoint = Module.NoSuchMethod;
  5359. }
  5360. if(this.entryPoint == Module.NoSuchMethod)
  5361. return null;
  5362. return this.entryPoint;
  5363. }
  5364. set
  5365. {
  5366. this.entryPoint = value;
  5367. }
  5368. }
  5369. protected ModuleReferenceList moduleReferences;
  5370. /// <summary>The list of modules (excluding assemblies) defining members that are referred to in this module or assembly.</summary>
  5371. public ModuleReferenceList ModuleReferences
  5372. {
  5373. get
  5374. {
  5375. //Populating the type list may cause module references to be added
  5376. if(this.Types == null)
  5377. return this.moduleReferences;
  5378. return this.moduleReferences;
  5379. }
  5380. set
  5381. {
  5382. this.moduleReferences = value;
  5383. }
  5384. }
  5385. public virtual bool ContainsModule(Module module)
  5386. {
  5387. if(module == null || this.ModuleReferences == null || this.ModuleReferences.Count == 0)
  5388. return false;
  5389. int n = this.ModuleReferences.Count;
  5390. for(int i = 0; i < n; ++i)
  5391. {
  5392. ModuleReference mr = this.ModuleReferences[i];
  5393. if(mr == null)
  5394. continue;
  5395. if(mr.Module == module)
  5396. return true;
  5397. }
  5398. return false;
  5399. }
  5400. protected ResourceList resources;
  5401. /// <summary>
  5402. /// A list of managed resources linked or embedded into this module or assembly.
  5403. /// </summary>
  5404. public virtual ResourceList Resources
  5405. {
  5406. get
  5407. {
  5408. if(this.resources != null)
  5409. return this.resources;
  5410. if(this.provideResources != null)
  5411. {
  5412. lock(Module.GlobalLock)
  5413. {
  5414. if(this.resources == null)
  5415. this.provideResources(this);
  5416. }
  5417. }
  5418. else
  5419. this.resources = new ResourceList();
  5420. return this.resources;
  5421. }
  5422. set
  5423. {
  5424. this.resources = value;
  5425. }
  5426. }
  5427. protected Win32ResourceList win32Resources;
  5428. /// <summary>
  5429. /// A list of Win32 resources embedded in this module or assembly.
  5430. /// </summary>
  5431. public virtual Win32ResourceList Win32Resources
  5432. {
  5433. get
  5434. {
  5435. if(this.win32Resources != null)
  5436. return this.win32Resources;
  5437. if(this.provideResources != null)
  5438. {
  5439. ResourceList dummy = this.Resources; //gets the win32 resources as as side effect
  5440. if(dummy != null)
  5441. dummy = null;
  5442. }
  5443. else
  5444. this.win32Resources = new Win32ResourceList();
  5445. return this.win32Resources;
  5446. }
  5447. set
  5448. {
  5449. this.win32Resources = value;
  5450. }
  5451. }
  5452. /// <summary>
  5453. /// Gets the first attribute of the given type in the custom attribute list of this module. Returns null if none found.
  5454. /// This should not be called until the module has been processed to replace symbolic references
  5455. /// to members with references to the actual members.
  5456. /// </summary>
  5457. public virtual AttributeNode GetAttribute(TypeNode attributeType)
  5458. {
  5459. AttributeList attributes = this.GetAttributes(attributeType, 1);
  5460. if(attributes != null && attributes.Count > 0)
  5461. return attributes[0];
  5462. return null;
  5463. }
  5464. public virtual AttributeList GetAttributes(TypeNode attributeType)
  5465. {
  5466. return GetAttributes(attributeType, Int32.MaxValue);
  5467. }
  5468. public virtual AttributeList GetAttributes(TypeNode attributeType, int maxCount)
  5469. {
  5470. AttributeList foundAttributes = new AttributeList();
  5471. if(attributeType == null)
  5472. return foundAttributes;
  5473. AttributeList attributes = this.Attributes;
  5474. for(int i = 0, count = 0, n = attributes == null ? 0 : attributes.Count; i < n && count < maxCount; i++)
  5475. {
  5476. AttributeNode attr = attributes[i];
  5477. if(attr == null)
  5478. continue;
  5479. MemberBinding mb = attr.Constructor as MemberBinding;
  5480. if(mb != null)
  5481. {
  5482. if(mb.BoundMember == null)
  5483. continue;
  5484. if(mb.BoundMember.DeclaringType != attributeType)
  5485. continue;
  5486. foundAttributes.Add(attr);
  5487. count++;
  5488. continue;
  5489. }
  5490. Literal lit = attr.Constructor as Literal;
  5491. if(lit == null)
  5492. continue;
  5493. if((lit.Value as TypeNode) != attributeType)
  5494. continue;
  5495. foundAttributes.Add(attr);
  5496. count++;
  5497. }
  5498. return foundAttributes;
  5499. }
  5500. protected TrivialHashtable memberDocumentationCache;
  5501. public TrivialHashtable GetMemberDocumentationCache()
  5502. {
  5503. TrivialHashtable cache = this.memberDocumentationCache;
  5504. if(cache != null)
  5505. return cache;
  5506. lock(this)
  5507. {
  5508. if(this.memberDocumentationCache != null)
  5509. return this.memberDocumentationCache;
  5510. XmlDocument doc = this.Documentation;
  5511. if(doc == null && this.ContainingAssembly != null && this.ContainingAssembly != this)
  5512. return this.memberDocumentationCache = this.ContainingAssembly.memberDocumentationCache;
  5513. cache = this.memberDocumentationCache = new TrivialHashtable();
  5514. if(doc == null)
  5515. return cache;
  5516. XmlNode docElem = doc.DocumentElement;
  5517. if(docElem == null)
  5518. return cache;
  5519. XmlNode membersNode = null;
  5520. if(docElem.HasChildNodes)
  5521. {
  5522. foreach(XmlNode dec in docElem.ChildNodes)
  5523. if(dec.Name == "members") { membersNode = dec; break; }
  5524. }
  5525. if(membersNode == null)
  5526. return cache;
  5527. if(membersNode.HasChildNodes)
  5528. {
  5529. foreach(XmlNode member in membersNode.ChildNodes)
  5530. {
  5531. if(member.Name != "member")
  5532. continue;
  5533. XmlNode nameAttr = member.Attributes.GetNamedItem("name");
  5534. if(nameAttr == null)
  5535. continue;
  5536. cache[Identifier.For(nameAttr.Value).UniqueIdKey] = member;
  5537. }
  5538. }
  5539. return cache;
  5540. }
  5541. }
  5542. protected TrivialHashtable validNamespaces;
  5543. public NamespaceList GetNamespaceList()
  5544. {
  5545. if(this.reader != null)
  5546. return this.GetNamespaceListFromReader();
  5547. TypeNodeList types = this.Types;
  5548. int n = types == null ? 0 : types.Count;
  5549. if(this.namespaceList == null || n > this.savedTypesLength)
  5550. {
  5551. lock(this)
  5552. {
  5553. if(this.namespaceList != null && this.types != null && this.types.Count == this.savedTypesLength)
  5554. return this.namespaceList;
  5555. NamespaceList nsList = this.namespaceList = new NamespaceList();
  5556. TrivialHashtable nsTable = this.validNamespaces = new TrivialHashtable();
  5557. for(int i = 0; i < n; i++)
  5558. {
  5559. //^ assert this.types != null;
  5560. TypeNode t = this.types[i];
  5561. if(t == null)
  5562. continue;
  5563. if(t.Namespace == null)
  5564. t.Namespace = Identifier.Empty;
  5565. Namespace ns = nsTable[t.Namespace.UniqueIdKey] as Namespace;
  5566. if(ns != null)
  5567. {
  5568. if(t.IsPublic)
  5569. ns.isPublic = true;
  5570. ns.Types.Add(t);
  5571. continue;
  5572. }
  5573. ns = new Namespace(t.Namespace);
  5574. ns.isPublic = t.IsPublic;
  5575. ns.Types = new TypeNodeList();
  5576. ns.Types.Add(t);
  5577. nsTable[t.Namespace.UniqueIdKey] = ns;
  5578. nsList.Add(ns);
  5579. }
  5580. }
  5581. }
  5582. return this.namespaceList;
  5583. }
  5584. private NamespaceList GetNamespaceListFromReader()
  5585. //^ requires this.reader != null;
  5586. {
  5587. if(this.namespaceList == null)
  5588. {
  5589. lock(Module.GlobalLock)
  5590. {
  5591. this.reader.GetNamespaces();
  5592. NamespaceList nsList = this.namespaceList = this.reader.namespaceList;
  5593. TrivialHashtable nsTable = this.validNamespaces = new TrivialHashtable();
  5594. for(int i = 0, n = nsList == null ? 0 : nsList.Count; i < n; i++)
  5595. {
  5596. //^ assert nsList != null;
  5597. Namespace ns = nsList[i];
  5598. if(ns == null || ns.Name == null)
  5599. continue;
  5600. ns.ProvideTypes = new Namespace.TypeProvider(this.GetTypesForNamespace);
  5601. nsTable[ns.Name.UniqueIdKey] = ns;
  5602. }
  5603. }
  5604. }
  5605. return this.namespaceList;
  5606. }
  5607. private void GetTypesForNamespace(Namespace nspace, object handle)
  5608. {
  5609. if(nspace == null || nspace.Name == null)
  5610. return;
  5611. lock(Module.GlobalLock)
  5612. {
  5613. int key = nspace.Name.UniqueIdKey;
  5614. TypeNodeList types = this.Types;
  5615. TypeNodeList nsTypes = nspace.Types = new TypeNodeList();
  5616. for(int i = 0, n = types == null ? 0 : types.Count; i < n; i++)
  5617. {
  5618. TypeNode t = types[i];
  5619. if(t == null || t.Namespace == null)
  5620. continue;
  5621. if(t.Namespace.UniqueIdKey == key)
  5622. nsTypes.Add(t);
  5623. }
  5624. }
  5625. }
  5626. public bool IsValidNamespace(Identifier nsName)
  5627. {
  5628. if(nsName == null)
  5629. return false;
  5630. this.GetNamespaceList();
  5631. //^ assert this.validNamespaces != null;
  5632. return this.validNamespaces[nsName.UniqueIdKey] != null;
  5633. }
  5634. public bool IsValidTypeName(Identifier nsName, Identifier typeName)
  5635. {
  5636. if(nsName == null || typeName == null)
  5637. return false;
  5638. if(!this.IsValidNamespace(nsName))
  5639. return false;
  5640. if(this.reader != null)
  5641. return this.reader.IsValidTypeName(nsName, typeName);
  5642. return this.GetType(nsName, typeName) != null;
  5643. }
  5644. public Module GetNestedModule(string moduleName)
  5645. {
  5646. if(this.Types == null) { Debug.Assert(false); } //Just get the types to pull in any exported types
  5647. ModuleReferenceList moduleReferences = this.ModuleReferences; //This should now contain all interesting referenced modules
  5648. for(int i = 0, n = moduleReferences == null ? 0 : moduleReferences.Count; i < n; i++)
  5649. {
  5650. ModuleReference mref = moduleReferences[i];
  5651. if(mref == null)
  5652. continue;
  5653. if(mref.Name == moduleName)
  5654. return mref.Module;
  5655. }
  5656. return null;
  5657. }
  5658. internal TrivialHashtableUsingWeakReferences/*!*/ StructurallyEquivalentType
  5659. {
  5660. get
  5661. {
  5662. if(this.structurallyEquivalentType == null)
  5663. this.structurallyEquivalentType = new TrivialHashtableUsingWeakReferences();
  5664. return this.structurallyEquivalentType;
  5665. }
  5666. }
  5667. private TrivialHashtableUsingWeakReferences structurallyEquivalentType;
  5668. /// <summary>
  5669. /// The identifier represents the structure via some mangling scheme. The result can be either from this module,
  5670. /// or any module this module has a reference to.
  5671. /// </summary>
  5672. public virtual TypeNode GetStructurallyEquivalentType(Identifier ns, Identifier/*!*/ id)
  5673. {
  5674. return this.GetStructurallyEquivalentType(ns, id, id, true);
  5675. }
  5676. public virtual TypeNode GetStructurallyEquivalentType(Identifier ns, Identifier/*!*/ id, Identifier uniqueMangledName, bool lookInReferencedAssemblies)
  5677. {
  5678. if(uniqueMangledName == null)
  5679. uniqueMangledName = id;
  5680. TypeNode result = (TypeNode)this.StructurallyEquivalentType[uniqueMangledName.UniqueIdKey];
  5681. if(result == Class.DoesNotExist)
  5682. return null;
  5683. if(result != null)
  5684. return result;
  5685. lock(Module.GlobalLock)
  5686. {
  5687. result = this.GetType(ns, id);
  5688. if(result != null)
  5689. {
  5690. this.StructurallyEquivalentType[uniqueMangledName.UniqueIdKey] = result;
  5691. return result;
  5692. }
  5693. if(!lookInReferencedAssemblies)
  5694. goto notfound;
  5695. AssemblyReferenceList refs = this.AssemblyReferences;
  5696. for(int i = 0, n = refs == null ? 0 : refs.Count; i < n; i++)
  5697. {
  5698. AssemblyReference ar = refs[i];
  5699. if(ar == null)
  5700. continue;
  5701. AssemblyNode a = ar.Assembly;
  5702. if(a == null)
  5703. continue;
  5704. result = a.GetType(ns, id);
  5705. if(result != null)
  5706. {
  5707. this.StructurallyEquivalentType[uniqueMangledName.UniqueIdKey] = result;
  5708. return result;
  5709. }
  5710. }
  5711. notfound:
  5712. this.StructurallyEquivalentType[uniqueMangledName.UniqueIdKey] = Class.DoesNotExist;
  5713. return null;
  5714. }
  5715. }
  5716. public virtual TypeNode GetType(Identifier @namespace, Identifier name, bool lookInReferencedAssemblies)
  5717. {
  5718. return this.GetType(@namespace, name, lookInReferencedAssemblies, lookInReferencedAssemblies ? new TrivialHashtable() : null);
  5719. }
  5720. protected virtual TypeNode GetType(Identifier @namespace, Identifier name, bool lookInReferencedAssemblies, TrivialHashtable assembliesAlreadyVisited)
  5721. {
  5722. if(assembliesAlreadyVisited != null)
  5723. {
  5724. if(assembliesAlreadyVisited[this.UniqueKey] != null)
  5725. return null;
  5726. assembliesAlreadyVisited[this.UniqueKey] = this;
  5727. }
  5728. TypeNode result = this.GetType(@namespace, name);
  5729. if(result != null || !lookInReferencedAssemblies)
  5730. return result;
  5731. AssemblyReferenceList refs = this.AssemblyReferences;
  5732. for(int i = 0, n = refs == null ? 0 : refs.Count; i < n; i++)
  5733. {
  5734. AssemblyReference ar = refs[i];
  5735. if(ar == null)
  5736. continue;
  5737. AssemblyNode a = ar.Assembly;
  5738. if(a == null)
  5739. continue;
  5740. result = a.GetType(@namespace, name, true, assembliesAlreadyVisited);
  5741. if(result != null)
  5742. return result;
  5743. }
  5744. return null;
  5745. }
  5746. public virtual TypeNode GetType(Identifier @namespace, Identifier name)
  5747. {
  5748. if(@namespace == null || name == null)
  5749. return null;
  5750. TypeNode result = null;
  5751. if(this.namespaceTable == null)
  5752. this.namespaceTable = new TrivialHashtable();
  5753. TrivialHashtable nsTable = (TrivialHashtable)this.namespaceTable[@namespace.UniqueIdKey];
  5754. if(nsTable != null)
  5755. {
  5756. result = (TypeNode)nsTable[name.UniqueIdKey];
  5757. if(result == Class.DoesNotExist)
  5758. return null;
  5759. if(result != null)
  5760. return result;
  5761. }
  5762. else
  5763. {
  5764. lock(Module.GlobalLock)
  5765. {
  5766. nsTable = (TrivialHashtable)this.namespaceTable[@namespace.UniqueIdKey];
  5767. if(nsTable == null)
  5768. this.namespaceTable[@namespace.UniqueIdKey] = nsTable = new TrivialHashtable(32);
  5769. }
  5770. }
  5771. if(this.provideTypeNode != null)
  5772. {
  5773. lock(Module.GlobalLock)
  5774. {
  5775. result = (TypeNode)nsTable[name.UniqueIdKey];
  5776. if(result == Class.DoesNotExist)
  5777. return null;
  5778. if(result != null)
  5779. return result;
  5780. result = this.provideTypeNode(@namespace, name);
  5781. if(result != null)
  5782. {
  5783. nsTable[name.UniqueIdKey] = result;
  5784. return result;
  5785. }
  5786. // !EFW - Removed by ComponentOne
  5787. //nsTable[name.UniqueIdKey] = Class.DoesNotExist;
  5788. return null;
  5789. }
  5790. }
  5791. if(this.types != null && this.types.Count > this.savedTypesLength)
  5792. {
  5793. int n = this.savedTypesLength = this.types.Count;
  5794. for(int i = 0; i < n; i++)
  5795. {
  5796. TypeNode t = this.types[i];
  5797. if(t == null)
  5798. continue;
  5799. if(t.Namespace == null)
  5800. t.Namespace = Identifier.Empty;
  5801. nsTable = (TrivialHashtable)this.namespaceTable[t.Namespace.UniqueIdKey];
  5802. if(nsTable == null)
  5803. this.namespaceTable[t.Namespace.UniqueIdKey] = nsTable = new TrivialHashtable();
  5804. nsTable[t.Name.UniqueIdKey] = t;
  5805. }
  5806. return this.GetType(@namespace, name);
  5807. }
  5808. return null;
  5809. }
  5810. protected internal TypeNodeList types;
  5811. /// <summary>The types contained in this module or assembly.</summary>
  5812. public virtual TypeNodeList Types
  5813. {
  5814. get
  5815. {
  5816. if(this.types != null)
  5817. return this.types;
  5818. if(this.provideTypeNodeList != null)
  5819. {
  5820. lock(Module.GlobalLock)
  5821. {
  5822. if(this.types == null)
  5823. this.provideTypeNodeList(this);
  5824. }
  5825. }
  5826. else
  5827. this.types = new TypeNodeList();
  5828. return this.types;
  5829. }
  5830. set
  5831. {
  5832. this.types = value;
  5833. }
  5834. }
  5835. protected TrivialHashtable referencedModulesAndAssemblies;
  5836. public virtual bool HasReferenceTo(Module module)
  5837. {
  5838. if(module == null)
  5839. return false;
  5840. AssemblyNode assembly = module as AssemblyNode;
  5841. if(assembly != null)
  5842. {
  5843. AssemblyReferenceList arefs = this.AssemblyReferences;
  5844. for(int i = 0, n = arefs == null ? 0 : arefs.Count; i < n; i++)
  5845. {
  5846. AssemblyReference aref = arefs[i];
  5847. if(aref == null)
  5848. continue;
  5849. if(aref.Matches(assembly.Name, assembly.Version, assembly.Culture, assembly.PublicKeyToken))
  5850. return true;
  5851. }
  5852. }
  5853. if(this.ContainingAssembly != module.ContainingAssembly)
  5854. return false;
  5855. ModuleReferenceList mrefs = this.ModuleReferences;
  5856. for(int i = 0, n = mrefs == null ? 0 : mrefs.Count; i < n; i++)
  5857. {
  5858. //^ assert mrefs != null;
  5859. ModuleReference mref = mrefs[i];
  5860. if(mref == null || mref.Name == null)
  5861. continue;
  5862. if(0 == PlatformHelpers.StringCompareOrdinalIgnoreCase(mref.Name, module.Name))
  5863. return true;
  5864. }
  5865. return false;
  5866. }
  5867. internal void InitializeAssemblyReferenceResolution(Module referringModule)
  5868. {
  5869. if(this.AssemblyReferenceResolution == null && referringModule != null)
  5870. {
  5871. this.AssemblyReferenceResolution = referringModule.AssemblyReferenceResolution;
  5872. this.AssemblyReferenceResolutionAfterProbingFailed = referringModule.AssemblyReferenceResolutionAfterProbingFailed;
  5873. }
  5874. }
  5875. public static Module GetModule(byte[] buffer)
  5876. {
  5877. return Module.GetModule(buffer, null, false, false, true, false);
  5878. }
  5879. public static Module GetModule(byte[] buffer, IDictionary cache)
  5880. {
  5881. return Module.GetModule(buffer, null, false, false, false, false);
  5882. }
  5883. public static Module GetModule(byte[] buffer, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache)
  5884. {
  5885. return Module.GetModule(buffer, cache, doNotLockFile, getDebugInfo, useGlobalCache, false);
  5886. }
  5887. public static Module GetModule(byte[] buffer, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache, bool preserveShortBranches)
  5888. {
  5889. if(buffer == null)
  5890. return null;
  5891. return (new Reader(buffer, cache, doNotLockFile, getDebugInfo, useGlobalCache, false)).ReadModule();
  5892. }
  5893. public static Module GetModule(string location)
  5894. {
  5895. return Module.GetModule(location, null, false, false, true, false);
  5896. }
  5897. public static Module GetModule(string location, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache)
  5898. {
  5899. return Module.GetModule(location, null, doNotLockFile, getDebugInfo, useGlobalCache, false);
  5900. }
  5901. public static Module GetModule(string location, IDictionary cache)
  5902. {
  5903. return Module.GetModule(location, cache, false, false, false, false);
  5904. }
  5905. public static Module GetModule(string location, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache)
  5906. {
  5907. return Module.GetModule(location, cache, doNotLockFile, getDebugInfo, useGlobalCache, false);
  5908. }
  5909. public static Module GetModule(string location, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache, bool preserveShortBranches)
  5910. {
  5911. if(location == null)
  5912. return null;
  5913. return (new Reader(location, cache, doNotLockFile, getDebugInfo, useGlobalCache, preserveShortBranches)).ReadModule();
  5914. }
  5915. public virtual AssemblyNode Resolve(AssemblyReference assemblyReference)
  5916. {
  5917. if(this.AssemblyReferenceResolution == null)
  5918. return null;
  5919. return this.AssemblyReferenceResolution(assemblyReference, this);
  5920. }
  5921. public virtual AssemblyNode ResolveAfterProbingFailed(AssemblyReference assemblyReference)
  5922. {
  5923. if(this.AssemblyReferenceResolutionAfterProbingFailed == null)
  5924. return null;
  5925. return this.AssemblyReferenceResolutionAfterProbingFailed(assemblyReference, this);
  5926. }
  5927. public virtual void AfterAssemblyLoadProcessing()
  5928. {
  5929. if(this.AfterAssemblyLoad != null)
  5930. {
  5931. this.AfterAssemblyLoad(this as AssemblyNode);
  5932. }
  5933. }
  5934. public virtual void WriteDocumentation(System.IO.TextWriter doc)
  5935. {
  5936. if(this.documentation == null)
  5937. return;
  5938. XmlTextWriter xwriter = new XmlTextWriter(doc);
  5939. xwriter.Formatting = Formatting.Indented;
  5940. xwriter.Indentation = 2;
  5941. xwriter.WriteProcessingInstruction("xml", "version=\"1.0\"");
  5942. xwriter.WriteStartElement("doc");
  5943. AssemblyNode assem = this as AssemblyNode;
  5944. if(assem != null)
  5945. {
  5946. xwriter.WriteStartElement("assembly");
  5947. xwriter.WriteElementString("name", assem.Name);
  5948. xwriter.WriteEndElement();
  5949. }
  5950. xwriter.WriteStartElement("members");
  5951. TypeNodeList types = this.Types;
  5952. for(int i = 1, n = types == null ? 0 : types.Count; i < n; i++)
  5953. {
  5954. //^ assert types != null;
  5955. TypeNode t = types[i];
  5956. if(t == null)
  5957. continue;
  5958. t.WriteDocumentation(xwriter);
  5959. }
  5960. xwriter.WriteEndElement();
  5961. xwriter.WriteEndElement();
  5962. xwriter.Close();
  5963. }
  5964. }
  5965. // An assembly is a module with a strong name
  5966. public class AssemblyNode : Module
  5967. {
  5968. private static Hashtable CompiledAssemblies;// so we can find in-memory compiled assemblies later (contains weak references)
  5969. protected AssemblyNode contractAssembly;
  5970. /// <summary>A separate assembly that supplied the type and method contracts for this assembly.</summary>
  5971. public virtual AssemblyNode ContractAssembly
  5972. {
  5973. get
  5974. {
  5975. return this.contractAssembly;
  5976. }
  5977. set
  5978. {
  5979. if(this.contractAssembly != null)
  5980. {
  5981. Debug.Assert(false);
  5982. return;
  5983. }
  5984. this.contractAssembly = value;
  5985. if(value == null)
  5986. return;
  5987. #region Copy over any external references from the contract assembly to this one (if needed)
  5988. // These external references are needed only for the contract deserializer
  5989. AssemblyReferenceList ars = new AssemblyReferenceList();
  5990. AssemblyReferenceList contractReferences = value.AssemblyReferences;
  5991. // see if contractReferences[i] is already in the external references of "this"
  5992. for(int i = 0, n = contractReferences == null ? 0 : contractReferences.Count; i < n; i++)
  5993. {
  5994. //^ assert contractReferences != null;
  5995. AssemblyReference aref = contractReferences[i];
  5996. if(aref == null)
  5997. continue;
  5998. if(aref.Assembly != this)
  5999. { // don't copy the contract's external reference to "this"
  6000. int j = 0;
  6001. int m = this.AssemblyReferences == null ? 0 : this.AssemblyReferences.Count;
  6002. while(j < m)
  6003. {
  6004. if(aref.Assembly.Name != null &&
  6005. this.AssemblyReferences[j].Name != null &&
  6006. aref.Assembly.Name.Equals(this.AssemblyReferences[j].Name))
  6007. break;
  6008. j++;
  6009. }
  6010. if(j == m)
  6011. { // then it wasn't found in the list of the real references
  6012. ars.Add(contractReferences[i]);
  6013. }
  6014. }
  6015. }
  6016. if(this.AssemblyReferences == null)
  6017. this.AssemblyReferences = new AssemblyReferenceList(ars);
  6018. else
  6019. this.AssemblyReferences.AddRange(ars);
  6020. #endregion Copy over any external references from the contract assembly to this one (if needed)
  6021. TypeNodeList instantiatedTypes = null;
  6022. if(this.reader != null)
  6023. instantiatedTypes = this.reader.GetInstantiatedTypes();
  6024. if(instantiatedTypes != null)
  6025. for(int i = 0, n = instantiatedTypes.Count; i < n; i++)
  6026. {
  6027. TypeNode t = instantiatedTypes[i];
  6028. if(t == null)
  6029. continue;
  6030. if(t.members == null)
  6031. continue;
  6032. }
  6033. }
  6034. }
  6035. internal static readonly AssemblyNode/*!*/ Dummy = new AssemblyNode();
  6036. protected string strongName;
  6037. /// <summary>
  6038. /// A string containing the name, version, culture and key of this assembly, formatted as required by the CLR loader.
  6039. /// </summary>
  6040. public virtual string/*!*/ StrongName
  6041. {
  6042. get
  6043. {
  6044. if(this.strongName == null)
  6045. this.strongName = AssemblyNode.GetStrongName(this.Name, this.Version, this.Culture, this.PublicKeyOrToken, (this.Flags & AssemblyFlags.Retargetable) != 0);
  6046. return this.strongName;
  6047. }
  6048. }
  6049. [Obsolete("Please use GetAttribute(TypeNode attributeType)")]
  6050. public virtual AttributeNode GetAttributeByName(TypeNode attributeType)
  6051. {
  6052. if(attributeType == null)
  6053. return null;
  6054. AttributeList attributes = this.Attributes;
  6055. for(int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
  6056. {
  6057. //^ assert attributes != null;
  6058. AttributeNode attr = attributes[i];
  6059. if(attr == null)
  6060. continue;
  6061. MemberBinding mb = attr.Constructor as MemberBinding;
  6062. if(mb != null)
  6063. {
  6064. if(mb.BoundMember == null || mb.BoundMember.DeclaringType == null)
  6065. continue;
  6066. if(mb.BoundMember.DeclaringType.FullName != attributeType.FullName)
  6067. continue;
  6068. return attr;
  6069. }
  6070. }
  6071. return null;
  6072. }
  6073. /// <summary>
  6074. /// Gets the first attribute of the given type in the custom attribute list of this member. Returns null if none found.
  6075. /// The member is assumed to be either imported, or already in a form suitable for export.
  6076. /// </summary>
  6077. public virtual AttributeNode GetModuleAttribute(TypeNode attributeType)
  6078. {
  6079. if(attributeType == null)
  6080. return null;
  6081. AttributeList attributes = this.ModuleAttributes;
  6082. for(int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
  6083. {
  6084. //^ assert attributes != null;
  6085. AttributeNode attr = attributes[i];
  6086. if(attr == null)
  6087. continue;
  6088. MemberBinding mb = attr.Constructor as MemberBinding;
  6089. if(mb != null)
  6090. {
  6091. if(mb.BoundMember == null)
  6092. continue;
  6093. if(mb.BoundMember.DeclaringType != attributeType)
  6094. continue;
  6095. return attr;
  6096. }
  6097. Literal lit = attr.Constructor as Literal;
  6098. if(lit == null)
  6099. continue;
  6100. if((lit.Value as TypeNode) != attributeType)
  6101. continue;
  6102. return attr;
  6103. }
  6104. return null;
  6105. }
  6106. public AssemblyNode()
  6107. : base()
  6108. {
  6109. this.NodeType = NodeType.Assembly;
  6110. this.ContainingAssembly = this;
  6111. }
  6112. public AssemblyNode(TypeNodeProvider provider, TypeNodeListProvider listProvider,
  6113. CustomAttributeProvider provideCustomAttributes, ResourceProvider provideResources, string directory)
  6114. : base(provider, listProvider, provideCustomAttributes, provideResources)
  6115. {
  6116. this.Directory = directory;
  6117. this.NodeType = NodeType.Assembly;
  6118. this.ContainingAssembly = this;
  6119. }
  6120. public override void Dispose()
  6121. {
  6122. if(this.cachedRuntimeAssembly != null)
  6123. this.cachedRuntimeAssembly.Dispose();
  6124. this.cachedRuntimeAssembly = null;
  6125. lock(Reader.StaticAssemblyCache)
  6126. {
  6127. foreach(object key in new ArrayList(Reader.StaticAssemblyCache.Keys))
  6128. {
  6129. if(Reader.StaticAssemblyCache[key] == this)
  6130. Reader.StaticAssemblyCache.Remove(key);
  6131. }
  6132. AssemblyReference aRef = (AssemblyReference)TargetPlatform.AssemblyReferenceFor[Identifier.For(this.Name).UniqueIdKey];
  6133. if(aRef != null && aRef.Assembly == this)
  6134. {
  6135. aRef.Assembly = null;
  6136. //TODO: what about other static references to the assembly, such as SystemTypes.SystemXmlAssembly?
  6137. }
  6138. }
  6139. base.Dispose();
  6140. }
  6141. private string culture;
  6142. /// <summary>The target culture of any localized resources in this assembly.</summary>
  6143. public string Culture
  6144. {
  6145. get { return this.culture; }
  6146. set { this.culture = value; }
  6147. }
  6148. private AssemblyFlags flags;
  6149. /// <summary>An enumeration that identifies the what kind of assembly this is.</summary>
  6150. public AssemblyFlags Flags
  6151. {
  6152. get { return this.flags; }
  6153. set { this.flags = value; }
  6154. }
  6155. private string moduleName;
  6156. /// <summary>Attributes that specifically target a module rather an assembly.</summary>
  6157. public string ModuleName
  6158. { //An assembly can have a different name from the module.
  6159. get { return this.moduleName; }
  6160. set { this.moduleName = value; }
  6161. }
  6162. private byte[] publicKeyOrToken;
  6163. /// <summary>The public part of the key pair used to sign this assembly, or a hash of the public key.</summary>
  6164. public byte[] PublicKeyOrToken
  6165. {
  6166. get { return this.publicKeyOrToken; }
  6167. set { this.publicKeyOrToken = value; }
  6168. }
  6169. private System.Version version;
  6170. /// <summary>The version of this assembly.</summary>
  6171. public System.Version Version
  6172. {
  6173. get { return this.version; }
  6174. set { this.version = value; }
  6175. }
  6176. private DateTime fileLastWriteTimeUtc;
  6177. public DateTime FileLastWriteTimeUtc
  6178. {
  6179. get { return this.fileLastWriteTimeUtc; }
  6180. set { this.fileLastWriteTimeUtc = value; }
  6181. }
  6182. protected TypeNodeList exportedTypes;
  6183. /// <summary>
  6184. /// Public types defined in other modules making up this assembly and to which other assemblies may refer to.
  6185. /// </summary>
  6186. public virtual TypeNodeList ExportedTypes
  6187. {
  6188. get
  6189. {
  6190. if(this.exportedTypes != null)
  6191. return this.exportedTypes;
  6192. if(this.provideTypeNodeList != null)
  6193. {
  6194. TypeNodeList types = this.Types; //Gets the exported types as a side-effect
  6195. if(types != null)
  6196. types = null;
  6197. }
  6198. else
  6199. this.exportedTypes = new TypeNodeList();
  6200. return this.exportedTypes;
  6201. }
  6202. set
  6203. {
  6204. this.exportedTypes = value;
  6205. }
  6206. }
  6207. public bool GetDebugSymbols
  6208. {
  6209. get
  6210. {
  6211. if(this.reader == null)
  6212. return false;
  6213. return this.reader.getDebugSymbols;
  6214. }
  6215. set
  6216. {
  6217. if(this.reader == null)
  6218. return;
  6219. this.reader.getDebugSymbols = value;
  6220. }
  6221. }
  6222. public static AssemblyNode GetAssembly(byte[] buffer)
  6223. {
  6224. return AssemblyNode.GetAssembly(buffer, null, false, false, true, false);
  6225. }
  6226. public static AssemblyNode GetAssembly(byte[] buffer, IDictionary cache)
  6227. {
  6228. return AssemblyNode.GetAssembly(buffer, cache, false, false, false, false);
  6229. }
  6230. public static AssemblyNode GetAssembly(byte[] buffer, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache)
  6231. {
  6232. return AssemblyNode.GetAssembly(buffer, cache, doNotLockFile, getDebugInfo, useGlobalCache, false);
  6233. }
  6234. public static AssemblyNode GetAssembly(byte[] buffer, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache, bool preserveShortBranches)
  6235. {
  6236. if(buffer == null)
  6237. return null;
  6238. if(CoreSystemTypes.SystemAssembly == null)
  6239. Debug.Fail("");
  6240. return (new Reader(buffer, cache, doNotLockFile, getDebugInfo, useGlobalCache, preserveShortBranches)).ReadModule() as AssemblyNode;
  6241. }
  6242. public static AssemblyNode GetAssembly(string location)
  6243. {
  6244. return AssemblyNode.GetAssembly(location, null, false, false, true, false);
  6245. }
  6246. public static AssemblyNode GetAssembly(string location, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache)
  6247. {
  6248. return AssemblyNode.GetAssembly(location, null, doNotLockFile, getDebugInfo, useGlobalCache, false);
  6249. }
  6250. public static AssemblyNode GetAssembly(string location, IDictionary cache)
  6251. {
  6252. return AssemblyNode.GetAssembly(location, cache, false, false, false, false);
  6253. }
  6254. public static AssemblyNode GetAssembly(string location, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache)
  6255. {
  6256. return AssemblyNode.GetAssembly(location, cache, doNotLockFile, getDebugInfo, useGlobalCache, false);
  6257. }
  6258. public static AssemblyNode GetAssembly(string location, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache, bool preserveShortBranches)
  6259. {
  6260. if(location == null)
  6261. return null;
  6262. if(CoreSystemTypes.SystemAssembly == null)
  6263. Debug.Fail("");
  6264. return (new Reader(location, cache, doNotLockFile, getDebugInfo, useGlobalCache, preserveShortBranches)).ReadModule() as AssemblyNode;
  6265. }
  6266. public static AssemblyNode GetAssembly(AssemblyReference assemblyReference)
  6267. {
  6268. return AssemblyNode.GetAssembly(assemblyReference, null, false, false, true, false);
  6269. }
  6270. public static AssemblyNode GetAssembly(AssemblyReference assemblyReference, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache)
  6271. {
  6272. return AssemblyNode.GetAssembly(assemblyReference, null, doNotLockFile, getDebugInfo, useGlobalCache, false);
  6273. }
  6274. public static AssemblyNode GetAssembly(AssemblyReference assemblyReference, IDictionary cache)
  6275. {
  6276. return AssemblyNode.GetAssembly(assemblyReference, cache, false, false, false, false);
  6277. }
  6278. public static AssemblyNode GetAssembly(AssemblyReference assemblyReference, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache)
  6279. {
  6280. return AssemblyNode.GetAssembly(assemblyReference, cache, doNotLockFile, getDebugInfo, useGlobalCache, false);
  6281. }
  6282. public static AssemblyNode GetAssembly(AssemblyReference assemblyReference, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache, bool preserveShortBranches)
  6283. {
  6284. if(assemblyReference == null)
  6285. return null;
  6286. if(CoreSystemTypes.SystemAssembly == null)
  6287. Debug.Fail("");
  6288. Reader reader = new Reader(cache, doNotLockFile, getDebugInfo, useGlobalCache, preserveShortBranches);
  6289. return assemblyReference.Assembly = reader.GetAssemblyFromReference(assemblyReference);
  6290. }
  6291. public static AssemblyNode GetAssembly(System.Reflection.Assembly runtimeAssembly)
  6292. {
  6293. return AssemblyNode.GetAssembly(runtimeAssembly, null, false, true, false);
  6294. }
  6295. public static AssemblyNode GetAssembly(System.Reflection.Assembly runtimeAssembly, IDictionary cache)
  6296. {
  6297. return AssemblyNode.GetAssembly(runtimeAssembly, cache, false, false, false);
  6298. }
  6299. public static AssemblyNode GetAssembly(System.Reflection.Assembly runtimeAssembly, IDictionary cache, bool getDebugInfo, bool useGlobalCache)
  6300. {
  6301. return AssemblyNode.GetAssembly(runtimeAssembly, cache, getDebugInfo, useGlobalCache, false);
  6302. }
  6303. public static AssemblyNode GetAssembly(System.Reflection.Assembly runtimeAssembly, IDictionary cache, bool getDebugInfo, bool useGlobalCache, bool preserveShortBranches)
  6304. {
  6305. if(runtimeAssembly == null)
  6306. return null;
  6307. if(CoreSystemTypes.SystemAssembly == null)
  6308. Debug.Fail("");
  6309. if(runtimeAssembly.GetName().Name == "mscorlib")
  6310. {
  6311. return CoreSystemTypes.SystemAssembly;
  6312. }
  6313. if(AssemblyNode.CompiledAssemblies != null)
  6314. {
  6315. WeakReference weakRef = (WeakReference)AssemblyNode.CompiledAssemblies[runtimeAssembly];
  6316. if(weakRef != null)
  6317. {
  6318. AssemblyNode assem = (AssemblyNode)weakRef.Target;
  6319. if(assem == null)
  6320. AssemblyNode.CompiledAssemblies.Remove(runtimeAssembly); //Remove the dead WeakReference
  6321. return assem;
  6322. }
  6323. }
  6324. if(runtimeAssembly.Location != null && runtimeAssembly.Location.Length > 0)
  6325. return AssemblyNode.GetAssembly(runtimeAssembly.Location, cache, false, getDebugInfo, useGlobalCache, preserveShortBranches);
  6326. //Get here for in memory assemblies that were not loaded from a known AssemblyNode
  6327. //Need CLR support to handle such assemblies. For now return null.
  6328. return null;
  6329. }
  6330. public void SetupDebugReader(string pdbSearchPath)
  6331. {
  6332. if(this.reader == null) { Debug.Assert(false); return; }
  6333. this.reader.SetupDebugReader(this.Location, pdbSearchPath);
  6334. }
  6335. internal static string/*!*/ GetStrongName(string name, Version version, string culture, byte[] publicKey, bool retargetable)
  6336. {
  6337. if(version == null)
  6338. version = new Version();
  6339. StringBuilder result = new StringBuilder();
  6340. result.Append(name);
  6341. result.Append(", Version=");
  6342. result.Append(version.ToString());
  6343. result.Append(", Culture=");
  6344. result.Append(((culture == null || culture.Length == 0) ? "neutral" : culture));
  6345. result.Append(AssemblyNode.GetKeyString(publicKey));
  6346. if(retargetable)
  6347. result.Append(", Retargetable=Yes");
  6348. return result.ToString();
  6349. }
  6350. private System.Reflection.AssemblyName assemblyName;
  6351. public System.Reflection.AssemblyName GetAssemblyName()
  6352. {
  6353. if(this.assemblyName == null)
  6354. {
  6355. System.Reflection.AssemblyName aName = new System.Reflection.AssemblyName();
  6356. if(this.Location != null && this.Location != "unknown:location")
  6357. {
  6358. StringBuilder sb = new StringBuilder("file:///");
  6359. sb.Append(Path.GetFullPath(this.Location));
  6360. sb.Replace('\\', '/');
  6361. aName.CodeBase = sb.ToString();
  6362. }
  6363. aName.CultureInfo = new System.Globalization.CultureInfo(this.Culture);
  6364. if(this.PublicKeyOrToken != null && this.PublicKeyOrToken.Length > 8)
  6365. aName.Flags = System.Reflection.AssemblyNameFlags.PublicKey;
  6366. if((this.Flags & AssemblyFlags.Retargetable) != 0)
  6367. aName.Flags |= (System.Reflection.AssemblyNameFlags)AssemblyFlags.Retargetable;
  6368. aName.HashAlgorithm = (System.Configuration.Assemblies.AssemblyHashAlgorithm)this.HashAlgorithm;
  6369. if(this.PublicKeyOrToken != null && this.PublicKeyOrToken.Length > 0)
  6370. aName.SetPublicKey(this.PublicKeyOrToken);
  6371. else
  6372. aName.SetPublicKey(new byte[0]);
  6373. aName.Name = this.Name;
  6374. aName.Version = this.Version;
  6375. switch(this.Flags & AssemblyFlags.CompatibilityMask)
  6376. {
  6377. case AssemblyFlags.NonSideBySideCompatible:
  6378. aName.VersionCompatibility = System.Configuration.Assemblies.AssemblyVersionCompatibility.SameDomain;
  6379. break;
  6380. case AssemblyFlags.NonSideBySideProcess:
  6381. aName.VersionCompatibility = System.Configuration.Assemblies.AssemblyVersionCompatibility.SameProcess;
  6382. break;
  6383. case AssemblyFlags.NonSideBySideMachine:
  6384. aName.VersionCompatibility = System.Configuration.Assemblies.AssemblyVersionCompatibility.SameMachine;
  6385. break;
  6386. }
  6387. this.assemblyName = aName;
  6388. }
  6389. return this.assemblyName;
  6390. }
  6391. private sealed class CachedRuntimeAssembly : IDisposable
  6392. {
  6393. internal System.Reflection.Assembly Value;
  6394. internal CachedRuntimeAssembly(System.Reflection.Assembly assembly)
  6395. {
  6396. this.Value = assembly;
  6397. }
  6398. ~CachedRuntimeAssembly()
  6399. {
  6400. this.Dispose();
  6401. }
  6402. public void Dispose()
  6403. {
  6404. if(this.Value != null)
  6405. {
  6406. if(AssemblyNode.CompiledAssemblies != null)
  6407. AssemblyNode.CompiledAssemblies.Remove(this.Value);
  6408. }
  6409. this.Value = null;
  6410. GC.SuppressFinalize(this);
  6411. }
  6412. }
  6413. private CachedRuntimeAssembly cachedRuntimeAssembly;
  6414. public System.Reflection.Assembly GetRuntimeAssembly()
  6415. {
  6416. return this.GetRuntimeAssembly(null, null);
  6417. }
  6418. public System.Reflection.Assembly GetRuntimeAssembly(System.Security.Policy.Evidence evidence)
  6419. {
  6420. return this.GetRuntimeAssembly(evidence, null);
  6421. }
  6422. public System.Reflection.Assembly GetRuntimeAssembly(AppDomain targetAppDomain)
  6423. {
  6424. return this.GetRuntimeAssembly(null, targetAppDomain);
  6425. }
  6426. // TODO: Evidence is obsolete but I'm not sure if it can be removed yet as this can parse assemblies from
  6427. // prior framework versions that do use it so we'll just suppress the warning for now.
  6428. #pragma warning disable 0618
  6429. public System.Reflection.Assembly GetRuntimeAssembly(System.Security.Policy.Evidence evidence, AppDomain targetAppDomain)
  6430. {
  6431. System.Reflection.Assembly result = this.cachedRuntimeAssembly == null ? null : this.cachedRuntimeAssembly.Value;
  6432. if(result == null || evidence != null || targetAppDomain != null)
  6433. {
  6434. lock(this)
  6435. {
  6436. if(this.cachedRuntimeAssembly != null && evidence == null && targetAppDomain == null)
  6437. return this.cachedRuntimeAssembly.Value;
  6438. if(targetAppDomain == null)
  6439. targetAppDomain = AppDomain.CurrentDomain;
  6440. if(this.Location != null)
  6441. {
  6442. string name = this.StrongName;
  6443. System.Reflection.Assembly[] alreadyLoadedAssemblies = targetAppDomain.GetAssemblies();
  6444. if(alreadyLoadedAssemblies != null)
  6445. for(int i = 0, n = alreadyLoadedAssemblies.Length; i < n; i++)
  6446. {
  6447. System.Reflection.Assembly a = alreadyLoadedAssemblies[i];
  6448. if(a == null)
  6449. continue;
  6450. if(a.FullName == name)
  6451. {
  6452. result = a;
  6453. break;
  6454. }
  6455. }
  6456. if(result == null)
  6457. {
  6458. if(evidence != null)
  6459. result = targetAppDomain.Load(this.GetAssemblyName(), evidence);
  6460. else
  6461. result = targetAppDomain.Load(this.GetAssemblyName());
  6462. }
  6463. }
  6464. if(result != null && evidence == null && targetAppDomain == AppDomain.CurrentDomain)
  6465. {
  6466. this.AddCachedAssembly(result);
  6467. this.cachedRuntimeAssembly = new CachedRuntimeAssembly(result);
  6468. }
  6469. }
  6470. }
  6471. return result;
  6472. }
  6473. #pragma warning restore 0618
  6474. private void AddCachedAssembly(System.Reflection.Assembly/*!*/ runtimeAssembly)
  6475. {
  6476. if(AssemblyNode.CompiledAssemblies == null)
  6477. AssemblyNode.CompiledAssemblies = Hashtable.Synchronized(new Hashtable());
  6478. AssemblyNode.CompiledAssemblies[runtimeAssembly] = new WeakReference(this);
  6479. }
  6480. private static string GetKeyString(byte[] publicKey)
  6481. {
  6482. if(publicKey == null)
  6483. return null;
  6484. int n = publicKey.Length;
  6485. StringBuilder str;
  6486. if(n > 8)
  6487. {
  6488. System.Security.Cryptography.SHA1 sha1 = new System.Security.Cryptography.SHA1CryptoServiceProvider();
  6489. publicKey = sha1.ComputeHash(publicKey);
  6490. byte[] token = new byte[8];
  6491. for(int i = 0, m = publicKey.Length - 1; i < 8; i++)
  6492. token[i] = publicKey[m - i];
  6493. publicKey = token;
  6494. n = 8;
  6495. }
  6496. if(n == 0)
  6497. str = new StringBuilder(", PublicKeyToken=null");
  6498. else
  6499. str = new StringBuilder(", PublicKeyToken=", n * 2 + 17);
  6500. for(int i = 0; i < n; i++)
  6501. str.Append(publicKey[i].ToString("x2"));
  6502. return str.ToString();
  6503. }
  6504. protected TrivialHashtable friends;
  6505. public virtual bool MayAccessInternalTypesOf(AssemblyNode assembly)
  6506. {
  6507. if(this == assembly)
  6508. return true;
  6509. if(assembly == null || SystemTypes.InternalsVisibleToAttribute == null)
  6510. return false;
  6511. if(this.friends == null)
  6512. this.friends = new TrivialHashtable();
  6513. object ob = this.friends[assembly.UniqueKey];
  6514. if(ob == (object)string.Empty)
  6515. return false;
  6516. if(ob == this)
  6517. return true;
  6518. AttributeList attributes = assembly.Attributes;
  6519. for(int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
  6520. {
  6521. //^ assert attributes != null;
  6522. AttributeNode attr = attributes[i];
  6523. if(attr == null)
  6524. continue;
  6525. MemberBinding mb = attr.Constructor as MemberBinding;
  6526. if(mb != null)
  6527. {
  6528. if(mb.BoundMember == null)
  6529. continue;
  6530. if(mb.BoundMember.DeclaringType != SystemTypes.InternalsVisibleToAttribute)
  6531. continue;
  6532. }
  6533. else
  6534. {
  6535. Literal lit = attr.Constructor as Literal;
  6536. if(lit == null)
  6537. continue;
  6538. if((lit.Value as TypeNode) != SystemTypes.InternalsVisibleToAttribute)
  6539. continue;
  6540. }
  6541. if(attr.Expressions == null || attr.Expressions.Count < 1)
  6542. continue;
  6543. Literal argLit = attr.Expressions[0] as Literal;
  6544. if(argLit == null)
  6545. continue;
  6546. string friendName = argLit.Value as string;
  6547. if(friendName == null)
  6548. continue;
  6549. try
  6550. {
  6551. AssemblyReference ar = new AssemblyReference(friendName);
  6552. byte[] tok = ar.PublicKeyToken;
  6553. if(tok != null && this.PublicKeyOrToken != null)
  6554. tok = this.PublicKeyToken;
  6555. if(!ar.Matches(this.Name, ar.Version, ar.Culture, tok))
  6556. continue;
  6557. }
  6558. catch(ArgumentException e)
  6559. {
  6560. if(this.MetadataImportErrors == null)
  6561. this.MetadataImportErrors = new ArrayList();
  6562. this.MetadataImportErrors.Add(e.Message);
  6563. continue;
  6564. }
  6565. this.friends[assembly.UniqueKey] = this;
  6566. return true;
  6567. }
  6568. this.friends[assembly.UniqueKey] = string.Empty;
  6569. return false;
  6570. }
  6571. public AssemblyReferenceList GetFriendAssemblies()
  6572. {
  6573. if(SystemTypes.InternalsVisibleToAttribute == null)
  6574. return null;
  6575. AttributeList attributes = this.Attributes;
  6576. if(attributes == null)
  6577. return null;
  6578. int n = attributes.Count;
  6579. if(n == 0)
  6580. return null;
  6581. AssemblyReferenceList result = new AssemblyReferenceList();
  6582. for(int i = 0; i < n; i++)
  6583. {
  6584. AttributeNode attr = attributes[i];
  6585. if(attr == null)
  6586. continue;
  6587. MemberBinding mb = attr.Constructor as MemberBinding;
  6588. if(mb != null)
  6589. {
  6590. if(mb.BoundMember == null)
  6591. continue;
  6592. if(mb.BoundMember.DeclaringType != SystemTypes.InternalsVisibleToAttribute)
  6593. continue;
  6594. }
  6595. else
  6596. {
  6597. Literal lit = attr.Constructor as Literal;
  6598. if(lit == null)
  6599. continue;
  6600. if((lit.Value as TypeNode) != SystemTypes.InternalsVisibleToAttribute)
  6601. continue;
  6602. }
  6603. if(attr.Expressions == null || attr.Expressions.Count < 1)
  6604. continue;
  6605. Literal argLit = attr.Expressions[0] as Literal;
  6606. if(argLit == null)
  6607. continue;
  6608. string friendName = argLit.Value as string;
  6609. if(friendName == null)
  6610. continue;
  6611. result.Add(new AssemblyReference(friendName));
  6612. }
  6613. return result;
  6614. }
  6615. /// <summary>
  6616. /// The attributes associated with this module. This corresponds to C# custom attributes with the module target specifier.
  6617. /// </summary>
  6618. public virtual AttributeList ModuleAttributes
  6619. {
  6620. get
  6621. {
  6622. if(this.moduleAttributes != null)
  6623. return this.moduleAttributes;
  6624. if(this.provideCustomAttributes != null)
  6625. {
  6626. lock(Module.GlobalLock)
  6627. {
  6628. if(this.moduleAttributes == null)
  6629. this.provideCustomAttributes(this);
  6630. }
  6631. }
  6632. else
  6633. this.moduleAttributes = new AttributeList();
  6634. return this.moduleAttributes;
  6635. }
  6636. set
  6637. {
  6638. this.moduleAttributes = value;
  6639. }
  6640. }
  6641. protected AttributeList moduleAttributes;
  6642. protected byte[] token;
  6643. public virtual byte[] PublicKeyToken
  6644. {
  6645. get
  6646. {
  6647. if(this.token != null)
  6648. return this.token;
  6649. if(this.PublicKeyOrToken == null || this.PublicKeyOrToken.Length == 0)
  6650. return null;
  6651. if(this.PublicKeyOrToken.Length == 8)
  6652. return this.token = this.PublicKeyOrToken;
  6653. System.Security.Cryptography.SHA1 sha1 = new System.Security.Cryptography.SHA1CryptoServiceProvider();
  6654. byte[] hashedKey = sha1.ComputeHash(this.PublicKeyOrToken);
  6655. byte[] token = new byte[8];
  6656. for(int i = 0, n = hashedKey.Length - 1; i < 8; i++)
  6657. token[i] = hashedKey[n - i];
  6658. return this.token = token;
  6659. }
  6660. }
  6661. public override string ToString()
  6662. {
  6663. return this.Name;
  6664. }
  6665. }
  6666. public class AssemblyReference : Node
  6667. {
  6668. private byte[] token;
  6669. internal Reader Reader;
  6670. public AssemblyReference() : base(NodeType.AssemblyReference)
  6671. {
  6672. }
  6673. public AssemblyReference(AssemblyNode/*!*/ assembly)
  6674. : base(NodeType.AssemblyReference)
  6675. {
  6676. this.culture = assembly.Culture;
  6677. this.flags = assembly.Flags & ~AssemblyFlags.PublicKey;
  6678. this.hashValue = assembly.HashValue;
  6679. this.name = assembly.Name;
  6680. this.publicKeyOrToken = assembly.PublicKeyOrToken;
  6681. if(assembly.PublicKeyOrToken != null && assembly.PublicKeyOrToken.Length > 8)
  6682. this.flags |= AssemblyFlags.PublicKey;
  6683. this.location = assembly.Location;
  6684. this.version = assembly.Version;
  6685. this.assembly = assembly;
  6686. }
  6687. public AssemblyReference(string assemblyStrongName, SourceContext sctx)
  6688. : this(assemblyStrongName)
  6689. {
  6690. this.SourceContext = sctx;
  6691. }
  6692. public AssemblyReference(string assemblyStrongName)
  6693. : base(NodeType.AssemblyReference)
  6694. {
  6695. AssemblyFlags flags = AssemblyFlags.None;
  6696. if(assemblyStrongName == null) { Debug.Assert(false); assemblyStrongName = ""; }
  6697. int i = 0, n = assemblyStrongName.Length;
  6698. string name = ParseToken(assemblyStrongName, ref i);
  6699. string version = null;
  6700. string culture = null;
  6701. string token = null;
  6702. while(i < n)
  6703. {
  6704. if(assemblyStrongName[i] != ',')
  6705. throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
  6706. ExceptionStrings.InvalidAssemblyStrongName, assemblyStrongName), "assemblyStrongName");
  6707. i++;
  6708. while(i < n && char.IsWhiteSpace(assemblyStrongName[i]))
  6709. i++;
  6710. switch(assemblyStrongName[i])
  6711. {
  6712. case 'v':
  6713. case 'V':
  6714. version = ParseAssignment(assemblyStrongName, "Version", ref i);
  6715. break;
  6716. case 'c':
  6717. case 'C':
  6718. culture = ParseAssignment(assemblyStrongName, "Culture", ref i);
  6719. break;
  6720. case 'p':
  6721. case 'P':
  6722. if(PlatformHelpers.StringCompareOrdinalIgnoreCase(assemblyStrongName, i, "PublicKeyToken", 0, "PublicKeyToken".Length) == 0)
  6723. token = ParseAssignment(assemblyStrongName, "PublicKeyToken", ref i);
  6724. else
  6725. {
  6726. token = ParseAssignment(assemblyStrongName, "PublicKey", ref i);
  6727. flags |= AssemblyFlags.PublicKey;
  6728. }
  6729. break;
  6730. case 'r':
  6731. case 'R':
  6732. string yesOrNo = ParseAssignment(assemblyStrongName, "Retargetable", ref i);
  6733. if(PlatformHelpers.StringCompareOrdinalIgnoreCase(yesOrNo, "Yes") == 0)
  6734. flags |= AssemblyFlags.Retargetable;
  6735. break;
  6736. }
  6737. while(i < n && assemblyStrongName[i] == ']')
  6738. i++;
  6739. }
  6740. while(i < n && char.IsWhiteSpace(assemblyStrongName[i]))
  6741. i++;
  6742. if(i < n)
  6743. throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
  6744. ExceptionStrings.InvalidAssemblyStrongName, assemblyStrongName), "assemblyStrongName");
  6745. if(PlatformHelpers.StringCompareOrdinalIgnoreCase(culture, "neutral") == 0)
  6746. culture = null;
  6747. if(PlatformHelpers.StringCompareOrdinalIgnoreCase(token, "null") == 0)
  6748. token = null;
  6749. byte[] tok = null;
  6750. if(token != null && (n = token.Length) > 0)
  6751. {
  6752. if(n > 16)
  6753. {
  6754. ArrayList tokArr = new ArrayList();
  6755. if(n % 2 == 1)
  6756. {
  6757. tokArr.Add(byte.Parse(token.Substring(0, 1), System.Globalization.NumberStyles.HexNumber, null));
  6758. n--;
  6759. }
  6760. for(i = 0; i < n; i += 2)
  6761. {
  6762. byte b = 0;
  6763. bool goodByte = byte.TryParse(token.Substring(i, 2), System.Globalization.NumberStyles.HexNumber, null, out b);
  6764. Debug.Assert(goodByte);
  6765. tokArr.Add(b);
  6766. }
  6767. tok = (byte[])tokArr.ToArray(typeof(byte));
  6768. }
  6769. else
  6770. {
  6771. ulong tk = ulong.Parse(token, System.Globalization.NumberStyles.HexNumber, null);
  6772. tok = new byte[8];
  6773. tok[0] = (byte)(tk >> 56);
  6774. tok[1] = (byte)(tk >> 48);
  6775. tok[2] = (byte)(tk >> 40);
  6776. tok[3] = (byte)(tk >> 32);
  6777. tok[4] = (byte)(tk >> 24);
  6778. tok[5] = (byte)(tk >> 16);
  6779. tok[6] = (byte)(tk >> 8);
  6780. tok[7] = (byte)tk;
  6781. }
  6782. }
  6783. this.culture = culture;
  6784. this.name = name;
  6785. this.publicKeyOrToken = tok;
  6786. this.version = version == null || version.Length == 0 ? null : new Version(version);
  6787. this.flags = flags;
  6788. }
  6789. private static string ParseToken(string/*!*/ assemblyStrongName, ref int i)
  6790. {
  6791. Debug.Assert(assemblyStrongName != null);
  6792. int n = assemblyStrongName.Length;
  6793. Debug.Assert(0 <= i && i < n);
  6794. while(i < n && char.IsWhiteSpace(assemblyStrongName[i]))
  6795. i++;
  6796. StringBuilder sb = new StringBuilder(n);
  6797. while(i < n)
  6798. {
  6799. char ch = assemblyStrongName[i];
  6800. if(ch == ',' || ch == ']' || char.IsWhiteSpace(ch))
  6801. break;
  6802. sb.Append(ch);
  6803. i++;
  6804. }
  6805. while(i < n && char.IsWhiteSpace(assemblyStrongName[i]))
  6806. i++;
  6807. return sb.ToString();
  6808. }
  6809. private static string ParseAssignment(string/*!*/ assemblyStrongName, string/*!*/ target, ref int i)
  6810. {
  6811. Debug.Assert(assemblyStrongName != null && target != null);
  6812. int n = assemblyStrongName.Length;
  6813. Debug.Assert(0 < i && i < n);
  6814. if(PlatformHelpers.StringCompareOrdinalIgnoreCase(assemblyStrongName, i, target, 0, target.Length) != 0)
  6815. goto throwError;
  6816. i += target.Length;
  6817. while(i < n && char.IsWhiteSpace(assemblyStrongName[i]))
  6818. i++;
  6819. if(i >= n || assemblyStrongName[i] != '=')
  6820. goto throwError;
  6821. i++;
  6822. if(i >= n)
  6823. goto throwError;
  6824. return ParseToken(assemblyStrongName, ref i);
  6825. throwError:
  6826. throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
  6827. ExceptionStrings.InvalidAssemblyStrongName, assemblyStrongName), "assemblyStrongName");
  6828. }
  6829. private string culture;
  6830. public string Culture
  6831. {
  6832. get { return this.culture; }
  6833. set { this.culture = value; }
  6834. }
  6835. private AssemblyFlags flags;
  6836. public AssemblyFlags Flags
  6837. {
  6838. get { return this.flags; }
  6839. set { this.flags = value; }
  6840. }
  6841. private byte[] hashValue;
  6842. public byte[] HashValue
  6843. {
  6844. get { return this.hashValue; }
  6845. set { this.hashValue = value; }
  6846. }
  6847. private string name;
  6848. public string Name
  6849. {
  6850. get { return this.name; }
  6851. set { this.name = value; }
  6852. }
  6853. private byte[] publicKeyOrToken;
  6854. public byte[] PublicKeyOrToken
  6855. {
  6856. get { return this.publicKeyOrToken; }
  6857. set { this.publicKeyOrToken = value; }
  6858. }
  6859. private System.Version version;
  6860. public System.Version Version
  6861. {
  6862. get { return this.version; }
  6863. set { this.version = value; }
  6864. }
  6865. private string location;
  6866. public string Location
  6867. {
  6868. get { return this.location; }
  6869. set { this.location = value; }
  6870. }
  6871. protected internal AssemblyNode assembly;
  6872. public virtual AssemblyNode Assembly
  6873. {
  6874. get
  6875. {
  6876. if(this.assembly != null)
  6877. return this.assembly;
  6878. if(this.Reader != null)
  6879. return this.assembly = this.Reader.GetAssemblyFromReference(this);
  6880. return null;
  6881. }
  6882. set
  6883. {
  6884. this.assembly = value;
  6885. }
  6886. }
  6887. protected string strongName;
  6888. public virtual string StrongName
  6889. {
  6890. get
  6891. {
  6892. if(this.strongName == null)
  6893. this.strongName = AssemblyNode.GetStrongName(this.Name, this.Version, this.Culture, this.PublicKeyOrToken, (this.Flags & AssemblyFlags.Retargetable) != 0);
  6894. return this.strongName;
  6895. }
  6896. }
  6897. private System.Reflection.AssemblyName assemblyName;
  6898. public System.Reflection.AssemblyName GetAssemblyName()
  6899. {
  6900. if(this.assemblyName == null)
  6901. {
  6902. System.Reflection.AssemblyName aName = new System.Reflection.AssemblyName();
  6903. aName.CultureInfo = new System.Globalization.CultureInfo(this.Culture == null ? "" : this.Culture);
  6904. if(this.PublicKeyOrToken != null && this.PublicKeyOrToken.Length > 8)
  6905. aName.Flags = System.Reflection.AssemblyNameFlags.PublicKey;
  6906. if((this.Flags & AssemblyFlags.Retargetable) != 0)
  6907. aName.Flags |= (System.Reflection.AssemblyNameFlags)AssemblyFlags.Retargetable;
  6908. aName.HashAlgorithm = System.Configuration.Assemblies.AssemblyHashAlgorithm.SHA1;
  6909. if(this.PublicKeyOrToken != null)
  6910. {
  6911. if(this.PublicKeyOrToken.Length > 8)
  6912. aName.SetPublicKey(this.PublicKeyOrToken);
  6913. else if(this.PublicKeyOrToken.Length > 0)
  6914. aName.SetPublicKeyToken(this.PublicKeyOrToken);
  6915. }
  6916. else
  6917. aName.SetPublicKey(new byte[0]);
  6918. aName.Name = this.Name;
  6919. aName.Version = this.Version;
  6920. switch(this.Flags & AssemblyFlags.CompatibilityMask)
  6921. {
  6922. case AssemblyFlags.NonSideBySideCompatible:
  6923. aName.VersionCompatibility = System.Configuration.Assemblies.AssemblyVersionCompatibility.SameDomain;
  6924. break;
  6925. case AssemblyFlags.NonSideBySideProcess:
  6926. aName.VersionCompatibility = System.Configuration.Assemblies.AssemblyVersionCompatibility.SameProcess;
  6927. break;
  6928. case AssemblyFlags.NonSideBySideMachine:
  6929. aName.VersionCompatibility = System.Configuration.Assemblies.AssemblyVersionCompatibility.SameMachine;
  6930. break;
  6931. }
  6932. this.assemblyName = aName;
  6933. }
  6934. return this.assemblyName;
  6935. }
  6936. public bool Matches(string name, Version version, string culture, byte[] publicKeyToken)
  6937. {
  6938. if(culture != null && culture.Length == 0)
  6939. culture = null;
  6940. if(this.Culture != null && this.Culture.Length == 0)
  6941. this.Culture = null;
  6942. if(this.Version != version && this.Version != null && (version == null || !this.Version.Equals(version)))
  6943. return false;
  6944. if(PlatformHelpers.StringCompareOrdinalIgnoreCase(this.Name, name) != 0 ||
  6945. PlatformHelpers.StringCompareOrdinalIgnoreCase(this.Culture, culture) != 0)
  6946. return false;
  6947. if((this.Flags & AssemblyFlags.Retargetable) != 0)
  6948. return true;
  6949. byte[] thisToken = this.PublicKeyToken;
  6950. if(publicKeyToken == null)
  6951. return thisToken == null;
  6952. if(thisToken == publicKeyToken)
  6953. return true;
  6954. if(thisToken == null)
  6955. return false;
  6956. int n = publicKeyToken.Length;
  6957. if(n != thisToken.Length)
  6958. return false;
  6959. for(int i = 0; i < n; i++) if(thisToken[i] != publicKeyToken[i])
  6960. return false;
  6961. return true;
  6962. }
  6963. public bool MatchesIgnoringVersion(AssemblyReference reference)
  6964. {
  6965. if(reference == null)
  6966. return false;
  6967. return this.Matches(reference.Name, this.Version, reference.Culture, reference.PublicKeyToken);
  6968. }
  6969. public byte[] PublicKeyToken
  6970. {
  6971. get
  6972. {
  6973. if(this.token != null)
  6974. return this.token;
  6975. if(this.PublicKeyOrToken == null || this.PublicKeyOrToken.Length == 0)
  6976. return null;
  6977. if(this.PublicKeyOrToken.Length == 8)
  6978. return this.token = this.PublicKeyOrToken;
  6979. System.Security.Cryptography.SHA1 sha = new System.Security.Cryptography.SHA1CryptoServiceProvider();
  6980. byte[] hashedKey = sha.ComputeHash(this.PublicKeyOrToken);
  6981. byte[] token = new byte[8];
  6982. for(int i = 0, n = hashedKey.Length - 1; i < 8; i++)
  6983. token[i] = hashedKey[n - i];
  6984. return this.token = token;
  6985. }
  6986. }
  6987. }
  6988. public class ModuleReference : Node
  6989. {
  6990. private Module module;
  6991. private string name;
  6992. public ModuleReference()
  6993. : base(NodeType.ModuleReference)
  6994. {
  6995. }
  6996. public ModuleReference(string name, Module module)
  6997. : base(NodeType.ModuleReference)
  6998. {
  6999. this.name = name;
  7000. this.module = module;
  7001. }
  7002. public Module Module
  7003. {
  7004. get { return this.module; }
  7005. set { this.module = value; }
  7006. }
  7007. public string Name
  7008. {
  7009. get { return this.name; }
  7010. set { this.name = value; }
  7011. }
  7012. }
  7013. /// <summary>
  7014. /// A member of a Namespace or a TypeNode
  7015. /// </summary>
  7016. public abstract class Member : Node
  7017. {
  7018. /// <summary>The namespace of which this node is a member. Null if this node is a member of type.</summary>
  7019. public Namespace DeclaringNamespace;
  7020. /// <summary>
  7021. /// Indicates that the signature of this member may include unsafe types such as pointers. For methods and properties, it also indicates that the
  7022. /// code may contain unsafe constructions such as pointer arithmetic.
  7023. /// </summary>
  7024. public bool IsUnsafe;
  7025. /// <summary>A list of other nodes that refer to this member. Must be filled in by client code.</summary>
  7026. public NodeList References;
  7027. protected Member(NodeType nodeType)
  7028. : base(nodeType)
  7029. {
  7030. }
  7031. protected Member(TypeNode declaringType, AttributeList attributes, Identifier name, NodeType nodeType)
  7032. : base(nodeType)
  7033. {
  7034. this.attributes = attributes;
  7035. this.declaringType = declaringType;
  7036. this.name = name;
  7037. }
  7038. private TypeNode declaringType;
  7039. /// <summary>The type of which this node is a member. Null if this node is a member of a Namespace.</summary>
  7040. public TypeNode DeclaringType
  7041. {
  7042. get { return this.declaringType; }
  7043. set { this.declaringType = value; }
  7044. }
  7045. private Identifier name;
  7046. /// <summary>The unqualified name of the member.</summary>
  7047. public Identifier Name
  7048. {
  7049. get { return this.name; }
  7050. set { this.name = value; }
  7051. }
  7052. protected AttributeList attributes;
  7053. private bool notObsolete;
  7054. private ObsoleteAttribute obsoleteAttribute;
  7055. /// <summary>
  7056. /// The attributes of this member. Corresponds to custom attribute annotations in C#.
  7057. /// </summary>
  7058. public virtual AttributeList Attributes
  7059. {
  7060. get
  7061. {
  7062. if(this.attributes != null)
  7063. return this.attributes;
  7064. return this.attributes = new AttributeList();
  7065. }
  7066. set
  7067. {
  7068. this.attributes = value;
  7069. }
  7070. }
  7071. protected Member hiddenMember;
  7072. public virtual Member HiddenMember
  7073. {
  7074. get
  7075. {
  7076. return this.hiddenMember;
  7077. }
  7078. set
  7079. {
  7080. this.hiddenMember = value;
  7081. }
  7082. }
  7083. protected bool hidesBaseClassMemberSpecifiedExplicitly;
  7084. protected bool hidesBaseClassMember;
  7085. /// <summary>Indicates if this is a member of a subclass that intentionally has the same signature as a member of a base class. Corresponds to the "new" modifier in C#.</summary>
  7086. public bool HidesBaseClassMember
  7087. {
  7088. get
  7089. {
  7090. if(this.hidesBaseClassMemberSpecifiedExplicitly)
  7091. return this.hidesBaseClassMember;
  7092. else
  7093. return this.HiddenMember != null;
  7094. }
  7095. set
  7096. {
  7097. this.hidesBaseClassMember = value;
  7098. this.hidesBaseClassMemberSpecifiedExplicitly = true;
  7099. }
  7100. }
  7101. protected Member overriddenMember;
  7102. public virtual Member OverriddenMember
  7103. {
  7104. get
  7105. {
  7106. return this.overriddenMember;
  7107. }
  7108. set
  7109. {
  7110. this.overriddenMember = value;
  7111. }
  7112. }
  7113. protected bool overridesBaseClassMemberSpecifiedExplicitly;
  7114. protected bool overridesBaseClassMember;
  7115. /// <summary>Indicates if this is a virtual method of a subclass that intentionally overrides a method of a base class. Corresponds to the "override" modifier in C#.</summary>
  7116. public virtual bool OverridesBaseClassMember
  7117. {
  7118. get
  7119. {
  7120. if(this.overridesBaseClassMemberSpecifiedExplicitly)
  7121. return this.overridesBaseClassMember;
  7122. else
  7123. return this.OverriddenMember != null;
  7124. }
  7125. set
  7126. {
  7127. this.overridesBaseClassMember = value;
  7128. this.overridesBaseClassMemberSpecifiedExplicitly = true;
  7129. }
  7130. }
  7131. /// <summary>
  7132. /// Gets the first attribute of the given type in the attribute list of this member. Returns null if none found.
  7133. /// This should not be called until the AST containing this member has been processed to replace symbolic references
  7134. /// to members with references to the actual members.
  7135. /// </summary>
  7136. public virtual AttributeNode GetAttribute(TypeNode attributeType)
  7137. {
  7138. if(attributeType == null)
  7139. return null;
  7140. AttributeList attributes = this.Attributes;
  7141. for(int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
  7142. {
  7143. AttributeNode attr = attributes[i];
  7144. if(attr == null)
  7145. continue;
  7146. MemberBinding mb = attr.Constructor as MemberBinding;
  7147. if(mb != null)
  7148. {
  7149. if(mb.BoundMember == null)
  7150. continue;
  7151. if(mb.BoundMember.DeclaringType != attributeType)
  7152. continue;
  7153. return attr;
  7154. }
  7155. Literal lit = attr.Constructor as Literal;
  7156. if(lit == null)
  7157. continue;
  7158. if((lit.Value as TypeNode) != attributeType)
  7159. continue;
  7160. return attr;
  7161. }
  7162. return null;
  7163. }
  7164. public virtual AttributeList GetFilteredAttributes(TypeNode attributeType)
  7165. {
  7166. if(attributeType == null)
  7167. return this.Attributes;
  7168. AttributeList attributes = this.Attributes;
  7169. AttributeList filtered = new AttributeList();
  7170. for(int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
  7171. {
  7172. AttributeNode attr = attributes[i];
  7173. if(attr == null)
  7174. continue;
  7175. MemberBinding mb = attr.Constructor as MemberBinding;
  7176. if(mb != null)
  7177. {
  7178. if(mb.BoundMember != null && mb.BoundMember.DeclaringType == attributeType)
  7179. continue;
  7180. filtered.Add(attr);
  7181. continue;
  7182. }
  7183. Literal lit = attr.Constructor as Literal;
  7184. if(lit != null && (lit.Value as TypeNode) == attributeType)
  7185. continue;
  7186. filtered.Add(attr);
  7187. }
  7188. return filtered;
  7189. }
  7190. /// <summary>
  7191. /// The concatenation of the FullName of the containing member and the name of this member.
  7192. /// Separated with a '.' character if the containing member is a namespace and a '+' character if the containing member is a Type.
  7193. /// Includes the parameter type full names when this member is a method or a property. Also includes (generic) template arguments.
  7194. /// </summary>
  7195. public abstract string/*!*/ FullName { get; }
  7196. /// <summary>True if all references to this member must be from the assembly containing the definition of this member. </summary>
  7197. public abstract bool IsAssembly { get; }
  7198. /// <summary>
  7199. /// True if access to this member is controlled by the compiler and not the runtime. Cannot be accessed from other assemblies since these
  7200. /// are not necessarily controlled by the same compiler.
  7201. /// </summary>
  7202. public abstract bool IsCompilerControlled { get; }
  7203. /// <summary>True if this member can only be accessed from subclasses of the class declaring this member.</summary>
  7204. public abstract bool IsFamily { get; }
  7205. /// <summary>True if this member can only be accessed from subclasses of the class declaring this member, provided that these subclasses are also
  7206. /// contained in the assembly containing this member.</summary>
  7207. public abstract bool IsFamilyAndAssembly { get; }
  7208. /// <summary>True if all references to this member must either be from the assembly containing the definition of this member,
  7209. /// or from a subclass of the class declaring this member.</summary>
  7210. public abstract bool IsFamilyOrAssembly { get; }
  7211. /// <summary>True if all references to this member must be from members of the type declaring this member./// </summary>
  7212. public abstract bool IsPrivate { get; }
  7213. /// <summary>True if the member can be accessed from anywhere./// </summary>
  7214. public abstract bool IsPublic { get; }
  7215. /// <summary>True if the name of this member conforms to a naming pattern with special meaning. For example the name of a property getter.</summary>
  7216. public abstract bool IsSpecialName { get; }
  7217. /// <summary>True if this member always has the same value or behavior for all instances the declaring type.</summary>
  7218. public abstract bool IsStatic { get; }
  7219. /// <summary>True if another assembly can contain a reference to this member.</summary>
  7220. public abstract bool IsVisibleOutsideAssembly { get; }
  7221. /// <summary>A cached reference to the first Obsolete attribute of this member. Null if no such attribute exists.</summary>
  7222. public ObsoleteAttribute ObsoleteAttribute
  7223. {
  7224. get
  7225. {
  7226. if(this.notObsolete)
  7227. return null;
  7228. if(this.obsoleteAttribute == null)
  7229. {
  7230. AttributeNode attr = this.GetAttribute(SystemTypes.ObsoleteAttribute);
  7231. if(attr != null)
  7232. {
  7233. ExpressionList args = attr.Expressions;
  7234. int numArgs = args == null ? 0 : args.Count;
  7235. Literal lit0 = numArgs > 0 ? args[0] as Literal : null;
  7236. Literal lit1 = numArgs > 1 ? args[1] as Literal : null;
  7237. string message = lit0 != null ? lit0.Value as string : null;
  7238. object isError = lit1 != null ? lit1.Value : null;
  7239. if(isError is bool)
  7240. return this.obsoleteAttribute = new ObsoleteAttribute(message, (bool)isError);
  7241. else
  7242. return this.obsoleteAttribute = new ObsoleteAttribute(message);
  7243. }
  7244. this.notObsolete = true;
  7245. }
  7246. return this.obsoleteAttribute;
  7247. }
  7248. set
  7249. {
  7250. this.obsoleteAttribute = value;
  7251. this.notObsolete = false;
  7252. }
  7253. }
  7254. /// <summary>The source code, if any, corresponding to the value in Documentation.</summary>
  7255. public Node DocumentationNode;
  7256. protected XmlNode documentation;
  7257. /// <summary>The body of an XML element containing a description of this member. Used to associated documentation (such as this comment) with members.
  7258. /// The fragment usually conforms to the structure defined in the C# standard.</summary>
  7259. public virtual XmlNode Documentation
  7260. {
  7261. get
  7262. {
  7263. XmlNode documentation = this.documentation;
  7264. if(documentation != null)
  7265. return documentation;
  7266. TypeNode t = this.DeclaringType;
  7267. if(t == null)
  7268. t = this as TypeNode;
  7269. Module m = t == null ? null : t.DeclaringModule;
  7270. TrivialHashtable cache = m == null ? null : m.GetMemberDocumentationCache();
  7271. if(cache == null)
  7272. return null;
  7273. return this.documentation = (XmlNode)cache[this.DocumentationId.UniqueIdKey];
  7274. }
  7275. set
  7276. {
  7277. this.documentation = value;
  7278. }
  7279. }
  7280. protected Identifier documentationId;
  7281. protected virtual Identifier GetDocumentationId()
  7282. {
  7283. return Identifier.Empty;
  7284. }
  7285. /// <summary>
  7286. /// The value of the name attribute of the XML element whose body is the XML fragment returned by Documentation.
  7287. /// </summary>
  7288. public Identifier DocumentationId
  7289. {
  7290. get
  7291. {
  7292. Identifier documentationId = this.documentationId;
  7293. if(documentationId != null)
  7294. return documentationId;
  7295. return this.DocumentationId = this.GetDocumentationId();
  7296. }
  7297. set
  7298. {
  7299. this.documentationId = value;
  7300. }
  7301. }
  7302. protected string helpText;
  7303. /// <summary>
  7304. /// The value of the summary child element of the XML fragment returned by Documentation. All markup is stripped from the value.
  7305. /// </summary>
  7306. public virtual string HelpText
  7307. {
  7308. get
  7309. {
  7310. string helpText = this.helpText;
  7311. if(helpText != null)
  7312. return helpText;
  7313. XmlNode documentation = this.Documentation;
  7314. if(documentation != null && documentation.HasChildNodes)
  7315. {
  7316. //^ assume documentation.ChildNodes != null;
  7317. foreach(XmlNode child in documentation.ChildNodes)
  7318. if(child.Name == "summary")
  7319. return this.helpText = this.GetHelpText(child);
  7320. }
  7321. return this.helpText = "";
  7322. }
  7323. set
  7324. {
  7325. this.helpText = value;
  7326. }
  7327. }
  7328. public virtual string GetParameterHelpText(string parameterName)
  7329. {
  7330. XmlNode documentation = this.Documentation;
  7331. if(documentation == null || documentation.ChildNodes == null)
  7332. return null;
  7333. foreach(XmlNode cdoc in documentation.ChildNodes)
  7334. {
  7335. if(cdoc == null)
  7336. continue;
  7337. if(cdoc.Name != "param")
  7338. continue;
  7339. if(cdoc.Attributes == null)
  7340. continue;
  7341. foreach(XmlAttribute attr in cdoc.Attributes)
  7342. {
  7343. if(attr == null || attr.Name != "name" || attr.Value != parameterName)
  7344. continue;
  7345. if(!cdoc.HasChildNodes)
  7346. continue;
  7347. return this.GetHelpText(cdoc);
  7348. }
  7349. }
  7350. return null;
  7351. }
  7352. private string GetHelpText(XmlNode node)
  7353. {
  7354. if(node == null)
  7355. return "";
  7356. StringBuilder sb = new StringBuilder();
  7357. if(node.HasChildNodes)
  7358. {
  7359. foreach(XmlNode child in node.ChildNodes)
  7360. {
  7361. switch(child.NodeType)
  7362. {
  7363. case XmlNodeType.Element:
  7364. string str = this.GetHelpText(child);
  7365. if(str == null || str.Length == 0)
  7366. continue;
  7367. if(sb.Length > 0 && !Char.IsPunctuation(str[0]))
  7368. sb.Append(' ');
  7369. sb.Append(str);
  7370. break;
  7371. case XmlNodeType.CDATA:
  7372. case XmlNodeType.Entity:
  7373. case XmlNodeType.Text:
  7374. this.AppendValue(sb, child);
  7375. break;
  7376. }
  7377. }
  7378. }
  7379. else if(node.Attributes != null)
  7380. {
  7381. foreach(XmlAttribute attr in node.Attributes)
  7382. {
  7383. this.AppendValue(sb, attr);
  7384. }
  7385. }
  7386. return sb.ToString();
  7387. }
  7388. private int filterPriority;
  7389. public virtual System.ComponentModel.EditorBrowsableState FilterPriority
  7390. {
  7391. get
  7392. {
  7393. if(this.filterPriority > 0)
  7394. return (System.ComponentModel.EditorBrowsableState)(this.filterPriority - 1);
  7395. int prio = 0;
  7396. XmlNode documentation = this.Documentation;
  7397. if(documentation != null && documentation.HasChildNodes)
  7398. {
  7399. foreach(XmlNode child in documentation.ChildNodes)
  7400. if(child.Name == "filterpriority")
  7401. {
  7402. PlatformHelpers.TryParseInt32(child.InnerText, out prio);
  7403. switch(prio)
  7404. {
  7405. case 2:
  7406. this.filterPriority = (int)System.ComponentModel.EditorBrowsableState.Advanced;
  7407. break;
  7408. case 3:
  7409. this.filterPriority = (int)System.ComponentModel.EditorBrowsableState.Never;
  7410. break;
  7411. default:
  7412. this.filterPriority = (int)System.ComponentModel.EditorBrowsableState.Always;
  7413. break;
  7414. }
  7415. this.filterPriority++;
  7416. return (System.ComponentModel.EditorBrowsableState)(this.filterPriority - 1);
  7417. }
  7418. }
  7419. AttributeList attributes = this.Attributes;
  7420. for(int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
  7421. {
  7422. //^ assert attributes != null;
  7423. AttributeNode attr = attributes[i];
  7424. if(attr == null || attr.Type == null)
  7425. continue;
  7426. if(attr.Expressions == null || attr.Expressions.Count < 1)
  7427. continue;
  7428. if(attr.Type.FullName != "System.ComponentModel.EditorBrowsableAttribute")
  7429. continue;
  7430. Literal lit = attr.Expressions[0] as Literal;
  7431. if(lit == null || !(lit.Value is int))
  7432. continue;
  7433. //^ assert lit.Value != null;
  7434. prio = (int)lit.Value;
  7435. return (System.ComponentModel.EditorBrowsableState)((this.filterPriority = prio + 1) - 1);
  7436. }
  7437. return (System.ComponentModel.EditorBrowsableState)((this.filterPriority = 1) - 1);
  7438. }
  7439. set
  7440. {
  7441. this.filterPriority = ((int)value) + 1;
  7442. }
  7443. }
  7444. /// <summary>
  7445. /// Writes out an element with tag "element", name attribute DocumentationId.ToString() and body Documentation using the provided XmlTextWriter instance.
  7446. /// </summary>
  7447. public virtual void WriteDocumentation(XmlTextWriter xwriter)
  7448. {
  7449. if(this.documentation == null || xwriter == null)
  7450. return;
  7451. xwriter.WriteStartElement("member");
  7452. if(this.DocumentationId == null)
  7453. return;
  7454. xwriter.WriteAttributeString("name", this.DocumentationId.ToString());
  7455. this.documentation.WriteContentTo(xwriter);
  7456. xwriter.WriteEndElement();
  7457. }
  7458. private readonly static char[]/*!*/ tags = { 'E', 'F', 'M', 'P', 'T' };
  7459. private void AppendValue(StringBuilder/*!*/ sb, XmlNode/*!*/ node)
  7460. {
  7461. string str = node.Value;
  7462. if(str != null)
  7463. {
  7464. str = str.Trim();
  7465. if(str.Length > 2 && str[1] == ':' && str.LastIndexOfAny(tags, 0, 1) == 0)
  7466. {
  7467. char tag = str[0];
  7468. str = str.Substring(2);
  7469. if(tag == 'T' && str.IndexOf(TargetPlatform.GenericTypeNamesMangleChar) >= 0)
  7470. {
  7471. Module mod = null;
  7472. if(this.DeclaringType != null)
  7473. mod = this.DeclaringType.DeclaringModule;
  7474. else if(this is TypeNode)
  7475. mod = ((TypeNode)this).DeclaringModule;
  7476. if(mod != null)
  7477. {
  7478. Identifier ns;
  7479. Identifier tn;
  7480. int i = str.LastIndexOf('.');
  7481. if(i < 0 || i >= str.Length)
  7482. {
  7483. ns = Identifier.Empty;
  7484. tn = Identifier.For(str);
  7485. }
  7486. else
  7487. {
  7488. ns = Identifier.For(str.Substring(0, i));
  7489. tn = Identifier.For(str.Substring(i + 1));
  7490. }
  7491. TypeNode t = mod.GetType(ns, tn, true);
  7492. if(t != null)
  7493. str = t.GetFullUnmangledNameWithTypeParameters();
  7494. }
  7495. }
  7496. }
  7497. if(str == null || str.Length == 0)
  7498. return;
  7499. bool lastCharWasSpace = false;
  7500. if(sb.Length > 0 && !Char.IsPunctuation(str[0]) && !Char.IsWhiteSpace(str[0]))
  7501. {
  7502. sb.Append(' ');
  7503. lastCharWasSpace = true;
  7504. }
  7505. foreach(char ch in str)
  7506. {
  7507. if(Char.IsWhiteSpace(ch))
  7508. {
  7509. if(lastCharWasSpace)
  7510. continue;
  7511. lastCharWasSpace = true;
  7512. sb.Append(' ');
  7513. }
  7514. else
  7515. {
  7516. lastCharWasSpace = false;
  7517. sb.Append(ch);
  7518. }
  7519. }
  7520. if(sb.Length > 0 && Char.IsWhiteSpace(sb[sb.Length - 1]))
  7521. sb.Length -= 1;
  7522. }
  7523. }
  7524. }
  7525. public class TypeMemberSnippet : Member
  7526. {
  7527. public IParserFactory ParserFactory;
  7528. public TypeMemberSnippet()
  7529. : base(NodeType.TypeMemberSnippet)
  7530. {
  7531. }
  7532. public TypeMemberSnippet(IParserFactory parserFactory, SourceContext sctx)
  7533. : base(NodeType.TypeMemberSnippet)
  7534. {
  7535. this.ParserFactory = parserFactory;
  7536. this.SourceContext = sctx;
  7537. }
  7538. public override string/*!*/ FullName
  7539. {
  7540. get { throw new InvalidOperationException(); }
  7541. }
  7542. public override bool IsCompilerControlled
  7543. {
  7544. get { throw new InvalidOperationException(); }
  7545. }
  7546. public override bool IsAssembly
  7547. {
  7548. get { throw new InvalidOperationException(); }
  7549. }
  7550. public override bool IsFamily
  7551. {
  7552. get { throw new InvalidOperationException(); }
  7553. }
  7554. public override bool IsFamilyAndAssembly
  7555. {
  7556. get { throw new InvalidOperationException(); }
  7557. }
  7558. public override bool IsFamilyOrAssembly
  7559. {
  7560. get { throw new InvalidOperationException(); }
  7561. }
  7562. public override bool IsPrivate
  7563. {
  7564. get { throw new InvalidOperationException(); }
  7565. }
  7566. public override bool IsPublic
  7567. {
  7568. get { throw new InvalidOperationException(); }
  7569. }
  7570. public override bool IsSpecialName
  7571. {
  7572. get { throw new InvalidOperationException(); }
  7573. }
  7574. public override bool IsStatic
  7575. {
  7576. get { throw new InvalidOperationException(); }
  7577. }
  7578. public override bool IsVisibleOutsideAssembly
  7579. {
  7580. get { throw new InvalidOperationException(); }
  7581. }
  7582. }
  7583. /// <summary>
  7584. /// The common base class for all types. This type should not be extended directly.
  7585. /// Instead extend one of the standard subclasses such as Class, Struct or Interface, since in
  7586. /// the CLR a type has to be an instance of one the subclasses, and a type which does not extend
  7587. /// one of these types will have no equivalent in the CLR.
  7588. /// </summary>
  7589. public abstract class TypeNode : Member
  7590. {
  7591. private int classSize;
  7592. /// <summary>Specifies the total size in bytes of instances of types with prescribed layout.</summary>
  7593. public int ClassSize
  7594. {
  7595. get { return this.classSize; }
  7596. set { this.classSize = value; }
  7597. }
  7598. private Module declaringModule;
  7599. /// <summary>The module or assembly to which the compiled type belongs.</summary>
  7600. public Module DeclaringModule
  7601. {
  7602. get { return this.declaringModule; }
  7603. set { this.declaringModule = value; }
  7604. }
  7605. private TypeFlags flags;
  7606. public TypeFlags Flags
  7607. {
  7608. get { return this.flags; }
  7609. set { this.flags = value; }
  7610. }
  7611. /// <summary>The interfaces implemented by this class or struct, or the extended by this interface.</summary>
  7612. public virtual InterfaceList Interfaces
  7613. {
  7614. get { return this.interfaces == null ? new InterfaceList() : this.interfaces; }
  7615. set { this.interfaces = value; }
  7616. }
  7617. protected InterfaceList interfaces;
  7618. public InterfaceList InterfaceExpressions;
  7619. private Identifier @namespace;
  7620. /// <summary>The namespace to which this type belongs. Null if the type is nested inside another type.</summary>
  7621. public Identifier Namespace
  7622. {
  7623. get { return this.@namespace; }
  7624. set { this.@namespace = value; }
  7625. }
  7626. private int packingSize;
  7627. /// <summary>Specifies the alignment of fields within types with prescribed layout.</summary>
  7628. public int PackingSize
  7629. {
  7630. get { return this.packingSize; }
  7631. set { this.packingSize = value; }
  7632. }
  7633. /// <summary>If this type is the combined result of a number of partial type definitions, this lists the partial definitions.</summary>
  7634. public TypeNodeList IsDefinedBy;
  7635. /// <summary>
  7636. /// True if this type is the result of a template instantiation with arguments that are themselves template parameters.
  7637. /// Used to model template instantiations occurring inside templates.
  7638. /// </summary>
  7639. public bool IsNotFullySpecialized;
  7640. public bool NewTemplateInstanceIsRecursive;
  7641. /// <summary>
  7642. /// If this type is a partial definition, the value of this is the combined type resulting from all the partial definitions.
  7643. /// </summary>
  7644. public TypeNode PartiallyDefines;
  7645. /// <summary>
  7646. /// The list of extensions of this type, if it's a non-extension type.
  7647. /// all extensions implement the IExtendTypeNode interface (in the Sing# code base).
  7648. /// null = empty list
  7649. /// </summary>
  7650. private TypeNodeList extensions = null;
  7651. /// <summary>
  7652. /// Whether or not the list of extensions has been examined;
  7653. /// it's a bug to record a new extension after extensions have been examined.
  7654. /// </summary>
  7655. private bool extensionsExamined = false;
  7656. /// <summary>
  7657. /// Record another extension of this type.
  7658. /// </summary>
  7659. /// <param name="extension"></param>
  7660. public void RecordExtension(TypeNode extension)
  7661. {
  7662. Debug.Assert(!extensionsExamined, "adding an extension after they've already been examined");
  7663. if(this.extensions == null)
  7664. this.extensions = new TypeNodeList();
  7665. this.extensions.Add(extension);
  7666. }
  7667. /// <summary>
  7668. /// The property that should be accessed by clients to get the list of extensions of this type.
  7669. /// </summary>
  7670. public TypeNodeList Extensions
  7671. {
  7672. get
  7673. {
  7674. this.extensionsExamined = true;
  7675. return this.extensions;
  7676. }
  7677. set
  7678. {
  7679. Debug.Assert(!extensionsExamined, "setting extensions after they've already been examined");
  7680. this.extensions = value;
  7681. }
  7682. }
  7683. /// <summary>
  7684. /// When duplicating a type node, we want to transfer the extensions and the extensionsExamined flag without
  7685. /// treating this as a "touch" that sets the examined flag. Pretty ugly, though.
  7686. /// </summary>
  7687. public TypeNodeList ExtensionsNoTouch
  7688. {
  7689. get { return this.extensions; }
  7690. }
  7691. /// <summary>
  7692. /// Copy a (possibly transformed) set of extensions from source to the
  7693. /// receiver, including whether or not the extensions have been examined.
  7694. /// </summary>
  7695. public void DuplicateExtensions(TypeNode source, TypeNodeList newExtensions)
  7696. {
  7697. if(source == null)
  7698. return;
  7699. this.extensions = newExtensions;
  7700. this.extensionsExamined = source.extensionsExamined;
  7701. }
  7702. /// <summary>
  7703. /// If the receiver is a type extension, return the extendee, otherwise return the receiver.
  7704. /// [The identity function, except for dialects (e.g. Extensible Sing#) that allow
  7705. /// extensions and differing views of types]
  7706. /// </summary>
  7707. public virtual TypeNode/*!*/ EffectiveTypeNode
  7708. {
  7709. get
  7710. {
  7711. return this;
  7712. }
  7713. }
  7714. /// <summary>
  7715. /// Return whether t1 represents the same type as t2 (or both are null).
  7716. /// This copes with the cases where t1 and/or t2 may be type views and/or type extensions, as
  7717. /// in Extensible Sing#.
  7718. /// </summary>
  7719. public static bool operator ==(TypeNode t1, TypeNode t2)
  7720. {
  7721. return
  7722. (object)t1 == null ?
  7723. (object)t2 == null :
  7724. (object)t2 != null && (object)t1.EffectiveTypeNode == (object)t2.EffectiveTypeNode;
  7725. }
  7726. // modify the other operations related to equality
  7727. public static bool operator !=(TypeNode t1, TypeNode t2)
  7728. {
  7729. return !(t1 == t2);
  7730. }
  7731. public override bool Equals(Object other)
  7732. {
  7733. return this == (other as TypeNode);
  7734. }
  7735. public override int GetHashCode()
  7736. {
  7737. TypeNode tn = this.EffectiveTypeNode;
  7738. if((object)tn == (object)this)
  7739. {
  7740. return base.GetHashCode();
  7741. }
  7742. else
  7743. {
  7744. return tn.GetHashCode();
  7745. }
  7746. }
  7747. /// <summary>
  7748. /// A delegate that is called the first time Members is accessed, if non-null.
  7749. /// Provides for incremental construction of the type node.
  7750. /// Must not leave Members null.
  7751. /// </summary>
  7752. public TypeMemberProvider ProvideTypeMembers;
  7753. /// <summary>
  7754. /// The type of delegates that fill in the Members property of the given type.
  7755. /// </summary>
  7756. public delegate void TypeMemberProvider(TypeNode/*!*/ type, object/*!*/ handle);
  7757. /// <summary>
  7758. /// A delegate that is called the first time NestedTypes is accessed, if non-null.
  7759. /// </summary>
  7760. public NestedTypeProvider ProvideNestedTypes;
  7761. /// <summary>
  7762. /// The type of delegates that fill in the NestedTypes property of the given type.
  7763. /// </summary>
  7764. public delegate void NestedTypeProvider(TypeNode/*!*/ type, object/*!*/ handle);
  7765. /// <summary>
  7766. /// A delegate that is called the first time Attributes is accessed, if non-null.
  7767. /// Provides for incremental construction of the type node.
  7768. /// Must not leave Attributes null.
  7769. /// </summary>
  7770. public TypeAttributeProvider ProvideTypeAttributes;
  7771. /// <summary>
  7772. /// The type of delegates that fill in the Attributes property of the given type.
  7773. /// </summary>
  7774. public delegate void TypeAttributeProvider(TypeNode/*!*/ type, object/*!*/ handle);
  7775. /// <summary>
  7776. /// Opaque information passed as a parameter to the delegates in ProvideTypeMembers et al.
  7777. /// Typically used to associate this namespace instance with a helper object.
  7778. /// </summary>
  7779. public object ProviderHandle;
  7780. private TypeNodeList templateInstances;
  7781. /// <summary>Contains all the types instantiated from this non generic template type.</summary>
  7782. public TypeNodeList TemplateInstances
  7783. {
  7784. get { return this.templateInstances; }
  7785. set { this.templateInstances = value; }
  7786. }
  7787. internal TypeNode(NodeType nodeType)
  7788. : base(nodeType)
  7789. {
  7790. }
  7791. internal TypeNode(NodeType nodeType, NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
  7792. : base(nodeType)
  7793. {
  7794. this.ProvideNestedTypes = provideNestedTypes;
  7795. this.ProvideTypeAttributes = provideAttributes;
  7796. this.ProvideTypeMembers = provideMembers;
  7797. this.ProviderHandle = handle;
  7798. this.isNormalized = true;
  7799. }
  7800. internal TypeNode(Module declaringModule, TypeNode declaringType, AttributeList attributes, TypeFlags flags,
  7801. Identifier Namespace, Identifier name, InterfaceList interfaces, MemberList members, NodeType nodeType)
  7802. : base(null, attributes, name, nodeType)
  7803. {
  7804. this.DeclaringModule = declaringModule;
  7805. this.DeclaringType = declaringType;
  7806. this.Flags = flags;
  7807. this.Interfaces = interfaces;
  7808. this.members = members;
  7809. this.Namespace = Namespace;
  7810. }
  7811. public override AttributeList Attributes
  7812. {
  7813. get
  7814. {
  7815. if(this.attributes == null)
  7816. {
  7817. if(this.ProvideTypeAttributes != null && this.ProviderHandle != null)
  7818. {
  7819. lock(Module.GlobalLock)
  7820. {
  7821. if(this.attributes == null)
  7822. {
  7823. // !EFW - Assign an empty list first. If not, it can get stuck in an
  7824. // endless loop if a type has an attribute with a type parameter that
  7825. // references the type being parsed. For example:
  7826. //
  7827. // [SomeAttribute(typeof(SomeClass<object>))]
  7828. // public class SomeClass<T> { }
  7829. //
  7830. this.attributes = new AttributeList();
  7831. this.ProvideTypeAttributes(this, this.ProviderHandle);
  7832. }
  7833. }
  7834. }
  7835. else
  7836. this.attributes = new AttributeList();
  7837. }
  7838. return this.attributes;
  7839. }
  7840. set
  7841. {
  7842. this.attributes = value;
  7843. }
  7844. }
  7845. protected SecurityAttributeList securityAttributes;
  7846. /// <summary>Contains declarative security information associated with the type.</summary>
  7847. public SecurityAttributeList SecurityAttributes
  7848. {
  7849. get
  7850. {
  7851. if(this.securityAttributes != null)
  7852. return this.securityAttributes;
  7853. if(this.attributes == null)
  7854. {
  7855. // Getting the type attributes also gets the security attributes in the case of a type that
  7856. // was read in by the Reader
  7857. AttributeList al = this.Attributes;
  7858. if(al != null)
  7859. al = null;
  7860. if(this.securityAttributes != null)
  7861. return this.securityAttributes;
  7862. }
  7863. return this.securityAttributes = new SecurityAttributeList();
  7864. }
  7865. set
  7866. {
  7867. this.securityAttributes = value;
  7868. }
  7869. }
  7870. /// <summary>The type from which this type is derived. Null in the case of interfaces and System.Object.</summary>
  7871. public virtual TypeNode BaseType
  7872. {
  7873. get
  7874. {
  7875. switch(this.NodeType)
  7876. {
  7877. case NodeType.ArrayType:
  7878. return CoreSystemTypes.Array;
  7879. case NodeType.ClassParameter:
  7880. case NodeType.Class:
  7881. return ((Class)this).BaseClass;
  7882. case NodeType.DelegateNode:
  7883. return CoreSystemTypes.MulticastDelegate;
  7884. case NodeType.EnumNode:
  7885. return CoreSystemTypes.Enum;
  7886. case NodeType.Struct:
  7887. case NodeType.TupleType:
  7888. case NodeType.TypeAlias:
  7889. case NodeType.TypeIntersection:
  7890. case NodeType.TypeUnion:
  7891. return CoreSystemTypes.ValueType;
  7892. default:
  7893. return null;
  7894. }
  7895. }
  7896. }
  7897. protected internal MemberList defaultMembers;
  7898. /// <summary>A list of any members of this type that have the DefaultMember attribute.</summary>
  7899. public virtual MemberList DefaultMembers
  7900. {
  7901. get
  7902. {
  7903. int n = this.Members.Count;
  7904. if(n != this.memberCount)
  7905. {
  7906. this.UpdateMemberTable(n);
  7907. this.defaultMembers = null;
  7908. }
  7909. if(this.defaultMembers == null)
  7910. {
  7911. AttributeList attrs = this.Attributes;
  7912. Identifier defMemName = null;
  7913. for(int j = 0, m = attrs == null ? 0 : attrs.Count; j < m; j++)
  7914. {
  7915. //^ assert attrs != null;
  7916. AttributeNode attr = attrs[j];
  7917. if(attr == null)
  7918. continue;
  7919. MemberBinding mb = attr.Constructor as MemberBinding;
  7920. if(mb != null && mb.BoundMember != null && mb.BoundMember.DeclaringType == SystemTypes.DefaultMemberAttribute)
  7921. {
  7922. if(attr.Expressions != null && attr.Expressions.Count > 0)
  7923. {
  7924. Literal lit = attr.Expressions[0] as Literal;
  7925. if(lit != null && lit.Value is string)
  7926. defMemName = Identifier.For((string)lit.Value);
  7927. }
  7928. break;
  7929. }
  7930. Literal litc = attr.Constructor as Literal;
  7931. if(litc != null && (litc.Value as TypeNode) == SystemTypes.DefaultMemberAttribute)
  7932. {
  7933. if(attr.Expressions != null && attr.Expressions.Count > 0)
  7934. {
  7935. Literal lit = attr.Expressions[0] as Literal;
  7936. if(lit != null && lit.Value is string)
  7937. defMemName = Identifier.For((string)lit.Value);
  7938. }
  7939. break;
  7940. }
  7941. }
  7942. if(defMemName != null)
  7943. this.defaultMembers = this.GetMembersNamed(defMemName);
  7944. else
  7945. this.defaultMembers = new MemberList();
  7946. }
  7947. return this.defaultMembers;
  7948. }
  7949. set
  7950. {
  7951. this.defaultMembers = value;
  7952. }
  7953. }
  7954. protected string fullName;
  7955. public override string/*!*/ FullName
  7956. {
  7957. get
  7958. {
  7959. if(this.fullName != null)
  7960. return this.fullName;
  7961. if(this.DeclaringType != null)
  7962. return this.fullName = this.DeclaringType.FullName + "+" + (this.Name == null ? "" : this.Name.ToString());
  7963. else if(this.Namespace != null && this.Namespace.UniqueIdKey != Identifier.Empty.UniqueIdKey)
  7964. return this.fullName = this.Namespace.ToString() + "." + (this.Name == null ? "" : this.Name.ToString());
  7965. else if(this.Name != null)
  7966. return this.fullName = this.Name.ToString();
  7967. else
  7968. return this.fullName = "";
  7969. }
  7970. }
  7971. // the same as FullName, except for dialects like Sing# with type extensions where names of
  7972. // type extensions may get mangled; in that case, this reports the name of the effective type node.
  7973. public virtual string FullNameDuringParsing
  7974. {
  7975. get { return this.FullName; }
  7976. }
  7977. public virtual string GetFullUnmangledNameWithoutTypeParameters()
  7978. {
  7979. if(this.DeclaringType != null)
  7980. return this.DeclaringType.GetFullUnmangledNameWithoutTypeParameters() + "+" + this.GetUnmangledNameWithoutTypeParameters();
  7981. else if(this.Namespace != null && this.Namespace.UniqueIdKey != Identifier.Empty.UniqueIdKey)
  7982. return this.Namespace.ToString() + "." + this.GetUnmangledNameWithoutTypeParameters();
  7983. else
  7984. return this.GetUnmangledNameWithoutTypeParameters();
  7985. }
  7986. public virtual string GetFullUnmangledNameWithTypeParameters()
  7987. {
  7988. if(this.DeclaringType != null)
  7989. return this.DeclaringType.GetFullUnmangledNameWithTypeParameters() + "+" + this.GetUnmangledNameWithTypeParameters(true);
  7990. else if(this.Namespace != null && this.Namespace.UniqueIdKey != Identifier.Empty.UniqueIdKey)
  7991. return this.Namespace.ToString() + "." + this.GetUnmangledNameWithTypeParameters(true);
  7992. else
  7993. return this.GetUnmangledNameWithTypeParameters(true);
  7994. }
  7995. public virtual string GetUnmangledNameWithTypeParameters()
  7996. {
  7997. return this.GetUnmangledNameWithTypeParameters(false);
  7998. }
  7999. private string GetUnmangledNameWithTypeParameters(bool fullNamesForTypeParameters)
  8000. {
  8001. StringBuilder sb = new StringBuilder(this.GetUnmangledNameWithoutTypeParameters());
  8002. TypeNodeList templateParameters = this.TemplateParameters;
  8003. if(this.Template != null)
  8004. templateParameters = this.TemplateArguments;
  8005. for(int i = 0, n = templateParameters == null ? 0 : templateParameters.Count; i < n; i++)
  8006. {
  8007. //^ assert templateParameters != null;
  8008. TypeNode tpar = templateParameters[i];
  8009. if(tpar == null)
  8010. continue;
  8011. if(i == 0)
  8012. sb.Append('<');
  8013. else
  8014. sb.Append(',');
  8015. if(tpar.Name != null)
  8016. if(fullNamesForTypeParameters)
  8017. sb.Append(tpar.GetFullUnmangledNameWithTypeParameters());
  8018. else
  8019. sb.Append(tpar.GetUnmangledNameWithTypeParameters());
  8020. if(i == n - 1)
  8021. sb.Append('>');
  8022. }
  8023. return sb.ToString();
  8024. }
  8025. public virtual string/*!*/ GetUnmangledNameWithoutTypeParameters()
  8026. {
  8027. char[] mangleChars = new[] { TargetPlatform.GenericTypeNamesMangleChar, '>' };
  8028. if(this.Template != null)
  8029. return this.Template.GetUnmangledNameWithoutTypeParameters();
  8030. if(this.Name == null)
  8031. return "";
  8032. string name = this.Name.ToString();
  8033. if(this.TemplateParameters != null && this.TemplateParameters.Count > 0)
  8034. {
  8035. int lastMangle = name.LastIndexOfAny(mangleChars);
  8036. if(lastMangle >= 0)
  8037. {
  8038. if(name[lastMangle] == '>')
  8039. lastMangle++;
  8040. return name.Substring(0, lastMangle);
  8041. }
  8042. }
  8043. return name;
  8044. }
  8045. public virtual string GetSerializedTypeName()
  8046. {
  8047. bool isAssemblyQualified = true;
  8048. return this.GetSerializedTypeName(this, ref isAssemblyQualified);
  8049. }
  8050. string GetSerializedTypeName(TypeNode/*!*/ type, ref bool isAssemblyQualified)
  8051. {
  8052. if(type == null)
  8053. return null;
  8054. StringBuilder sb = new StringBuilder();
  8055. TypeModifier tMod = type as TypeModifier;
  8056. if(tMod != null)
  8057. type = tMod.ModifiedType;
  8058. ArrayType arrType = type as ArrayType;
  8059. if(arrType != null)
  8060. {
  8061. type = arrType.ElementType;
  8062. bool isAssemQual = false;
  8063. this.AppendSerializedTypeName(sb, arrType.ElementType, ref isAssemQual);
  8064. if(arrType.IsSzArray())
  8065. sb.Append("[]");
  8066. else
  8067. {
  8068. sb.Append('[');
  8069. if(arrType.Rank == 1)
  8070. sb.Append('*');
  8071. for(int i = 1; i < arrType.Rank; i++)
  8072. sb.Append(',');
  8073. sb.Append(']');
  8074. }
  8075. goto done;
  8076. }
  8077. Pointer pointer = type as Pointer;
  8078. if(pointer != null)
  8079. {
  8080. type = pointer.ElementType;
  8081. bool isAssemQual = false;
  8082. this.AppendSerializedTypeName(sb, pointer.ElementType, ref isAssemQual);
  8083. sb.Append('*');
  8084. goto done;
  8085. }
  8086. Reference reference = type as Reference;
  8087. if(reference != null)
  8088. {
  8089. type = reference.ElementType;
  8090. bool isAssemQual = false;
  8091. this.AppendSerializedTypeName(sb, reference.ElementType, ref isAssemQual);
  8092. sb.Append('&');
  8093. goto done;
  8094. }
  8095. if(type.Template == null)
  8096. sb.Append(type.FullName);
  8097. else
  8098. {
  8099. sb.Append(type.Template.FullName);
  8100. sb.Append('[');
  8101. for(int i = 0, n = type.TemplateArguments == null ? 0 : type.TemplateArguments.Count; i < n; i++)
  8102. {
  8103. //^ assert type.TemplateArguments != null;
  8104. bool isAssemQual = true;
  8105. this.AppendSerializedTypeName(sb, type.TemplateArguments[i], ref isAssemQual);
  8106. if(i < n - 1)
  8107. sb.Append(',');
  8108. }
  8109. sb.Append(']');
  8110. }
  8111. done:
  8112. if(isAssemblyQualified)
  8113. this.AppendAssemblyQualifierIfNecessary(sb, type, out isAssemblyQualified);
  8114. return sb.ToString();
  8115. }
  8116. void AppendAssemblyQualifierIfNecessary(StringBuilder/*!*/ sb, TypeNode type, out bool isAssemQualified)
  8117. {
  8118. isAssemQualified = false;
  8119. if(type == null)
  8120. return;
  8121. AssemblyNode referencedAssembly = type.DeclaringModule as AssemblyNode;
  8122. if(referencedAssembly != null)
  8123. {
  8124. sb.Append(", ");
  8125. sb.Append(referencedAssembly.StrongName);
  8126. isAssemQualified = true;
  8127. }
  8128. }
  8129. void AppendSerializedTypeName(StringBuilder/*!*/ sb, TypeNode type, ref bool isAssemQualified)
  8130. {
  8131. if(type == null)
  8132. return;
  8133. string argTypeName = this.GetSerializedTypeName(type, ref isAssemQualified);
  8134. if(isAssemQualified)
  8135. sb.Append('[');
  8136. sb.Append(argTypeName);
  8137. if(isAssemQualified)
  8138. sb.Append(']');
  8139. }
  8140. /// <summary>
  8141. /// Return the name the constructor should have in this type node. By default, it's
  8142. /// the same as the name of the enclosing type node, but it can be different in e.g.
  8143. /// extensions in Extensible Sing#
  8144. /// </summary>
  8145. public virtual Identifier ConstructorName
  8146. {
  8147. get
  8148. {
  8149. if(this.constructorName == null)
  8150. {
  8151. Identifier id = this.Name;
  8152. if(this.IsNormalized && this.IsGeneric)
  8153. id = Identifier.For(this.GetUnmangledNameWithoutTypeParameters());
  8154. this.constructorName = id;
  8155. }
  8156. return this.constructorName;
  8157. }
  8158. }
  8159. private Identifier constructorName;
  8160. /// <summary>True if the type is an abstract class or an interface.</summary>
  8161. public virtual bool IsAbstract
  8162. {
  8163. get
  8164. {
  8165. return (this.Flags & TypeFlags.Abstract) != 0;
  8166. }
  8167. }
  8168. public override bool IsAssembly
  8169. {
  8170. get
  8171. {
  8172. TypeFlags visibility = this.Flags & TypeFlags.VisibilityMask;
  8173. return visibility == TypeFlags.NotPublic || visibility == TypeFlags.NestedAssembly;
  8174. }
  8175. }
  8176. public override bool IsCompilerControlled
  8177. {
  8178. get { return false; }
  8179. }
  8180. public override bool IsFamily
  8181. {
  8182. get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedFamily; }
  8183. }
  8184. public override bool IsFamilyAndAssembly
  8185. {
  8186. get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedFamANDAssem; }
  8187. }
  8188. public override bool IsFamilyOrAssembly
  8189. {
  8190. get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedFamORAssem; }
  8191. }
  8192. protected bool isGeneric;
  8193. /// <summary>True if this type is a template conforming to the rules of a generic type in the CLR.</summary>
  8194. public virtual bool IsGeneric
  8195. {
  8196. get
  8197. {
  8198. return this.isGeneric;
  8199. }
  8200. set
  8201. {
  8202. this.isGeneric = value;
  8203. }
  8204. }
  8205. public virtual bool IsNestedAssembly
  8206. {
  8207. get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedAssembly; }
  8208. }
  8209. public virtual bool IsNestedFamily
  8210. {
  8211. get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedFamily; }
  8212. }
  8213. public virtual bool IsNestedFamilyAndAssembly
  8214. {
  8215. get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedFamANDAssem; }
  8216. }
  8217. public virtual bool IsNestedInternal
  8218. {
  8219. get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedFamORAssem; }
  8220. }
  8221. public virtual bool IsNestedIn(TypeNode type)
  8222. {
  8223. for(TypeNode decType = this.DeclaringType; decType != null; decType = decType.DeclaringType)
  8224. {
  8225. if(decType == type)
  8226. return true;
  8227. }
  8228. return false;
  8229. }
  8230. public virtual bool IsNestedPublic
  8231. {
  8232. get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedPublic; }
  8233. }
  8234. public virtual bool IsNonPublic
  8235. {
  8236. get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NotPublic; }
  8237. }
  8238. protected bool isNormalized;
  8239. /// <summary>
  8240. /// True if the type node is in "normal" form. A node is in "normal" form if it is effectively a node in an AST formed directly
  8241. /// from CLR module or assembly. Such a node can be written out as compiled code to an assembly or module without further processing.
  8242. /// </summary>
  8243. public virtual bool IsNormalized
  8244. {
  8245. get
  8246. {
  8247. if(this.isNormalized)
  8248. return true;
  8249. if(this.DeclaringModule == null)
  8250. return false;
  8251. return this.isNormalized = this.DeclaringModule.IsNormalized;
  8252. }
  8253. set
  8254. {
  8255. this.isNormalized = value;
  8256. }
  8257. }
  8258. public override bool IsPrivate
  8259. {
  8260. get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedPrivate; }
  8261. }
  8262. /// <summary>True if values of this type can be compared directly in CLR IL instructions.</summary>
  8263. public virtual bool IsPrimitiveComparable
  8264. {
  8265. get
  8266. {
  8267. switch(this.typeCode)
  8268. {
  8269. case ElementType.Boolean:
  8270. case ElementType.Char:
  8271. case ElementType.Int8:
  8272. case ElementType.Int16:
  8273. case ElementType.Int32:
  8274. case ElementType.Int64:
  8275. case ElementType.IntPtr:
  8276. case ElementType.UInt8:
  8277. case ElementType.UInt16:
  8278. case ElementType.UInt32:
  8279. case ElementType.UInt64:
  8280. case ElementType.UIntPtr:
  8281. case ElementType.Single:
  8282. case ElementType.Double:
  8283. return true;
  8284. default:
  8285. return !(this is Struct) || this is EnumNode || this is Pointer;
  8286. }
  8287. }
  8288. }
  8289. /// <summary>True if values of this type are integers that can be processed by CLR IL instructions.</summary>
  8290. public virtual bool IsPrimitiveInteger
  8291. {
  8292. get
  8293. {
  8294. switch(this.typeCode)
  8295. {
  8296. case ElementType.Int8:
  8297. case ElementType.Int16:
  8298. case ElementType.Int32:
  8299. case ElementType.Int64:
  8300. case ElementType.IntPtr:
  8301. case ElementType.UInt8:
  8302. case ElementType.UInt16:
  8303. case ElementType.UInt32:
  8304. case ElementType.UInt64:
  8305. case ElementType.UIntPtr:
  8306. return true;
  8307. default:
  8308. return false;
  8309. }
  8310. }
  8311. }
  8312. /// <summary>True if values of this type are integers or floating point numbers that can be processed by CLR IL instructions.</summary>
  8313. public virtual bool IsPrimitiveNumeric
  8314. {
  8315. get
  8316. {
  8317. switch(this.typeCode)
  8318. {
  8319. case ElementType.Int8:
  8320. case ElementType.Int16:
  8321. case ElementType.Int32:
  8322. case ElementType.Int64:
  8323. case ElementType.IntPtr:
  8324. case ElementType.UInt8:
  8325. case ElementType.UInt16:
  8326. case ElementType.UInt32:
  8327. case ElementType.UInt64:
  8328. case ElementType.UIntPtr:
  8329. case ElementType.Single:
  8330. case ElementType.Double:
  8331. return true;
  8332. default:
  8333. return false;
  8334. }
  8335. }
  8336. }
  8337. /// <summary>True if values of this type are unsigned integers that can be processed by CLR IL instructions.</summary>
  8338. public virtual bool IsPrimitiveUnsignedInteger
  8339. {
  8340. get
  8341. {
  8342. switch(this.typeCode)
  8343. {
  8344. case ElementType.UInt8:
  8345. case ElementType.UInt16:
  8346. case ElementType.UInt32:
  8347. case ElementType.UInt64:
  8348. case ElementType.UIntPtr:
  8349. return true;
  8350. default:
  8351. return false;
  8352. }
  8353. }
  8354. }
  8355. public override bool IsPublic
  8356. {
  8357. get
  8358. {
  8359. TypeFlags visibility = this.Flags & TypeFlags.VisibilityMask;
  8360. return visibility == TypeFlags.Public || visibility == TypeFlags.NestedPublic;
  8361. }
  8362. }
  8363. /// <summary>True if values of this type can be processed by CLR IL instructions.</summary>
  8364. public virtual bool IsPrimitive
  8365. {
  8366. get
  8367. {
  8368. switch(this.typeCode)
  8369. {
  8370. case ElementType.Boolean:
  8371. case ElementType.Char:
  8372. case ElementType.Double:
  8373. case ElementType.Int16:
  8374. case ElementType.Int32:
  8375. case ElementType.Int64:
  8376. case ElementType.Int8:
  8377. case ElementType.IntPtr:
  8378. case ElementType.Single:
  8379. case ElementType.String:
  8380. case ElementType.UInt16:
  8381. case ElementType.UInt32:
  8382. case ElementType.UInt64:
  8383. case ElementType.UInt8:
  8384. case ElementType.UIntPtr:
  8385. return true;
  8386. default:
  8387. return false;
  8388. }
  8389. }
  8390. }
  8391. /// <summary>True if the type cannot be derived from.</summary>
  8392. public virtual bool IsSealed
  8393. {
  8394. get
  8395. {
  8396. return (this.Flags & TypeFlags.Sealed) != 0;
  8397. }
  8398. }
  8399. public override bool IsSpecialName
  8400. {
  8401. get { return (this.Flags & TypeFlags.SpecialName) != 0; }
  8402. }
  8403. public override bool IsStatic
  8404. {
  8405. get { return true; }
  8406. }
  8407. /// <summary>True if the identity of the type depends on its structure rather than its name.
  8408. /// Arrays, pointers and generic type instances are examples of such types.</summary>
  8409. public virtual bool IsStructural
  8410. {
  8411. get
  8412. {
  8413. return this.Template != null;
  8414. }
  8415. }
  8416. /// <summary>True if the type serves as a parameter to a type template.</summary>
  8417. public virtual bool IsTemplateParameter
  8418. {
  8419. get
  8420. {
  8421. return false;
  8422. }
  8423. }
  8424. /// <summary>True if the type is a value type containing only fields of unmanaged types.</summary>
  8425. public virtual bool IsUnmanaged
  8426. {
  8427. get
  8428. {
  8429. return false;
  8430. }
  8431. }
  8432. /// <summary>A list of the types that contribute to the structure of a structural type.</summary>
  8433. public virtual TypeNodeList StructuralElementTypes
  8434. {
  8435. get
  8436. {
  8437. TypeNodeList result = this.TemplateArguments;
  8438. if(result != null && result.Count > 0)
  8439. return result;
  8440. return this.TemplateParameters;
  8441. }
  8442. }
  8443. /// <summary>True if values of this type are unsigned integers that can be processed by CLR IL instructions.</summary>
  8444. public virtual bool IsUnsignedPrimitiveNumeric
  8445. {
  8446. get
  8447. {
  8448. switch(this.typeCode)
  8449. {
  8450. case ElementType.UInt8:
  8451. case ElementType.UInt16:
  8452. case ElementType.UInt32:
  8453. case ElementType.UInt64:
  8454. case ElementType.UIntPtr:
  8455. return true;
  8456. default:
  8457. return false;
  8458. }
  8459. }
  8460. }
  8461. /// <summary>True if instances of this type have no identity other than their value and are copied upon assignment.</summary>
  8462. public virtual bool IsValueType
  8463. {
  8464. get
  8465. {
  8466. switch(this.NodeType)
  8467. {
  8468. case NodeType.EnumNode:
  8469. case NodeType.ConstrainedType:
  8470. case NodeType.TupleType:
  8471. case NodeType.TypeAlias:
  8472. case NodeType.TypeIntersection:
  8473. case NodeType.TypeUnion:
  8474. return true;
  8475. case NodeType.Struct:
  8476. return true;
  8477. default:
  8478. return false;
  8479. }
  8480. }
  8481. }
  8482. /// <summary>
  8483. /// True if underlying type (modulo type modifiers) is a pointer type (Pointer)
  8484. /// </summary>
  8485. public virtual bool IsPointerType
  8486. {
  8487. get { return false; }
  8488. }
  8489. public override bool IsVisibleOutsideAssembly
  8490. {
  8491. get
  8492. {
  8493. if(this.DeclaringType != null && !this.DeclaringType.IsVisibleOutsideAssembly)
  8494. return false;
  8495. switch(this.Flags & TypeFlags.VisibilityMask)
  8496. {
  8497. case TypeFlags.Public:
  8498. case TypeFlags.NestedPublic:
  8499. return true;
  8500. case TypeFlags.NestedFamily:
  8501. case TypeFlags.NestedFamORAssem:
  8502. return this.DeclaringType != null && !this.DeclaringType.IsSealed;
  8503. default:
  8504. return false;
  8505. }
  8506. }
  8507. }
  8508. // This field stores those members declared syntactically within
  8509. // this type node. (Under Extended Sing#, additional members can
  8510. // be logically part of a type node but declared in a separate
  8511. // syntactic type node.)
  8512. protected internal MemberList members;
  8513. protected volatile internal bool membersBeingPopulated;
  8514. /// <summary>
  8515. /// The list of members contained inside this type, by default ignoring any extensions of this type.
  8516. /// (Subclasses in the Extensible Sing# dialect override this to include members of visible extensions.)
  8517. /// If the value of members is null and the value of ProvideTypeMembers is not null, the
  8518. /// TypeMemberProvider delegate is called to fill in the value of this property.
  8519. /// </summary>
  8520. public virtual MemberList Members
  8521. {
  8522. get
  8523. {
  8524. if(this.members == null || this.membersBeingPopulated)
  8525. if(this.ProvideTypeMembers != null && this.ProviderHandle != null)
  8526. {
  8527. lock(Module.GlobalLock)
  8528. {
  8529. if(this.members == null)
  8530. {
  8531. this.membersBeingPopulated = true;
  8532. this.ProvideTypeMembers(this, this.ProviderHandle);
  8533. this.membersBeingPopulated = false;
  8534. }
  8535. }
  8536. }
  8537. else
  8538. this.members = new MemberList();
  8539. return this.members;
  8540. }
  8541. set
  8542. {
  8543. this.members = value;
  8544. this.memberCount = 0;
  8545. this.memberTable = null;
  8546. this.constructors = null;
  8547. this.defaultMembers = null;
  8548. this.explicitCoercionFromTable = null;
  8549. this.explicitCoercionMethods = null;
  8550. this.explicitCoercionToTable = null;
  8551. this.implicitCoercionFromTable = null;
  8552. this.implicitCoercionMethods = null;
  8553. this.implicitCoercionToTable = null;
  8554. this.opFalse = null;
  8555. this.opTrue = null;
  8556. }
  8557. }
  8558. protected TypeNode template;
  8559. /// <summary>The (generic) type template from which this type was instantiated. Null if this is not a (generic) type template instance.</summary>
  8560. public virtual TypeNode Template
  8561. {
  8562. get
  8563. {
  8564. TypeNode result = this.template;
  8565. if(result == null)
  8566. {
  8567. if(this.isGeneric || TargetPlatform.GenericTypeNamesMangleChar != '_')
  8568. return null;
  8569. AttributeList attributes = this.Attributes;
  8570. lock(this)
  8571. {
  8572. if(this.template != null)
  8573. {
  8574. if(this.template == TypeNode.NotSpecified)
  8575. return null;
  8576. return this.template;
  8577. }
  8578. if(result == null)
  8579. this.template = TypeNode.NotSpecified;
  8580. }
  8581. }
  8582. else if(result == TypeNode.NotSpecified)
  8583. return null;
  8584. return result;
  8585. }
  8586. set
  8587. {
  8588. this.template = value;
  8589. }
  8590. }
  8591. public TypeNode TemplateExpression;
  8592. protected TypeNodeList templateArguments;
  8593. /// <summary>The arguments used when this (generic) type template instance was instantiated.</summary>
  8594. public virtual TypeNodeList TemplateArguments
  8595. {
  8596. get
  8597. {
  8598. if(this.template == null)
  8599. {
  8600. TypeNode templ = this.Template; //Will fill in the arguments
  8601. if(templ != null)
  8602. templ = null;
  8603. }
  8604. return this.templateArguments;
  8605. }
  8606. set
  8607. {
  8608. this.templateArguments = value;
  8609. }
  8610. }
  8611. public TypeNodeList TemplateArgumentExpressions;
  8612. internal TypeNodeList consolidatedTemplateArguments;
  8613. public virtual TypeNodeList ConsolidatedTemplateArguments
  8614. {
  8615. get
  8616. {
  8617. if(this.consolidatedTemplateArguments == null)
  8618. this.consolidatedTemplateArguments = this.GetConsolidatedTemplateArguments();
  8619. return this.consolidatedTemplateArguments;
  8620. }
  8621. set
  8622. {
  8623. this.consolidatedTemplateArguments = value;
  8624. }
  8625. }
  8626. private void AddTemplateParametersFromAttributeEncoding(TypeNodeList result)
  8627. {
  8628. }
  8629. internal TypeNodeList templateParameters;
  8630. /// <summary>The type parameters of this type. Null if this type is not a (generic) type template.</summary>
  8631. public virtual TypeNodeList TemplateParameters
  8632. {
  8633. get
  8634. {
  8635. TypeNodeList result = this.templateParameters;
  8636. if(result == null)
  8637. {
  8638. if(this.isGeneric || TargetPlatform.GenericTypeNamesMangleChar != '_')
  8639. return null; //Can happen when this is nested in a generic type
  8640. TypeNodeList nestedTypes = this.NestedTypes;
  8641. lock(this)
  8642. {
  8643. if((result = this.templateParameters) != null)
  8644. return result.Count == 0 ? null : result;
  8645. result = new TypeNodeList();
  8646. for(int i = 0, n = nestedTypes == null ? 0 : nestedTypes.Count; i < n; i++)
  8647. {
  8648. TypeNode nt = nestedTypes[i];
  8649. if(nt == null)
  8650. continue;
  8651. if(nt is MethodTypeParameter)
  8652. continue;
  8653. if(nt.NodeType == NodeType.TypeParameter || nt.NodeType == NodeType.ClassParameter)
  8654. result.Add(nt);
  8655. }
  8656. this.AddTemplateParametersFromAttributeEncoding(result);
  8657. this.TemplateParameters = result;
  8658. }
  8659. }
  8660. if(result.Count == 0)
  8661. return null;
  8662. return result;
  8663. }
  8664. set
  8665. {
  8666. if(value == null)
  8667. {
  8668. if(this.templateParameters == null)
  8669. return;
  8670. if(this.templateParameters.Count > 0)
  8671. value = new TypeNodeList();
  8672. }
  8673. this.templateParameters = value;
  8674. }
  8675. }
  8676. protected internal TypeNodeList consolidatedTemplateParameters;
  8677. public virtual TypeNodeList ConsolidatedTemplateParameters
  8678. {
  8679. get
  8680. {
  8681. if(this.consolidatedTemplateParameters == null)
  8682. this.consolidatedTemplateParameters = this.GetConsolidatedTemplateParameters();
  8683. return this.consolidatedTemplateParameters;
  8684. }
  8685. set
  8686. {
  8687. this.consolidatedTemplateParameters = value;
  8688. }
  8689. }
  8690. internal ElementType typeCode = ElementType.Class;
  8691. /// <summary>The System.TypeCode value that Convert.GetTypeCode will return pass an instance of this type as parameter.</summary>
  8692. public virtual System.TypeCode TypeCode
  8693. {
  8694. get
  8695. {
  8696. switch(this.typeCode)
  8697. {
  8698. case ElementType.Boolean:
  8699. return System.TypeCode.Boolean;
  8700. case ElementType.Char:
  8701. return System.TypeCode.Char;
  8702. case ElementType.Double:
  8703. return System.TypeCode.Double;
  8704. case ElementType.Int16:
  8705. return System.TypeCode.Int16;
  8706. case ElementType.Int32:
  8707. return System.TypeCode.Int32;
  8708. case ElementType.Int64:
  8709. return System.TypeCode.Int64;
  8710. case ElementType.Int8:
  8711. return System.TypeCode.SByte;
  8712. case ElementType.Single:
  8713. return System.TypeCode.Single;
  8714. case ElementType.UInt16:
  8715. return System.TypeCode.UInt16;
  8716. case ElementType.UInt32:
  8717. return System.TypeCode.UInt32;
  8718. case ElementType.UInt64:
  8719. return System.TypeCode.UInt64;
  8720. case ElementType.UInt8:
  8721. return System.TypeCode.Byte;
  8722. case ElementType.Void:
  8723. return System.TypeCode.Empty;
  8724. default:
  8725. if(this == CoreSystemTypes.String)
  8726. return System.TypeCode.String;
  8727. if(this == CoreSystemTypes.Decimal)
  8728. return System.TypeCode.Decimal;
  8729. if(this == CoreSystemTypes.DateTime)
  8730. return System.TypeCode.DateTime;
  8731. if(this == CoreSystemTypes.DBNull)
  8732. return System.TypeCode.DBNull;
  8733. return System.TypeCode.Object;
  8734. }
  8735. }
  8736. }
  8737. private readonly static TypeNode NotSpecified = new Class();
  8738. protected internal TrivialHashtableUsingWeakReferences structurallyEquivalentMethod;
  8739. /// <summary>
  8740. /// Returns the methods of an abstract type that have been left unimplemented. Includes methods inherited from
  8741. /// base classes and interfaces, and methods from any (known) extensions.
  8742. /// </summary>
  8743. /// <param name="result">A method list to which the abstract methods must be appended.</param>
  8744. public virtual void GetAbstractMethods(MethodList/*!*/ result)
  8745. {
  8746. if(!this.IsAbstract)
  8747. return;
  8748. //For each interface, get abstract methods and keep those that are not implemented by this class or a base class
  8749. InterfaceList interfaces = this.Interfaces;
  8750. for(int i = 0, n = interfaces == null ? 0 : interfaces.Count; i < n; i++)
  8751. {
  8752. Interface iface = interfaces[i];
  8753. if(iface == null)
  8754. continue;
  8755. MemberList imembers = iface.Members;
  8756. for(int j = 0, m = imembers == null ? 0 : imembers.Count; j < m; j++)
  8757. {
  8758. Method meth = imembers[j] as Method;
  8759. if(meth == null)
  8760. continue;
  8761. if(this.ImplementsExplicitly(meth))
  8762. continue;
  8763. if(this.ImplementsMethod(meth, true))
  8764. continue;
  8765. result.Add(meth);
  8766. }
  8767. }
  8768. }
  8769. protected internal TrivialHashtable szArrayTypes;
  8770. /// <summary>
  8771. /// Returns a type representing an array whose elements are of this type. Will always return the same instance for the same rank.
  8772. /// </summary>
  8773. /// <param name="rank">The number of dimensions of the array.</param>
  8774. public virtual ArrayType/*!*/ GetArrayType(int rank)
  8775. {
  8776. return this.GetArrayType(rank, false);
  8777. }
  8778. public virtual ArrayType/*!*/ GetArrayType(int rank, bool lowerBoundIsUnknown)
  8779. {
  8780. if(rank > 1 || lowerBoundIsUnknown)
  8781. return this.GetArrayType(rank, 0, 0, new int[0], new int[0]);
  8782. if(this.szArrayTypes == null)
  8783. this.szArrayTypes = new TrivialHashtable();
  8784. ArrayType result = (ArrayType)this.szArrayTypes[rank];
  8785. if(result != null)
  8786. return result;
  8787. lock(this)
  8788. {
  8789. result = (ArrayType)this.szArrayTypes[rank];
  8790. if(result != null)
  8791. return result;
  8792. this.szArrayTypes[rank] = result = new ArrayType(this, 1);
  8793. result.Flags &= ~TypeFlags.VisibilityMask;
  8794. result.Flags |= this.Flags & TypeFlags.VisibilityMask;
  8795. return result;
  8796. }
  8797. }
  8798. protected internal TrivialHashtable arrayTypes;
  8799. /// <summary>
  8800. /// Returns a type representing an array whose elements are of this type. Will always return the same instance for the same rank, sizes and bounds.
  8801. /// </summary>
  8802. /// <param name="rank">The number of dimensions of the array.</param>
  8803. /// <param name="sizes">The size of each dimension.</param>
  8804. /// <param name="loBounds">The lower bound for indices. Defaults to zero.</param>
  8805. public virtual ArrayType/*!*/ GetArrayType(int rank, int[] sizes, int[] loBounds)
  8806. {
  8807. return this.GetArrayType(rank, sizes == null ? 0 : sizes.Length, loBounds == null ? 0 : loBounds.Length, sizes == null ? new int[0] : sizes, loBounds == null ? new int[0] : loBounds);
  8808. }
  8809. internal ArrayType/*!*/ GetArrayType(int rank, int numSizes, int numLoBounds, int[]/*!*/ sizes, int[]/*!*/ loBounds)
  8810. {
  8811. if(this.arrayTypes == null)
  8812. this.arrayTypes = new TrivialHashtable();
  8813. StringBuilder sb = new StringBuilder(rank * 5);
  8814. for(int i = 0; i < rank; i++)
  8815. {
  8816. if(i < numLoBounds)
  8817. sb.Append(loBounds[i]);
  8818. else
  8819. sb.Append('0');
  8820. if(i < numSizes) { sb.Append(':'); sb.Append(sizes[i]); }
  8821. sb.Append(',');
  8822. }
  8823. Identifier id = Identifier.For(sb.ToString());
  8824. ArrayType result = (ArrayType)this.arrayTypes[id.UniqueIdKey];
  8825. if(result != null)
  8826. return result;
  8827. lock(this)
  8828. {
  8829. result = (ArrayType)this.arrayTypes[id.UniqueIdKey];
  8830. if(result != null)
  8831. return result;
  8832. if(loBounds == null)
  8833. loBounds = new int[0];
  8834. this.arrayTypes[id.UniqueIdKey] = result = new ArrayType(this, rank, sizes, loBounds);
  8835. result.Flags &= ~TypeFlags.VisibilityMask;
  8836. result.Flags |= this.Flags & TypeFlags.VisibilityMask;
  8837. return result;
  8838. }
  8839. }
  8840. protected internal MemberList constructors;
  8841. public virtual MemberList GetConstructors()
  8842. {
  8843. if(this.Members.Count != this.memberCount)
  8844. this.constructors = null;
  8845. if(this.constructors != null)
  8846. return this.constructors;
  8847. lock(this)
  8848. {
  8849. if(this.constructors != null)
  8850. return this.constructors;
  8851. return this.constructors = TypeNode.WeedOutNonSpecialMethods(this.GetMembersNamed(StandardIds.Ctor), MethodFlags.RTSpecialName);
  8852. }
  8853. }
  8854. /// <summary>
  8855. /// Returns the constructor with the specified parameter types. Returns null if this type has no such constructor.
  8856. /// </summary>
  8857. public virtual InstanceInitializer GetConstructor(params TypeNode[] types)
  8858. {
  8859. return (InstanceInitializer)GetMethod(this.GetConstructors(), types);
  8860. }
  8861. protected override Identifier GetDocumentationId()
  8862. {
  8863. if(this.DeclaringType == null)
  8864. return Identifier.For("T:" + this.FullName);
  8865. else
  8866. return Identifier.For(this.DeclaringType.DocumentationId + "." + this.Name);
  8867. }
  8868. internal virtual void AppendDocumentIdMangledName(StringBuilder/*!*/ sb, TypeNodeList methodTypeParameters, TypeNodeList typeParameters)
  8869. {
  8870. if(this.DeclaringType != null)
  8871. {
  8872. this.DeclaringType.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
  8873. sb.Append('.');
  8874. sb.Append(this.GetUnmangledNameWithoutTypeParameters());
  8875. }
  8876. else
  8877. sb.Append(this.GetFullUnmangledNameWithoutTypeParameters());
  8878. TypeNodeList templateArguments = this.TemplateArguments;
  8879. int n = templateArguments == null ? 0 : templateArguments.Count;
  8880. if(n == 0)
  8881. return;
  8882. sb.Append('{');
  8883. for(int i = 0; i < n; i++)
  8884. {
  8885. //^ assert templateArguments != null;
  8886. TypeNode templArg = templateArguments[i];
  8887. if(templArg == null)
  8888. continue;
  8889. templArg.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
  8890. if(i < n - 1)
  8891. sb.Append(',');
  8892. }
  8893. sb.Append('}');
  8894. }
  8895. internal TrivialHashtable modifierTable;
  8896. internal TypeNode/*!*/ GetModified(TypeNode/*!*/ modifierType, bool optionalModifier)
  8897. {
  8898. if(this.modifierTable == null)
  8899. this.modifierTable = new TrivialHashtable();
  8900. TypeNode result = (TypeNode)this.modifierTable[modifierType.UniqueKey];
  8901. if(result != null)
  8902. return result;
  8903. result = optionalModifier ? (TypeNode)new OptionalModifier(modifierType, this) : (TypeNode)new RequiredModifier(modifierType, this);
  8904. this.modifierTable[modifierType.UniqueKey] = result;
  8905. return result;
  8906. }
  8907. public virtual TypeNode/*!*/ GetGenericTemplateInstance(Module/*!*/ module, TypeNodeList/*!*/ consolidatedArguments)
  8908. {
  8909. if(this.DeclaringType == null)
  8910. return this.GetTemplateInstance(module, null, null, consolidatedArguments);
  8911. TypeNodeList myArgs = this.GetOwnTemplateArguments(consolidatedArguments);
  8912. if(myArgs == consolidatedArguments)
  8913. return this.GetTemplateInstance(module, null, this.DeclaringType, consolidatedArguments);
  8914. int n = consolidatedArguments.Count;
  8915. int m = myArgs == null ? 0 : myArgs.Count;
  8916. int k = n - m;
  8917. Debug.Assert(k > 0);
  8918. TypeNodeList parentArgs = new TypeNodeList();
  8919. for(int i = 0; i < k; i++)
  8920. parentArgs.Add(consolidatedArguments[i]);
  8921. TypeNode declaringType = this.DeclaringType.GetGenericTemplateInstance(module, parentArgs);
  8922. TypeNode nestedType = declaringType.GetNestedType(this.Name);
  8923. if(nestedType == null) { Debug.Fail("template declaring type dummy instance does not have a nested type corresponding to template"); nestedType = this; }
  8924. if(m == 0) { Debug.Assert(nestedType.template != null); return nestedType; }
  8925. return nestedType.GetTemplateInstance(module, null, declaringType, myArgs);
  8926. }
  8927. public virtual TypeNode/*!*/ GetTemplateInstance(Module module, params TypeNode[] typeArguments)
  8928. {
  8929. return this.GetTemplateInstance(module, null, null, new TypeNodeList(typeArguments));
  8930. }
  8931. protected virtual void TryToFindExistingInstance(Module/*!*/ module, TypeNode declaringType, TypeNodeList/*!*/ templateArguments, Identifier/*!*/ mangledName,
  8932. Identifier/*!*/ uniqueMangledName, out TypeNode result, out Identifier unusedMangledName)
  8933. {
  8934. unusedMangledName = null;
  8935. string mangledNameString = mangledName.Name;
  8936. int n = templateArguments.Count;
  8937. int tiCount = 0;
  8938. bool lookInReferencedAssemblies = TargetPlatform.GenericTypeNamesMangleChar != '`'; //REVIEW: huh? why not use IsGeneric?
  8939. result = module.GetStructurallyEquivalentType(this.Namespace == null ? Identifier.Empty : this.Namespace, mangledName, uniqueMangledName, lookInReferencedAssemblies);
  8940. if(this.IsGeneric)
  8941. {
  8942. if(result == null)
  8943. unusedMangledName = mangledName;
  8944. return;
  8945. }
  8946. while(result != null)
  8947. {
  8948. //Mangled name is the same. But mangling is not unique (types are not qualified with assemblies), so check for equality.
  8949. if(this == result.Template && (declaringType == result.DeclaringType || !this.IsGeneric))
  8950. {
  8951. bool goodMatch = (result.TemplateArguments != null || n == 0) && result.TemplateArguments.Count == n;
  8952. for(int i = 0; goodMatch && i < n; i++)
  8953. goodMatch = templateArguments[i] == result.TemplateArguments[i];
  8954. if(goodMatch)
  8955. return;
  8956. }
  8957. //Mangle some more
  8958. mangledName = new Identifier(mangledNameString + (++tiCount).ToString());
  8959. result = module.GetStructurallyEquivalentType(this.Namespace == null ? Identifier.Empty : this.Namespace, mangledName, null, lookInReferencedAssemblies);
  8960. }
  8961. if(result == null)
  8962. unusedMangledName = mangledName;
  8963. }
  8964. public virtual Identifier/*!*/ GetMangledTemplateInstanceName(TypeNodeList/*!*/ templateArguments, out Identifier/*!*/ uniqueMangledName, out bool notFullySpecialized)
  8965. {
  8966. StringBuilder mangledNameBuilder = new StringBuilder(this.Name.ToString());
  8967. StringBuilder uniqueMangledNameBuilder = new StringBuilder(this.Name.ToString());
  8968. uniqueMangledNameBuilder.Append(this.UniqueKey);
  8969. notFullySpecialized = false;
  8970. for(int i = 0, n = templateArguments.Count; i < n; i++)
  8971. {
  8972. if(i == 0) { mangledNameBuilder.Append('<'); uniqueMangledNameBuilder.Append('<'); }
  8973. TypeNode t = templateArguments[i];
  8974. if(t == null || t.Name == null)
  8975. continue;
  8976. if(TypeIsNotFullySpecialized(t))
  8977. notFullySpecialized = true;
  8978. mangledNameBuilder.Append(t.FullName);
  8979. uniqueMangledNameBuilder.Append(t.FullName);
  8980. uniqueMangledNameBuilder.Append(t.UniqueKey);
  8981. if(i < n - 1)
  8982. {
  8983. mangledNameBuilder.Append(',');
  8984. uniqueMangledNameBuilder.Append(',');
  8985. }
  8986. else
  8987. {
  8988. mangledNameBuilder.Append('>');
  8989. uniqueMangledNameBuilder.Append('>');
  8990. }
  8991. }
  8992. uniqueMangledName = Identifier.For(uniqueMangledNameBuilder.ToString());
  8993. return Identifier.For(mangledNameBuilder.ToString());
  8994. }
  8995. private static bool TypeIsNotFullySpecialized(TypeNode t)
  8996. {
  8997. TypeNode tt = TypeNode.StripModifiers(t);
  8998. //^ assert tt != null;
  8999. if(tt is TypeParameter || tt is ClassParameter || tt.IsNotFullySpecialized)
  9000. return true;
  9001. for(int j = 0, m = tt.StructuralElementTypes == null ? 0 : tt.StructuralElementTypes.Count; j < m; j++)
  9002. {
  9003. TypeNode et = tt.StructuralElementTypes[j];
  9004. if(et == null)
  9005. continue;
  9006. if(TypeIsNotFullySpecialized(et))
  9007. return true;
  9008. }
  9009. return false;
  9010. }
  9011. /// <summary>
  9012. /// Gets an instance for the given template arguments of this (generic) template type.
  9013. /// </summary>
  9014. /// <param name="referringType">The type in which the reference to the template instance occurs. If the template is not
  9015. /// generic, the instance becomes a nested type of the referring type so that it has the same access privileges as the
  9016. /// code referring to the instance.</param>
  9017. /// <param name="templateArguments">The template arguments.</param>
  9018. /// <returns>An instance of the template. Always the same instance for the same arguments.</returns>
  9019. public virtual TypeNode/*!*/ GetTemplateInstance(TypeNode referringType, params TypeNode[] templateArguments)
  9020. {
  9021. return this.GetTemplateInstance(referringType, new TypeNodeList(templateArguments));
  9022. }
  9023. /// <summary>
  9024. /// Gets an instance for the given template arguments of this (generic) template type.
  9025. /// </summary>
  9026. /// <param name="referringType">The type in which the reference to the template instance occurs. If the template is not
  9027. /// generic, the instance becomes a nested type of the referring type so that it has the same access privileges as the
  9028. /// code referring to the instance.</param>
  9029. /// <param name="templateArguments">The template arguments.</param>
  9030. /// <returns>An instance of the template. Always the same instance for the same arguments.</returns>
  9031. public virtual TypeNode/*!*/ GetTemplateInstance(TypeNode referringType, TypeNodeList templateArguments)
  9032. {
  9033. if(referringType == null)
  9034. return this;
  9035. Module module = referringType.DeclaringModule;
  9036. return this.GetTemplateInstance(module, referringType, this.DeclaringType, templateArguments);
  9037. }
  9038. class CachingModuleForGenericsInstances : Module
  9039. {
  9040. public override TypeNode GetStructurallyEquivalentType(Identifier ns, Identifier/*!*/ id, Identifier uniqueMangledName, bool lookInReferencedAssemblies)
  9041. {
  9042. if(uniqueMangledName == null)
  9043. return null;
  9044. return (TypeNode)this.StructurallyEquivalentType[uniqueMangledName.UniqueIdKey];
  9045. }
  9046. }
  9047. protected static Module/*!*/ cachingModuleForGenericInstances = new CachingModuleForGenericsInstances();
  9048. public virtual TypeNode/*!*/ GetTemplateInstance(Module module, TypeNode referringType, TypeNode declaringType, TypeNodeList templateArguments)
  9049. {
  9050. TypeNodeList templateParameters = this.TemplateParameters;
  9051. if(module == null || templateArguments == null || (declaringType == null && (templateParameters == null || templateParameters.Count == 0)))
  9052. return this;
  9053. if(this.IsGeneric)
  9054. {
  9055. referringType = null;
  9056. module = TypeNode.cachingModuleForGenericInstances;
  9057. }
  9058. bool notFullySpecialized;
  9059. Identifier/*!*/ uniqueMangledName;
  9060. Identifier mangledName = this.GetMangledTemplateInstanceName(templateArguments, out uniqueMangledName, out notFullySpecialized);
  9061. TypeNode result;
  9062. Identifier dummyId;
  9063. this.TryToFindExistingInstance(module, declaringType, templateArguments, mangledName, uniqueMangledName, out result, out dummyId);
  9064. if(result != null)
  9065. return result;
  9066. if(this.NewTemplateInstanceIsRecursive)
  9067. return this; //An instance of this template is trying to instantiate the template again
  9068. lock(Module.GlobalLock)
  9069. {
  9070. Identifier unusedMangledName;
  9071. this.TryToFindExistingInstance(module, declaringType, templateArguments, mangledName, uniqueMangledName, out result, out unusedMangledName);
  9072. if(result != null)
  9073. return result;
  9074. //^ assume unusedMangledName != null;
  9075. TypeNodeList consolidatedTemplateArguments =
  9076. declaringType == null ? templateArguments : declaringType.GetConsolidatedTemplateArguments(templateArguments);
  9077. Duplicator duplicator = new Duplicator(module, referringType);
  9078. duplicator.RecordOriginalAsTemplate = true;
  9079. duplicator.SkipBodies = true;
  9080. duplicator.TypesToBeDuplicated[this.UniqueKey] = this;
  9081. result = duplicator.VisitTypeNode(this, unusedMangledName, consolidatedTemplateArguments, this.Template == null ? this : this.Template, true);
  9082. //^ assume result != null;
  9083. if(module == this.DeclaringModule)
  9084. {
  9085. if(this.TemplateInstances == null)
  9086. this.TemplateInstances = new TypeNodeList();
  9087. this.TemplateInstances.Add(result);
  9088. }
  9089. result.Name = unusedMangledName;
  9090. result.Name.SourceContext = this.Name.SourceContext;
  9091. result.fullName = null;
  9092. if(this.IsGeneric)
  9093. result.DeclaringModule = this.DeclaringModule;
  9094. result.DeclaringType = this.IsGeneric || referringType == null ? declaringType : referringType;
  9095. result.Template = this;
  9096. result.templateParameters = new TypeNodeList();
  9097. result.consolidatedTemplateParameters = new TypeNodeList();
  9098. result.templateArguments = templateArguments;
  9099. result.consolidatedTemplateArguments = consolidatedTemplateArguments;
  9100. result.IsNotFullySpecialized = notFullySpecialized || (declaringType != null && declaringType.IsNotFullySpecialized);
  9101. module.StructurallyEquivalentType[unusedMangledName.UniqueIdKey] = result;
  9102. module.StructurallyEquivalentType[uniqueMangledName.UniqueIdKey] = result;
  9103. Specializer specializer = new Specializer(module, this.ConsolidatedTemplateParameters, consolidatedTemplateArguments);
  9104. specializer.VisitTypeNode(result);
  9105. TypeFlags visibility = this.Flags & TypeFlags.VisibilityMask;
  9106. for(int i = 0, m = templateArguments.Count; i < m; i++)
  9107. {
  9108. TypeNode t = templateArguments[i];
  9109. if(t == null)
  9110. continue;
  9111. if(t is TypeParameter || t is ClassParameter || t.IsNotFullySpecialized)
  9112. continue;
  9113. visibility = TypeNode.GetVisibilityIntersection(visibility, t.Flags & TypeFlags.VisibilityMask);
  9114. }
  9115. result.Flags &= ~TypeFlags.VisibilityMask;
  9116. result.Flags |= visibility;
  9117. if(this.IsGeneric)
  9118. return result;
  9119. return result;
  9120. }
  9121. }
  9122. protected virtual TypeNodeList GetConsolidatedTemplateArguments()
  9123. {
  9124. TypeNodeList typeArgs = this.TemplateArguments;
  9125. if(this.DeclaringType == null)
  9126. return typeArgs;
  9127. TypeNodeList result = this.DeclaringType.ConsolidatedTemplateArguments;
  9128. if(result == null)
  9129. {
  9130. if(this.DeclaringType.IsGeneric && this.DeclaringType.Template == null)
  9131. result = this.DeclaringType.ConsolidatedTemplateParameters;
  9132. if(result == null)
  9133. return typeArgs;
  9134. }
  9135. int n = (typeArgs == null) ? 0 : typeArgs.Count;
  9136. if(n == 0)
  9137. return result;
  9138. result = new TypeNodeList(result);
  9139. result.AddRange(typeArgs);
  9140. return result;
  9141. }
  9142. protected virtual TypeNodeList GetConsolidatedTemplateArguments(TypeNodeList typeArgs)
  9143. {
  9144. TypeNodeList result = this.ConsolidatedTemplateArguments;
  9145. if(result == null || result.Count == 0)
  9146. {
  9147. if(this.IsGeneric && this.Template == null)
  9148. result = this.ConsolidatedTemplateParameters;
  9149. else
  9150. return typeArgs;
  9151. }
  9152. int n = (typeArgs == null) ? 0 : typeArgs.Count;
  9153. if(n == 0)
  9154. return result;
  9155. //^ assert typeArgs != null;
  9156. result = new TypeNodeList(result);
  9157. result.AddRange(typeArgs);
  9158. return result;
  9159. }
  9160. protected virtual TypeNodeList GetConsolidatedTemplateParameters()
  9161. {
  9162. TypeNodeList typeParams = this.TemplateParameters;
  9163. TypeNode declaringType = this.DeclaringType;
  9164. if(declaringType == null)
  9165. return typeParams;
  9166. while(declaringType.Template != null)
  9167. declaringType = declaringType.Template;
  9168. TypeNodeList result = declaringType.ConsolidatedTemplateParameters;
  9169. if(result == null)
  9170. return typeParams;
  9171. int n = (typeParams == null) ? 0 : typeParams.Count;
  9172. if(n == 0)
  9173. return result;
  9174. result = new TypeNodeList(result);
  9175. result.AddRange(typeParams);
  9176. return result;
  9177. }
  9178. protected virtual TypeNodeList GetOwnTemplateArguments(TypeNodeList consolidatedTemplateArguments)
  9179. {
  9180. int n = this.TemplateParameters == null ? 0 : this.TemplateParameters.Count;
  9181. int m = consolidatedTemplateArguments == null ? 0 : consolidatedTemplateArguments.Count;
  9182. int k = m - n;
  9183. if(k <= 0)
  9184. return consolidatedTemplateArguments;
  9185. TypeNodeList result = new TypeNodeList();
  9186. if(consolidatedTemplateArguments != null)
  9187. for(int i = 0; i < n; i++)
  9188. result.Add(consolidatedTemplateArguments[i + k]);
  9189. return result;
  9190. }
  9191. protected internal Pointer pointerType;
  9192. public virtual Pointer/*!*/ GetPointerType()
  9193. {
  9194. Pointer result = this.pointerType;
  9195. if(result == null)
  9196. {
  9197. lock(this)
  9198. {
  9199. if(this.pointerType != null)
  9200. return this.pointerType;
  9201. result = this.pointerType = new Pointer(this);
  9202. result.Flags &= ~TypeFlags.VisibilityMask;
  9203. result.Flags |= this.Flags & TypeFlags.VisibilityMask;
  9204. result.DeclaringModule = this.DeclaringModule;
  9205. }
  9206. }
  9207. return result;
  9208. }
  9209. protected internal Reference referenceType;
  9210. public virtual Reference/*!*/ GetReferenceType()
  9211. {
  9212. Reference result = this.referenceType;
  9213. if(result == null)
  9214. {
  9215. lock(this)
  9216. {
  9217. if(this.referenceType != null)
  9218. return this.referenceType;
  9219. result = this.referenceType = new Reference(this);
  9220. result.Flags &= ~TypeFlags.VisibilityMask;
  9221. result.Flags |= this.Flags & TypeFlags.VisibilityMask;
  9222. result.DeclaringModule = this.DeclaringModule;
  9223. }
  9224. }
  9225. return result;
  9226. }
  9227. //^ [Microsoft.Contracts.SpecPublic]
  9228. protected internal TrivialHashtable memberTable;
  9229. protected internal int memberCount;
  9230. /// <summary>
  9231. /// Returns a list of all the members declared directly by this type with the specified name.
  9232. /// Returns an empty list if this type has no such members.
  9233. /// </summary>
  9234. public virtual MemberList/*!*/ GetMembersNamed(Identifier name)
  9235. {
  9236. if(name == null)
  9237. return new MemberList();
  9238. MemberList members = this.Members;
  9239. int n = members == null ? 0 : members.Count;
  9240. if(n != this.memberCount || this.memberTable == null)
  9241. this.UpdateMemberTable(n);
  9242. //^ assert this.memberTable != null;
  9243. MemberList result = (MemberList)this.memberTable[name.UniqueIdKey];
  9244. if(result == null)
  9245. {
  9246. lock(this)
  9247. {
  9248. result = (MemberList)this.memberTable[name.UniqueIdKey];
  9249. if(result != null)
  9250. return result;
  9251. result = new MemberList();
  9252. this.memberTable[name.UniqueIdKey] = result;
  9253. }
  9254. }
  9255. return result;
  9256. }
  9257. /// <summary>
  9258. /// Returns the first event declared by this type with the specified name.
  9259. /// Returns null if this type has no such event.
  9260. /// </summary>
  9261. public virtual Event GetEvent(Identifier name)
  9262. {
  9263. MemberList members = this.GetMembersNamed(name);
  9264. for(int i = 0, n = members.Count; i < n; i++)
  9265. {
  9266. Event ev = members[i] as Event;
  9267. if(ev != null)
  9268. return ev;
  9269. }
  9270. return null;
  9271. }
  9272. /// <summary>
  9273. /// Returns the first field declared by this type with the specified name. Returns null if this type has no such field.
  9274. /// </summary>
  9275. public virtual Field GetField(Identifier name)
  9276. {
  9277. MemberList members = this.GetMembersNamed(name);
  9278. for(int i = 0, n = members.Count; i < n; i++)
  9279. {
  9280. Field field = members[i] as Field;
  9281. if(field != null)
  9282. return field;
  9283. }
  9284. return null;
  9285. }
  9286. /// <summary>
  9287. /// Returns the first method declared by this type with the specified name and parameter types. Returns null if this type has no such method.
  9288. /// </summary>
  9289. /// <returns></returns>
  9290. public virtual Method GetMethod(Identifier name, params TypeNode[] types)
  9291. {
  9292. return GetMethod(this.GetMembersNamed(name), types);
  9293. }
  9294. private static Method GetMethod(MemberList members, params TypeNode[] types)
  9295. {
  9296. if(members == null)
  9297. return null;
  9298. int m = types == null ? 0 : types.Length;
  9299. TypeNodeList typeNodes = m == 0 ? null : new TypeNodeList(types);
  9300. for(int i = 0, n = members.Count; i < n; i++)
  9301. {
  9302. Method meth = members[i] as Method;
  9303. if(meth == null)
  9304. continue;
  9305. if(meth.ParameterTypesMatchStructurally(typeNodes))
  9306. return meth;
  9307. }
  9308. return null;
  9309. }
  9310. public Method GetMatchingMethod(Method method)
  9311. {
  9312. if(method == null || method.Name == null)
  9313. return null;
  9314. MemberList members = this.GetMembersNamed(method.Name);
  9315. for(int i = 0, n = members == null ? 0 : members.Count; i < n; i++)
  9316. {
  9317. Method m = members[i] as Method;
  9318. // !EFW - Bug fix for problem reported by SHarwell. Must compare type parameter counts too.
  9319. // If not, overloaded methods, one with and one without generic parameters, will be matched
  9320. // incorrectly.
  9321. if(m == null || !m.TypeParameterCountsMatch(method))
  9322. continue;
  9323. if(m.ParametersMatchStructurally(method.Parameters))
  9324. return m;
  9325. }
  9326. return null;
  9327. }
  9328. /// <summary>
  9329. /// Returns the first nested type declared by this type with the specified name. Returns null if this type has no such nested type.
  9330. /// </summary>
  9331. public virtual TypeNode GetNestedType(Identifier name)
  9332. {
  9333. if(name == null)
  9334. return null;
  9335. if(this.members != null)
  9336. {
  9337. MemberList members = this.GetMembersNamed(name);
  9338. for(int i = 0, n = members.Count; i < n; i++)
  9339. {
  9340. TypeNode type = members[i] as TypeNode;
  9341. if(type != null)
  9342. return type;
  9343. }
  9344. return null;
  9345. }
  9346. TypeNodeList nestedTypes = this.NestedTypes;
  9347. for(int i = 0, n = nestedTypes == null ? 0 : nestedTypes.Count; i < n; i++)
  9348. {
  9349. TypeNode type = nestedTypes[i];
  9350. if(type != null && type.Name.UniqueIdKey == name.UniqueIdKey)
  9351. return type;
  9352. }
  9353. return null;
  9354. }
  9355. protected internal TypeNodeList nestedTypes;
  9356. // !EFW - Yes, static. See below.
  9357. private static int recursionCounter;
  9358. public virtual TypeNodeList NestedTypes
  9359. {
  9360. get
  9361. {
  9362. // !EFW - Okay, this is a REALLY ugly hack but I couldn't think of any other way around it.
  9363. // If a type contains a nested type that itself implements a nested type from within the
  9364. // containing type (still with me?), this gets into an endless loop and eventually overflows
  9365. // the stack. The problem is, we can't just ignore all subsequent recursions or it can
  9366. // throw a different error about a missing template type later on. The trick is to let it
  9367. // recurse enough to get all of the information it needs but not enough to overflow the
  9368. // stack. The full test case worked at 9 levels of recursion so 20 should be more than
  9369. // enough for any case. It overflowed at 256 levels of recursion.
  9370. //
  9371. // The abbreviated example:
  9372. //
  9373. // public interface IConsumer {}
  9374. // public interface IConsumeContext<TMessage> {}
  9375. //
  9376. // public class Consumes<TMessage> where TMessage : class
  9377. // {
  9378. // public interface All : IConsumer
  9379. // {
  9380. // void Consume(TMessage message);
  9381. // }
  9382. //
  9383. // public interface Context : Consumes<IConsumeContext<TMessage>>.All
  9384. // {
  9385. // }
  9386. // }
  9387. //
  9388. // Note that this abbreviated example will overflow the stack but will not manifest the
  9389. // secondary "missing template type" error if the recursion count is too low. In case
  9390. // you're wondering, the full test case was the Mass Transit project on GitHub which was
  9391. // being used as a reference assembly by the person that reported the error.
  9392. //
  9393. if(recursionCounter > 20)
  9394. return null;
  9395. if(this.nestedTypes != null && (this.members == null || this.members.Count == this.memberCount))
  9396. return this.nestedTypes;
  9397. if(this.ProvideNestedTypes != null && this.ProviderHandle != null)
  9398. {
  9399. lock(Module.GlobalLock)
  9400. {
  9401. recursionCounter++;
  9402. this.ProvideNestedTypes(this, this.ProviderHandle);
  9403. recursionCounter--;
  9404. }
  9405. }
  9406. else
  9407. {
  9408. MemberList members = this.Members;
  9409. TypeNodeList nestedTypes = new TypeNodeList();
  9410. for(int i = 0, n = members == null ? 0 : members.Count; i < n; i++)
  9411. {
  9412. TypeNode nt = members[i] as TypeNode;
  9413. if(nt == null)
  9414. continue;
  9415. nestedTypes.Add(nt);
  9416. }
  9417. this.nestedTypes = nestedTypes;
  9418. }
  9419. return this.nestedTypes;
  9420. }
  9421. set
  9422. {
  9423. this.nestedTypes = value;
  9424. }
  9425. }
  9426. /// <summary>
  9427. /// Returns the first property declared by this type with the specified name and parameter types. Returns null if this type has no such property.
  9428. /// </summary>
  9429. public virtual Property GetProperty(Identifier name, params TypeNode[] types)
  9430. {
  9431. return GetProperty(this.GetMembersNamed(name), types);
  9432. }
  9433. private static Property GetProperty(MemberList members, params TypeNode[] types)
  9434. {
  9435. if(members == null)
  9436. return null;
  9437. int m = types == null ? 0 : types.Length;
  9438. TypeNodeList typeNodes = m == 0 ? null : new TypeNodeList(types);
  9439. for(int i = 0, n = members.Count; i < n; i++)
  9440. {
  9441. Property prop = members[i] as Property;
  9442. if(prop == null)
  9443. continue;
  9444. if(prop.ParameterTypesMatch(typeNodes))
  9445. return prop;
  9446. }
  9447. return null;
  9448. }
  9449. protected internal MemberList explicitCoercionMethods;
  9450. public virtual MemberList ExplicitCoercionMethods
  9451. {
  9452. get
  9453. {
  9454. if(this.Members.Count != this.memberCount)
  9455. this.explicitCoercionMethods = null;
  9456. if(this.explicitCoercionMethods != null)
  9457. return this.explicitCoercionMethods;
  9458. lock(this)
  9459. {
  9460. if(this.explicitCoercionMethods != null)
  9461. return this.explicitCoercionMethods;
  9462. return this.explicitCoercionMethods = TypeNode.WeedOutNonSpecialMethods(this.GetMembersNamed(StandardIds.opExplicit), MethodFlags.SpecialName);
  9463. }
  9464. }
  9465. }
  9466. protected internal MemberList implicitCoercionMethods;
  9467. public virtual MemberList ImplicitCoercionMethods
  9468. {
  9469. get
  9470. {
  9471. if(this.Members.Count != this.memberCount)
  9472. this.implicitCoercionMethods = null;
  9473. if(this.implicitCoercionMethods != null)
  9474. return this.implicitCoercionMethods;
  9475. lock(this)
  9476. {
  9477. if(this.implicitCoercionMethods != null)
  9478. return this.implicitCoercionMethods;
  9479. return this.implicitCoercionMethods = TypeNode.WeedOutNonSpecialMethods(this.GetMembersNamed(StandardIds.opImplicit), MethodFlags.SpecialName);
  9480. }
  9481. }
  9482. }
  9483. protected readonly static Method MethodDoesNotExist = new Method();
  9484. protected internal TrivialHashtable explicitCoercionFromTable;
  9485. public virtual Method GetExplicitCoercionFromMethod(TypeNode sourceType)
  9486. {
  9487. if(sourceType == null)
  9488. return null;
  9489. Method result = null;
  9490. if(this.explicitCoercionFromTable != null)
  9491. result = (Method)this.explicitCoercionFromTable[sourceType.UniqueKey];
  9492. if(result == TypeNode.MethodDoesNotExist)
  9493. return null;
  9494. if(result != null)
  9495. return result;
  9496. lock(this)
  9497. {
  9498. if(this.explicitCoercionFromTable != null)
  9499. result = (Method)this.explicitCoercionFromTable[sourceType.UniqueKey];
  9500. if(result == TypeNode.MethodDoesNotExist)
  9501. return null;
  9502. if(result != null)
  9503. return result;
  9504. MemberList coercions = this.ExplicitCoercionMethods;
  9505. for(int i = 0, n = coercions.Count; i < n; i++)
  9506. {
  9507. Method m = (Method)coercions[i];
  9508. if(sourceType == m.Parameters[0].Type) { result = m; break; }
  9509. }
  9510. if(this.explicitCoercionFromTable == null)
  9511. this.explicitCoercionFromTable = new TrivialHashtable();
  9512. if(result == null)
  9513. this.explicitCoercionFromTable[sourceType.UniqueKey] = TypeNode.MethodDoesNotExist;
  9514. else
  9515. this.explicitCoercionFromTable[sourceType.UniqueKey] = result;
  9516. return result;
  9517. }
  9518. }
  9519. protected internal TrivialHashtable explicitCoercionToTable;
  9520. public virtual Method GetExplicitCoercionToMethod(TypeNode targetType)
  9521. {
  9522. if(targetType == null)
  9523. return null;
  9524. Method result = null;
  9525. if(this.explicitCoercionToTable != null)
  9526. result = (Method)this.explicitCoercionToTable[targetType.UniqueKey];
  9527. if(result == TypeNode.MethodDoesNotExist)
  9528. return null;
  9529. if(result != null)
  9530. return result;
  9531. lock(this)
  9532. {
  9533. if(this.explicitCoercionToTable != null)
  9534. result = (Method)this.explicitCoercionToTable[targetType.UniqueKey];
  9535. if(result == TypeNode.MethodDoesNotExist)
  9536. return null;
  9537. if(result != null)
  9538. return result;
  9539. MemberList coercions = this.ExplicitCoercionMethods;
  9540. for(int i = 0, n = coercions.Count; i < n; i++)
  9541. {
  9542. Method m = (Method)coercions[i];
  9543. if(m.ReturnType == targetType) { result = m; break; }
  9544. }
  9545. if(this.explicitCoercionToTable == null)
  9546. this.explicitCoercionToTable = new TrivialHashtable();
  9547. if(result == null)
  9548. this.explicitCoercionToTable[targetType.UniqueKey] = TypeNode.MethodDoesNotExist;
  9549. else
  9550. this.explicitCoercionToTable[targetType.UniqueKey] = result;
  9551. }
  9552. return result;
  9553. }
  9554. protected internal TrivialHashtable implicitCoercionFromTable;
  9555. public virtual Method GetImplicitCoercionFromMethod(TypeNode sourceType)
  9556. {
  9557. if(sourceType == null)
  9558. return null;
  9559. Method result = null;
  9560. if(this.implicitCoercionFromTable != null)
  9561. result = (Method)this.implicitCoercionFromTable[sourceType.UniqueKey];
  9562. if(result == TypeNode.MethodDoesNotExist)
  9563. return null;
  9564. if(result != null)
  9565. return result;
  9566. lock(this)
  9567. {
  9568. if(this.implicitCoercionFromTable != null)
  9569. result = (Method)this.implicitCoercionFromTable[sourceType.UniqueKey];
  9570. if(result == TypeNode.MethodDoesNotExist)
  9571. return null;
  9572. if(result != null)
  9573. return result;
  9574. MemberList coercions = this.ImplicitCoercionMethods;
  9575. for(int i = 0, n = coercions.Count; i < n; i++)
  9576. {
  9577. Method m = (Method)coercions[i];
  9578. if(sourceType.IsStructurallyEquivalentTo(TypeNode.StripModifiers(m.Parameters[0].Type))) { result = m; break; }
  9579. }
  9580. if(this.implicitCoercionFromTable == null)
  9581. this.implicitCoercionFromTable = new TrivialHashtable();
  9582. if(result == null)
  9583. this.implicitCoercionFromTable[sourceType.UniqueKey] = TypeNode.MethodDoesNotExist;
  9584. else
  9585. this.implicitCoercionFromTable[sourceType.UniqueKey] = result;
  9586. return result;
  9587. }
  9588. }
  9589. protected internal TrivialHashtable implicitCoercionToTable;
  9590. public virtual Method GetImplicitCoercionToMethod(TypeNode targetType)
  9591. {
  9592. if(targetType == null)
  9593. return null;
  9594. Method result = null;
  9595. if(this.implicitCoercionToTable != null)
  9596. result = (Method)this.implicitCoercionToTable[targetType.UniqueKey];
  9597. if(result == TypeNode.MethodDoesNotExist)
  9598. return null;
  9599. if(result != null)
  9600. return result;
  9601. lock(this)
  9602. {
  9603. if(this.implicitCoercionToTable != null)
  9604. result = (Method)this.implicitCoercionToTable[targetType.UniqueKey];
  9605. if(result == TypeNode.MethodDoesNotExist)
  9606. return null;
  9607. if(result != null)
  9608. return result;
  9609. MemberList coercions = this.ImplicitCoercionMethods;
  9610. for(int i = 0, n = coercions.Count; i < n; i++)
  9611. {
  9612. Method m = (Method)coercions[i];
  9613. if(m.ReturnType == targetType) { result = m; break; }
  9614. }
  9615. if(this.implicitCoercionToTable == null)
  9616. this.implicitCoercionToTable = new TrivialHashtable();
  9617. if(result == null)
  9618. this.implicitCoercionToTable[targetType.UniqueKey] = TypeNode.MethodDoesNotExist;
  9619. else
  9620. this.implicitCoercionToTable[targetType.UniqueKey] = result;
  9621. return result;
  9622. }
  9623. }
  9624. protected Method opFalse;
  9625. public virtual Method GetOpFalse()
  9626. {
  9627. Method result = this.opFalse;
  9628. if(result == TypeNode.MethodDoesNotExist)
  9629. return null;
  9630. if(result != null)
  9631. return result;
  9632. MemberList members = this.Members; //evaluate for side effect
  9633. if(members != null)
  9634. members = null;
  9635. lock(this)
  9636. {
  9637. result = this.opFalse;
  9638. if(result == TypeNode.MethodDoesNotExist)
  9639. return null;
  9640. if(result != null)
  9641. return result;
  9642. TypeNode t = this;
  9643. while(t != null)
  9644. {
  9645. MemberList opFalses = t.GetMembersNamed(StandardIds.opFalse);
  9646. if(opFalses != null)
  9647. for(int i = 0, n = opFalses.Count; i < n; i++)
  9648. {
  9649. Method opFalse = opFalses[i] as Method;
  9650. if(opFalse == null)
  9651. continue;
  9652. if(!opFalse.IsSpecialName || !opFalse.IsStatic || !opFalse.IsPublic || opFalse.ReturnType != CoreSystemTypes.Boolean ||
  9653. opFalse.Parameters == null || opFalse.Parameters.Count != 1)
  9654. continue;
  9655. return this.opFalse = opFalse;
  9656. }
  9657. t = t.BaseType;
  9658. }
  9659. this.opFalse = TypeNode.MethodDoesNotExist;
  9660. return null;
  9661. }
  9662. }
  9663. protected Method opTrue;
  9664. public virtual Method GetOpTrue()
  9665. {
  9666. Method result = this.opTrue;
  9667. if(result == TypeNode.MethodDoesNotExist)
  9668. return null;
  9669. if(result != null)
  9670. return result;
  9671. MemberList members = this.Members; //evaluate for side effect
  9672. if(members != null)
  9673. members = null;
  9674. lock(this)
  9675. {
  9676. result = this.opTrue;
  9677. if(result == TypeNode.MethodDoesNotExist)
  9678. return null;
  9679. if(result != null)
  9680. return result;
  9681. TypeNode t = this;
  9682. while(t != null)
  9683. {
  9684. MemberList opTrues = t.GetMembersNamed(StandardIds.opTrue);
  9685. if(opTrues != null)
  9686. for(int i = 0, n = opTrues.Count; i < n; i++)
  9687. {
  9688. Method opTrue = opTrues[i] as Method;
  9689. if(opTrue == null)
  9690. continue;
  9691. if(!opTrue.IsSpecialName || !opTrue.IsStatic || !opTrue.IsPublic || opTrue.ReturnType != CoreSystemTypes.Boolean ||
  9692. opTrue.Parameters == null || opTrue.Parameters.Count != 1)
  9693. continue;
  9694. return this.opTrue = opTrue;
  9695. }
  9696. t = t.BaseType;
  9697. }
  9698. this.opTrue = TypeNode.MethodDoesNotExist;
  9699. return null;
  9700. }
  9701. }
  9702. private static Hashtable typeMap; //contains weak references
  9703. /// <summary>
  9704. /// Gets a TypeNode instance corresponding to the given System.Type instance.
  9705. /// </summary>
  9706. /// <param name="type">A runtime type.</param>
  9707. /// <returns>A TypeNode instance.</returns>
  9708. public static TypeNode GetTypeNode(System.Type type)
  9709. {
  9710. if(type == null)
  9711. return null;
  9712. Hashtable typeMap = TypeNode.typeMap;
  9713. if(typeMap == null)
  9714. TypeNode.typeMap = typeMap = Hashtable.Synchronized(new Hashtable());
  9715. TypeNode result = null;
  9716. WeakReference wr = (WeakReference)typeMap[type];
  9717. if(wr != null)
  9718. {
  9719. result = wr.Target as TypeNode;
  9720. if(result == Class.DoesNotExist)
  9721. return null;
  9722. if(result != null)
  9723. return result;
  9724. }
  9725. if(type.IsGenericType && !type.IsGenericTypeDefinition)
  9726. {
  9727. try
  9728. {
  9729. TypeNode template = TypeNode.GetTypeNode(type.GetGenericTypeDefinition());
  9730. if(template == null)
  9731. return null;
  9732. TypeNodeList templateArguments = new TypeNodeList();
  9733. foreach(Type arg in type.GetGenericArguments())
  9734. templateArguments.Add(TypeNode.GetTypeNode(arg));
  9735. return template.GetGenericTemplateInstance(template.DeclaringModule, templateArguments);
  9736. }
  9737. catch
  9738. {
  9739. //TODO: log error
  9740. return null;
  9741. }
  9742. }
  9743. if(type.IsGenericParameter)
  9744. {
  9745. try
  9746. {
  9747. int parIndx = type.GenericParameterPosition;
  9748. System.Reflection.MethodInfo mi = type.DeclaringMethod as System.Reflection.MethodInfo;
  9749. if(mi != null)
  9750. {
  9751. Method m = Method.GetMethod(mi);
  9752. if(m == null)
  9753. return null;
  9754. if(m.TemplateParameters != null && m.TemplateParameters.Count > parIndx)
  9755. return m.TemplateParameters[parIndx];
  9756. }
  9757. else
  9758. {
  9759. System.Type ti = type.DeclaringType;
  9760. TypeNode t = TypeNode.GetTypeNode(ti);
  9761. if(t == null)
  9762. return null;
  9763. if(t.TemplateParameters != null && t.TemplateParameters.Count > parIndx)
  9764. return t.TemplateParameters[parIndx];
  9765. }
  9766. return null;
  9767. }
  9768. catch
  9769. {
  9770. //TODO: log error
  9771. return null;
  9772. }
  9773. }
  9774. if(type.HasElementType)
  9775. {
  9776. TypeNode elemType = TypeNode.GetTypeNode(type.GetElementType());
  9777. if(elemType == null)
  9778. return null;
  9779. if(type.IsArray)
  9780. result = elemType.GetArrayType(type.GetArrayRank());
  9781. else if(type.IsByRef)
  9782. result = elemType.GetReferenceType();
  9783. else if(type.IsPointer)
  9784. result = elemType.GetPointerType();
  9785. else
  9786. {
  9787. Debug.Assert(false);
  9788. result = null;
  9789. }
  9790. }
  9791. else if(type.DeclaringType != null)
  9792. {
  9793. TypeNode dType = TypeNode.GetTypeNode(type.DeclaringType);
  9794. if(dType == null)
  9795. return null;
  9796. result = dType.GetNestedType(Identifier.For(type.Name));
  9797. }
  9798. else
  9799. {
  9800. AssemblyNode assem = AssemblyNode.GetAssembly(type.Assembly);
  9801. if(assem != null)
  9802. {
  9803. result = assem.GetType(Identifier.For(type.Namespace), Identifier.For(type.Name));
  9804. }
  9805. }
  9806. if(result == null)
  9807. typeMap[type] = new WeakReference(Class.DoesNotExist);
  9808. else
  9809. typeMap[type] = new WeakReference(result);
  9810. return result;
  9811. }
  9812. protected internal Type runtimeType;
  9813. /// <summary>
  9814. /// Gets a System.Type instance corresponding to this type. The assembly containin this type must be normalized
  9815. /// and must have a location on disk or must have been loaded via AssemblyNode.GetRuntimeAssembly.
  9816. /// </summary>
  9817. /// <returns>A System.Type instance. (A runtime type.)</returns>
  9818. public virtual Type GetRuntimeType()
  9819. {
  9820. if(this.runtimeType == null)
  9821. {
  9822. lock(this)
  9823. {
  9824. if(this.runtimeType != null)
  9825. return this.runtimeType;
  9826. if(this.IsGeneric && this.Template != null)
  9827. {
  9828. try
  9829. {
  9830. TypeNode rootTemplate = this.Template;
  9831. while(rootTemplate.Template != null)
  9832. rootTemplate = rootTemplate.Template;
  9833. Type genType = rootTemplate.GetRuntimeType();
  9834. if(genType == null)
  9835. return null;
  9836. TypeNodeList args = this.ConsolidatedTemplateArguments;
  9837. Type[] arguments = new Type[args.Count];
  9838. for(int i = 0; i < args.Count; i++)
  9839. arguments[i] = args[i].GetRuntimeType();
  9840. return genType.MakeGenericType(arguments);
  9841. }
  9842. catch
  9843. {
  9844. //TODO: add error to metadata import errors if type is imported
  9845. return null;
  9846. }
  9847. }
  9848. if(this.DeclaringType != null)
  9849. {
  9850. Type dt = this.DeclaringType.GetRuntimeType();
  9851. if(dt != null)
  9852. {
  9853. System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.DeclaredOnly;
  9854. if(this.IsPublic)
  9855. flags |= System.Reflection.BindingFlags.Public;
  9856. else
  9857. flags |= System.Reflection.BindingFlags.NonPublic;
  9858. this.runtimeType = dt.GetNestedType(this.Name.ToString(), flags);
  9859. }
  9860. }
  9861. else if(this.DeclaringModule != null && this.DeclaringModule.IsNormalized && this.DeclaringModule.ContainingAssembly != null)
  9862. {
  9863. System.Reflection.Assembly runtimeAssembly = this.DeclaringModule.ContainingAssembly.GetRuntimeAssembly();
  9864. if(runtimeAssembly != null)
  9865. this.runtimeType = runtimeAssembly.GetType(this.FullName, false);
  9866. }
  9867. }
  9868. }
  9869. return this.runtimeType;
  9870. }
  9871. public static TypeFlags GetVisibilityIntersection(TypeFlags vis1, TypeFlags vis2)
  9872. {
  9873. switch(vis2)
  9874. {
  9875. case TypeFlags.Public:
  9876. case TypeFlags.NestedPublic:
  9877. return vis1;
  9878. case TypeFlags.NotPublic:
  9879. case TypeFlags.NestedAssembly:
  9880. switch(vis1)
  9881. {
  9882. case TypeFlags.Public:
  9883. return vis2;
  9884. case TypeFlags.NestedPublic:
  9885. case TypeFlags.NestedFamORAssem:
  9886. return TypeFlags.NestedAssembly;
  9887. case TypeFlags.NestedFamily:
  9888. return TypeFlags.NestedFamANDAssem;
  9889. default:
  9890. return vis1;
  9891. }
  9892. case TypeFlags.NestedFamANDAssem:
  9893. switch(vis1)
  9894. {
  9895. case TypeFlags.Public:
  9896. case TypeFlags.NestedPublic:
  9897. case TypeFlags.NestedFamORAssem:
  9898. case TypeFlags.NestedFamily:
  9899. return TypeFlags.NestedFamANDAssem;
  9900. default:
  9901. return vis1;
  9902. }
  9903. case TypeFlags.NestedFamORAssem:
  9904. switch(vis1)
  9905. {
  9906. case TypeFlags.Public:
  9907. case TypeFlags.NestedPublic:
  9908. return TypeFlags.NestedFamORAssem;
  9909. default:
  9910. return vis1;
  9911. }
  9912. case TypeFlags.NestedFamily:
  9913. switch(vis1)
  9914. {
  9915. case TypeFlags.Public:
  9916. case TypeFlags.NestedPublic:
  9917. case TypeFlags.NestedFamORAssem:
  9918. return TypeFlags.NestedFamily;
  9919. case TypeFlags.NestedAssembly:
  9920. return TypeFlags.NestedFamANDAssem;
  9921. default:
  9922. return vis1;
  9923. }
  9924. default:
  9925. return TypeFlags.NestedPrivate;
  9926. }
  9927. }
  9928. private TrivialHashtable explicitInterfaceImplementations;
  9929. public bool ImplementsExplicitly(Method method)
  9930. {
  9931. if(method == null)
  9932. return false;
  9933. TrivialHashtable explicitInterfaceImplementations = this.explicitInterfaceImplementations;
  9934. if(explicitInterfaceImplementations == null)
  9935. {
  9936. MemberList members = this.Members;
  9937. lock(this)
  9938. {
  9939. if((explicitInterfaceImplementations = this.explicitInterfaceImplementations) == null)
  9940. {
  9941. explicitInterfaceImplementations = this.explicitInterfaceImplementations = new TrivialHashtable();
  9942. for(int i = 0, n = members.Count; i < n; i++)
  9943. {
  9944. Method m = members[i] as Method;
  9945. if(m == null)
  9946. continue;
  9947. MethodList implementedInterfaceMethods = m.ImplementedInterfaceMethods;
  9948. if(implementedInterfaceMethods != null)
  9949. for(int j = 0, k = implementedInterfaceMethods.Count; j < k; j++)
  9950. {
  9951. Method im = implementedInterfaceMethods[j];
  9952. if(im == null)
  9953. continue;
  9954. explicitInterfaceImplementations[im.UniqueKey] = m;
  9955. }
  9956. }
  9957. }
  9958. }
  9959. }
  9960. return explicitInterfaceImplementations[method.UniqueKey] != null;
  9961. }
  9962. internal bool ImplementsMethod(Method meth, bool checkPublic)
  9963. {
  9964. return this.GetImplementingMethod(meth, checkPublic) != null;
  9965. }
  9966. public Method GetImplementingMethod(Method meth, bool checkPublic)
  9967. {
  9968. if(meth == null)
  9969. return null;
  9970. MemberList mems = this.GetMembersNamed(meth.Name);
  9971. for(int j = 0, m = mems == null ? 0 : mems.Count; j < m; j++)
  9972. {
  9973. Method locM = mems[j] as Method;
  9974. if(locM == null || !locM.IsVirtual || (checkPublic && !locM.IsPublic))
  9975. continue;
  9976. if((locM.ReturnType != meth.ReturnType && !(locM.ReturnType != null && locM.ReturnType.IsStructurallyEquivalentTo(meth.ReturnType))) ||
  9977. !locM.ParametersMatchStructurally(meth.Parameters))
  9978. continue;
  9979. return locM;
  9980. }
  9981. if(checkPublic && this.BaseType != null)
  9982. return this.BaseType.GetImplementingMethod(meth, true);
  9983. return null;
  9984. }
  9985. /// <summary>
  9986. /// Returns true if the CLR CTS allows a value of this type may be assigned to a variable of the target type (possibly after boxing),
  9987. /// either because the target type is the same or a base type, or because the target type is an interface implemented by this type or the implementor of this type,
  9988. /// or because this type and the target type are zero based single dimensional arrays with assignment compatible reference element types
  9989. /// </summary>
  9990. public virtual bool IsAssignableTo(TypeNode targetType)
  9991. {
  9992. if(this == CoreSystemTypes.Void)
  9993. return false;
  9994. if(targetType == this)
  9995. return true;
  9996. if(this == CoreSystemTypes.Object)
  9997. return false;
  9998. if(targetType == CoreSystemTypes.Object || this.IsStructurallyEquivalentTo(targetType) ||
  9999. this.BaseType != null && (this.BaseType.IsAssignableTo(targetType)))
  10000. return true;
  10001. if(this.BaseType != null && this.ConsolidatedTemplateParameters != null && this.BaseType.Template != null && this.BaseType.Template.IsAssignableTo(targetType))
  10002. return true; //When seeing if one template is assignable to another, be sure to strip off template instances along the inheritance chain
  10003. InterfaceList interfaces = this.Interfaces;
  10004. if(interfaces == null)
  10005. return false;
  10006. for(int i = 0, n = interfaces.Count; i < n; i++)
  10007. {
  10008. Interface iface = interfaces[i];
  10009. if(iface == null)
  10010. continue;
  10011. if(iface.IsAssignableTo(targetType))
  10012. return true;
  10013. if(iface.Template != null && this.ConsolidatedTemplateParameters != null && iface.Template.IsAssignableTo(targetType))
  10014. return true; //When seeing if one template is assignable to another, be sure to strip off template instances along the inheritance chain
  10015. }
  10016. return false;
  10017. }
  10018. /// <summary>
  10019. /// Returns true if this type is assignable to some instance of the given template.
  10020. /// </summary>
  10021. public virtual bool IsAssignableToInstanceOf(TypeNode targetTemplate)
  10022. {
  10023. if(this == CoreSystemTypes.Void || targetTemplate == null)
  10024. return false;
  10025. if(targetTemplate.IsStructurallyEquivalentTo(this.Template == null ? this : this.Template) ||
  10026. this.BaseType != null && (this.BaseType.IsAssignableToInstanceOf(targetTemplate) ||
  10027. this.BaseType.Template != null && this.BaseType.Template.IsAssignableToInstanceOf(targetTemplate)))
  10028. return true;
  10029. InterfaceList interfaces = this.Interfaces;
  10030. if(interfaces == null)
  10031. return false;
  10032. for(int i = 0, n = interfaces.Count; i < n; i++)
  10033. {
  10034. Interface iface = interfaces[i];
  10035. if(iface == null)
  10036. continue;
  10037. if(iface.IsAssignableToInstanceOf(targetTemplate))
  10038. return true;
  10039. }
  10040. return false;
  10041. }
  10042. /// <summary>
  10043. /// Returns true if this type is assignable to some instance of the given template.
  10044. /// </summary>
  10045. public virtual bool IsAssignableToInstanceOf(TypeNode targetTemplate, out TypeNodeList templateArguments)
  10046. {
  10047. templateArguments = null;
  10048. if(this == CoreSystemTypes.Void || targetTemplate == null)
  10049. return false;
  10050. if(targetTemplate == this.Template)
  10051. {
  10052. templateArguments = this.TemplateArguments;
  10053. return true;
  10054. }
  10055. if(this != CoreSystemTypes.Object && this.BaseType != null && this.BaseType.IsAssignableToInstanceOf(targetTemplate, out templateArguments))
  10056. return true;
  10057. InterfaceList interfaces = this.Interfaces;
  10058. if(interfaces == null)
  10059. return false;
  10060. for(int i = 0, n = interfaces.Count; i < n; i++)
  10061. {
  10062. Interface iface = interfaces[i];
  10063. if(iface == null)
  10064. continue;
  10065. if(iface.IsAssignableToInstanceOf(targetTemplate, out templateArguments))
  10066. return true;
  10067. }
  10068. return false;
  10069. }
  10070. /// <summary>
  10071. /// Returns true if otherType is the base class of this type or if the base class of this type is derived from otherType.
  10072. /// </summary>
  10073. public virtual bool IsDerivedFrom(TypeNode otherType)
  10074. {
  10075. if(otherType == null)
  10076. return false;
  10077. TypeNode baseType = this.BaseType;
  10078. while(baseType != null)
  10079. {
  10080. if(baseType == otherType)
  10081. return true;
  10082. baseType = baseType.BaseType;
  10083. }
  10084. return false;
  10085. }
  10086. // Not thread safe code...
  10087. bool isCheckingInheritedFrom = false;
  10088. public virtual bool IsInheritedFrom(TypeNode otherType)
  10089. {
  10090. if(otherType == null)
  10091. return false;
  10092. if(this == otherType)
  10093. return true;
  10094. bool result = false;
  10095. if(this.isCheckingInheritedFrom)
  10096. goto done;
  10097. this.isCheckingInheritedFrom = true;
  10098. if(this.Template != null)
  10099. {
  10100. result = this.Template.IsInheritedFrom(otherType);
  10101. goto done;
  10102. }
  10103. if(otherType.Template != null)
  10104. {
  10105. otherType = otherType.Template;
  10106. }
  10107. TypeNode baseType = this.BaseType;
  10108. if(baseType != null && baseType.IsInheritedFrom(otherType))
  10109. {
  10110. result = true;
  10111. goto done;
  10112. }
  10113. InterfaceList interfaces = this.Interfaces;
  10114. if(interfaces == null)
  10115. goto done;
  10116. for(int i = 0, n = interfaces.Count; i < n; i++)
  10117. {
  10118. Interface iface = interfaces[i];
  10119. if(iface == null)
  10120. continue;
  10121. if(iface.IsInheritedFrom(otherType))
  10122. {
  10123. result = true;
  10124. goto done;
  10125. }
  10126. }
  10127. done:
  10128. this.isCheckingInheritedFrom = false;
  10129. return result;
  10130. }
  10131. public virtual bool IsStructurallyEquivalentTo(TypeNode type)
  10132. {
  10133. if(null == (object)type)
  10134. return false;
  10135. if(this == type)
  10136. return true;
  10137. if(this.Template == (object)null || type.Template == (object)null)
  10138. {
  10139. if(((object)this) == (object)type.Template || ((object)this.Template) == (object)type)
  10140. return true;
  10141. Identifier thisName = this.Template == null ? this.Name : this.Template.Name;
  10142. Identifier typeName = type.Template == null ? type.Name : type.Template.Name;
  10143. if(thisName == null || typeName == null || thisName.UniqueIdKey != typeName.UniqueIdKey)
  10144. return false;
  10145. if(this.NodeType != type.NodeType)
  10146. return false;
  10147. if(this.DeclaringType == null || type.DeclaringType == null)
  10148. return false;
  10149. }
  10150. if(this.TemplateArguments == null || type.TemplateArguments == null)
  10151. {
  10152. if(this.DeclaringType != null && (this.TemplateArguments == null || this.TemplateArguments.Count == 0) &&
  10153. (type.TemplateArguments == null || type.TemplateArguments.Count == 0))
  10154. return this.DeclaringType.IsStructurallyEquivalentTo(type.DeclaringType);
  10155. return false;
  10156. }
  10157. int n = this.TemplateArguments.Count;
  10158. if(n != type.TemplateArguments.Count)
  10159. return false;
  10160. if(this.Template != type.Template && !this.Template.IsStructurallyEquivalentTo(type.Template))
  10161. return false;
  10162. for(int i = 0; i < n; i++)
  10163. {
  10164. TypeNode ta1 = this.TemplateArguments[i];
  10165. TypeNode ta2 = type.TemplateArguments[i];
  10166. if(null == (object)ta1 || null == (object)ta2)
  10167. return false;
  10168. if(ta1 == ta2)
  10169. continue;
  10170. if(!ta1.IsStructurallyEquivalentTo(ta2))
  10171. return false;
  10172. }
  10173. if(this.DeclaringType != null)
  10174. return this.DeclaringType.IsStructurallyEquivalentTo(type.DeclaringType);
  10175. return true;
  10176. }
  10177. public virtual bool IsStructurallyEquivalentList(TypeNodeList list1, TypeNodeList list2)
  10178. {
  10179. if(list1 == null)
  10180. return list2 == null;
  10181. if(list2 == null)
  10182. return false;
  10183. int n = list1.Count;
  10184. if(list2.Count != n)
  10185. return false;
  10186. for(int i = 0; i < n; i++)
  10187. {
  10188. TypeNode t1 = list1[i];
  10189. TypeNode t2 = list2[i];
  10190. if(null == (object)t1 || null == (object)t2)
  10191. return false;
  10192. if(t1 == t2)
  10193. continue;
  10194. if(!t1.IsStructurallyEquivalentTo(t2))
  10195. return false;
  10196. }
  10197. return true;
  10198. }
  10199. public static TypeNode StripModifiers(TypeNode type)
  10200. //^ ensures t != null ==> result != null;
  10201. {
  10202. for(TypeModifier tmod = type as TypeModifier; tmod != null; tmod = type as TypeModifier)
  10203. type = tmod.ModifiedType;
  10204. // Don't strip under pointers or refs. We only strip top-level modifiers.
  10205. return type;
  10206. }
  10207. public static TypeNode DeepStripModifiers(TypeNode type)
  10208. //^ ensures type != null ==> result != null;
  10209. {
  10210. // strip off any outer type modifiers
  10211. for(TypeModifier tmod = type as TypeModifier; tmod != null; tmod = type as TypeModifier)
  10212. type = tmod.ModifiedType;
  10213. // For arrays and references, strip the inner type and then reconstruct the array or reference
  10214. ArrayType ar = type as ArrayType;
  10215. if(ar != null)
  10216. {
  10217. TypeNode t = TypeNode.DeepStripModifiers(ar.ElementType);
  10218. return t.GetArrayType(1);
  10219. }
  10220. Reference rt = type as Reference;
  10221. if(rt != null)
  10222. {
  10223. TypeNode t = TypeNode.DeepStripModifiers(rt.ElementType);
  10224. return t.GetReferenceType();
  10225. }
  10226. return type;
  10227. }
  10228. /// <summary>
  10229. /// Strip the given modifier from the type, modulo substructures that are instantiated with respect
  10230. /// to the given template type. In other words, traverse type and templateType in parallel, stripping common
  10231. /// non-null modifiers, but stop when reaching a type variable in the template type.
  10232. /// <param name="type">Type to be stripped</param>
  10233. /// <param name="modifiers">Modifiers to strip off</param>
  10234. /// <param name="templateType">Template bounding the stripping of type. Passing null for the templateType performs a full DeepStrip</param>
  10235. /// </summary>
  10236. public static TypeNode DeepStripModifiers(TypeNode type, TypeNode templateType, params TypeNode[] modifiers)
  10237. {
  10238. if(templateType == null)
  10239. return DeepStripModifiers(type, modifiers);
  10240. if(templateType is ITypeParameter)
  10241. return type;
  10242. // strip off inner modifiers then outer type modifier if it matches
  10243. OptionalModifier optmod = type as OptionalModifier;
  10244. if(optmod != null)
  10245. {
  10246. OptionalModifier optmodtemplate = (OptionalModifier)templateType; // must be in sync
  10247. TypeNode t = TypeNode.DeepStripModifiers(optmod.ModifiedType, optmodtemplate.ModifiedType, modifiers);
  10248. for(int i = 0; i < modifiers.Length; ++i)
  10249. {
  10250. if(optmod.Modifier == modifiers[i])
  10251. {
  10252. // strip it
  10253. return t;
  10254. }
  10255. }
  10256. return OptionalModifier.For(optmod.Modifier, t);
  10257. }
  10258. RequiredModifier reqmod = type as RequiredModifier;
  10259. if(reqmod != null)
  10260. {
  10261. RequiredModifier reqmodtemplate = (RequiredModifier)templateType; // must be in sync
  10262. TypeNode t = TypeNode.DeepStripModifiers(reqmod.ModifiedType, reqmodtemplate.ModifiedType, modifiers);
  10263. for(int i = 0; i < modifiers.Length; ++i)
  10264. {
  10265. if(reqmod.Modifier == modifiers[i])
  10266. {
  10267. // strip it
  10268. return t;
  10269. }
  10270. }
  10271. return RequiredModifier.For(reqmod.Modifier, t);
  10272. }
  10273. // For arrays and references, strip the inner type and then reconstruct the array or reference
  10274. ArrayType ar = type as ArrayType;
  10275. if(ar != null)
  10276. {
  10277. ArrayType artemplate = (ArrayType)templateType;
  10278. TypeNode t = TypeNode.DeepStripModifiers(ar.ElementType, artemplate.ElementType, modifiers);
  10279. return t.GetArrayType(1);
  10280. }
  10281. Reference rt = type as Reference;
  10282. if(rt != null)
  10283. {
  10284. Reference rttemplate = (Reference)templateType;
  10285. TypeNode t = TypeNode.DeepStripModifiers(rt.ElementType, rttemplate.ElementType, modifiers);
  10286. return t.GetReferenceType();
  10287. }
  10288. // strip template arguments
  10289. if(type.Template != null && type.TemplateArguments != null && type.TemplateArguments.Count > 0)
  10290. {
  10291. TypeNodeList strippedArgs = new TypeNodeList();
  10292. for(int i = 0; i < type.TemplateArguments.Count; i++)
  10293. {
  10294. //FIX: bug introduced by check in 16494
  10295. //templateType may have type parameters in either the TemplateArguments position or the templateParameters position.
  10296. //This may indicate an inconsistency in the template instantiation representation elsewhere.
  10297. TypeNodeList templateTypeArgs = templateType.TemplateArguments != null ? templateType.TemplateArguments : templateType.TemplateParameters;
  10298. strippedArgs.Add(DeepStripModifiers(type.TemplateArguments[i], templateTypeArgs[i], modifiers));
  10299. }
  10300. return type.Template.GetTemplateInstance(type, strippedArgs);
  10301. }
  10302. return type;
  10303. }
  10304. public static TypeNode DeepStripModifiers(TypeNode type, params TypeNode[] modifiers)
  10305. {
  10306. // strip off inner modifiers then outer type modifier if it matches
  10307. OptionalModifier optmod = type as OptionalModifier;
  10308. if(optmod != null)
  10309. {
  10310. TypeNode t = TypeNode.DeepStripModifiers(optmod.ModifiedType, modifiers);
  10311. for(int i = 0; i < modifiers.Length; ++i)
  10312. {
  10313. if(optmod.Modifier == modifiers[i])
  10314. {
  10315. // strip it
  10316. return t;
  10317. }
  10318. }
  10319. return OptionalModifier.For(optmod.Modifier, t);
  10320. }
  10321. RequiredModifier reqmod = type as RequiredModifier;
  10322. if(reqmod != null)
  10323. {
  10324. TypeNode t = TypeNode.DeepStripModifiers(reqmod.ModifiedType, modifiers);
  10325. for(int i = 0; i < modifiers.Length; ++i)
  10326. {
  10327. if(reqmod.Modifier == modifiers[i])
  10328. {
  10329. // strip it
  10330. return t;
  10331. }
  10332. }
  10333. return RequiredModifier.For(reqmod.Modifier, t);
  10334. }
  10335. // For arrays and references, strip the inner type and then reconstruct the array or reference
  10336. ArrayType ar = type as ArrayType;
  10337. if(ar != null)
  10338. {
  10339. TypeNode t = TypeNode.DeepStripModifiers(ar.ElementType, modifiers);
  10340. return t.GetArrayType(1);
  10341. }
  10342. Reference rt = type as Reference;
  10343. if(rt != null)
  10344. {
  10345. TypeNode t = TypeNode.DeepStripModifiers(rt.ElementType, modifiers);
  10346. return t.GetReferenceType();
  10347. }
  10348. // strip template arguments
  10349. if(type.Template != null && type.TemplateArguments != null && type.TemplateArguments.Count > 0)
  10350. {
  10351. TypeNodeList strippedArgs = new TypeNodeList();
  10352. for(int i = 0; i < type.TemplateArguments.Count; i++)
  10353. strippedArgs.Add(DeepStripModifiers(type.TemplateArguments[i], modifiers));
  10354. return type.Template.GetTemplateInstance(type, strippedArgs);
  10355. }
  10356. return type;
  10357. }
  10358. public static bool HasModifier(TypeNode type, TypeNode modifier)
  10359. {
  10360. // Don't look under pointers or refs.
  10361. TypeModifier tmod = type as TypeModifier;
  10362. if(tmod != null)
  10363. {
  10364. if(tmod.Modifier == modifier)
  10365. return true;
  10366. return TypeNode.HasModifier(tmod.ModifiedType, modifier);
  10367. }
  10368. return false;
  10369. }
  10370. public static TypeNode StripModifier(TypeNode type, TypeNode modifier)
  10371. {
  10372. // Don't strip under pointers or refs. We only strip top-level modifiers
  10373. TypeModifier tmod = type as TypeModifier;
  10374. if(tmod != null)
  10375. {
  10376. TypeNode et = TypeNode.StripModifier(tmod.ModifiedType, modifier);
  10377. //^ assert et != null;
  10378. if(tmod.Modifier == modifier)
  10379. return et;
  10380. if(et == tmod.ModifiedType)
  10381. return tmod;
  10382. if(tmod is OptionalModifier)
  10383. return OptionalModifier.For(tmod.Modifier, et);
  10384. return RequiredModifier.For(tmod.Modifier, et);
  10385. }
  10386. return type;
  10387. }
  10388. /// <summary>
  10389. /// Needed whenever we change the id of an existing member
  10390. /// </summary>
  10391. public virtual void ClearMemberTable()
  10392. {
  10393. lock(this)
  10394. {
  10395. this.memberTable = null;
  10396. this.memberCount = 0;
  10397. }
  10398. }
  10399. protected virtual void UpdateMemberTable(int range)
  10400. //^ ensures this.memberTable != null;
  10401. {
  10402. MemberList thisMembers = this.Members;
  10403. lock(this)
  10404. {
  10405. if(this.memberTable == null)
  10406. this.memberTable = new TrivialHashtable(32);
  10407. for(int i = this.memberCount; i < range; i++)
  10408. {
  10409. Member mem = thisMembers[i];
  10410. if(mem == null || mem.Name == null)
  10411. continue;
  10412. MemberList members = (MemberList)this.memberTable[mem.Name.UniqueIdKey];
  10413. if(members == null)
  10414. this.memberTable[mem.Name.UniqueIdKey] = members = new MemberList();
  10415. members.Add(mem);
  10416. }
  10417. this.memberCount = range;
  10418. this.constructors = null;
  10419. }
  10420. }
  10421. protected static MemberList WeedOutNonSpecialMethods(MemberList members, MethodFlags mask)
  10422. {
  10423. if(members == null)
  10424. return null;
  10425. bool membersOK = true;
  10426. for(int i = 0, n = members.Count; i < n; i++)
  10427. {
  10428. Method m = members[i] as Method;
  10429. if(m == null || (m.Flags & mask) == 0)
  10430. {
  10431. membersOK = false;
  10432. break;
  10433. }
  10434. }
  10435. if(membersOK)
  10436. return members;
  10437. MemberList newMembers = new MemberList();
  10438. for(int i = 0, n = members.Count; i < n; i++)
  10439. {
  10440. Method m = members[i] as Method;
  10441. if(m == null || (m.Flags & mask) == 0)
  10442. continue;
  10443. newMembers.Add(m);
  10444. }
  10445. return newMembers;
  10446. }
  10447. public override void WriteDocumentation(XmlTextWriter xwriter)
  10448. {
  10449. base.WriteDocumentation(xwriter);
  10450. MemberList members = this.Members;
  10451. for(int i = 0, n = members == null ? 0 : members.Count; i < n; i++)
  10452. {
  10453. Member mem = members[i];
  10454. if(mem == null)
  10455. continue;
  10456. mem.WriteDocumentation(xwriter);
  10457. }
  10458. }
  10459. public override string ToString()
  10460. {
  10461. return this.GetFullUnmangledNameWithTypeParameters();
  10462. }
  10463. }
  10464. public class Class : TypeNode
  10465. {
  10466. internal readonly static Class DoesNotExist = new Class();
  10467. internal readonly static Class Dummy = new Class();
  10468. internal Class baseClass;
  10469. public Class BaseClassExpression;
  10470. public bool IsAbstractSealedContainerForStatics;
  10471. public Class()
  10472. : base(NodeType.Class)
  10473. {
  10474. }
  10475. public Class(NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
  10476. : base(NodeType.Class, provideNestedTypes, provideAttributes, provideMembers, handle)
  10477. {
  10478. }
  10479. public Class(Module declaringModule, TypeNode declaringType, AttributeList attributes, TypeFlags flags,
  10480. Identifier Namespace, Identifier name, Class baseClass, InterfaceList interfaces, MemberList members)
  10481. : base(declaringModule, declaringType, attributes, flags, Namespace, name, interfaces, members, NodeType.Class)
  10482. {
  10483. this.baseClass = baseClass;
  10484. }
  10485. /// <summary>
  10486. /// The class from which this class has been derived. Null if this class is System.Object.
  10487. /// </summary>
  10488. public virtual Class BaseClass
  10489. {
  10490. get
  10491. {
  10492. return baseClass;
  10493. }
  10494. set
  10495. {
  10496. baseClass = value;
  10497. }
  10498. }
  10499. public override void GetAbstractMethods(MethodList/*!*/ result)
  10500. {
  10501. if(!this.IsAbstract)
  10502. return;
  10503. MethodList candidates = new MethodList();
  10504. if(this.BaseClass != null)
  10505. {
  10506. this.BaseClass.GetAbstractMethods(candidates);
  10507. for(int i = 0, n = candidates.Count; i < n; i++)
  10508. {
  10509. Method meth = candidates[i];
  10510. if(!this.ImplementsMethod(meth, false))
  10511. result.Add(meth);
  10512. }
  10513. }
  10514. //Add any abstract methods declared inside this class
  10515. MemberList members = this.Members;
  10516. for(int i = 0, n = members.Count; i < n; i++)
  10517. {
  10518. Method meth = members[i] as Method;
  10519. if(meth == null)
  10520. continue;
  10521. if(meth.IsAbstract)
  10522. result.Add(meth);
  10523. }
  10524. //For each interface, get abstract methods and keep those that are not implemented by this class or a base class
  10525. InterfaceList interfaces = this.Interfaces;
  10526. if(interfaces != null)
  10527. for(int i = 0, n = interfaces.Count; i < n; i++)
  10528. {
  10529. Interface iface = interfaces[i];
  10530. if(iface == null)
  10531. continue;
  10532. MemberList imembers = iface.Members;
  10533. if(imembers == null)
  10534. continue;
  10535. for(int j = 0, m = imembers.Count; j < m; j++)
  10536. {
  10537. Method meth = imembers[j] as Method;
  10538. if(meth == null)
  10539. continue;
  10540. if(this.ImplementsExplicitly(meth))
  10541. continue;
  10542. if(this.ImplementsMethod(meth, true))
  10543. continue;
  10544. if(this.AlreadyInList(result, meth))
  10545. continue;
  10546. result.Add(meth);
  10547. }
  10548. }
  10549. }
  10550. protected bool AlreadyInList(MethodList list, Method method)
  10551. {
  10552. if(list == null)
  10553. return false;
  10554. for(int i = 0, n = list.Count; i < n; i++)
  10555. {
  10556. if(list[i] == method)
  10557. return true;
  10558. }
  10559. return false;
  10560. }
  10561. }
  10562. public class ClosureClass : Class
  10563. {
  10564. public ClosureClass()
  10565. {
  10566. }
  10567. }
  10568. /// <summary>
  10569. /// Does not model a real type, but leverages the symbol table methods of Class. In other words, this is implementation inheritance, not an ISA relationship.
  10570. /// </summary>
  10571. //TODO: use delegation rather than inheritance to achieve this
  10572. public class Scope : Class
  10573. {
  10574. public Scope()
  10575. {
  10576. }
  10577. public Scope(Scope outerScope)
  10578. {
  10579. this.OuterScope = outerScope;
  10580. }
  10581. protected Scope outerScope;
  10582. public SourceContext LexicalSourceExtent;
  10583. public Scope OuterScope
  10584. {
  10585. get
  10586. {
  10587. if(this.outerScope == null)
  10588. this.outerScope = (Scope)this.baseClass;
  10589. return this.outerScope;
  10590. }
  10591. set
  10592. {
  10593. this.baseClass = this.outerScope = value;
  10594. }
  10595. }
  10596. public virtual TypeNode GetType(Identifier typeName)
  10597. {
  10598. return this.GetNestedType(typeName);
  10599. }
  10600. }
  10601. public class TypeScope : Scope
  10602. {
  10603. public TypeNode Type;
  10604. public TypeScope() { }
  10605. public TypeScope(Scope parentScope, TypeNode/*!*/ type)
  10606. {
  10607. this.baseClass = parentScope;
  10608. this.DeclaringModule = type.DeclaringModule;
  10609. this.Type = type;
  10610. if(type != null && type.PartiallyDefines != null)
  10611. this.Type = type.PartiallyDefines;
  10612. this.templateParameters = type.TemplateParameters;
  10613. if(type != null)
  10614. this.LexicalSourceExtent = type.SourceContext;
  10615. }
  10616. public override MemberList/*!*/ GetMembersNamed(Identifier name)
  10617. {
  10618. TypeNode t = this.Type;
  10619. MemberList result = null;
  10620. while(t != null)
  10621. {
  10622. result = t.GetMembersNamed(name);
  10623. if(result.Count > 0)
  10624. return result;
  10625. t = t.BaseType;
  10626. }
  10627. if(result != null)
  10628. return result;
  10629. return new MemberList();
  10630. }
  10631. public override MemberList Members
  10632. {
  10633. get
  10634. {
  10635. return this.Type.Members;
  10636. }
  10637. set
  10638. {
  10639. base.Members = value;
  10640. }
  10641. }
  10642. }
  10643. public class MethodScope : Scope
  10644. {
  10645. protected Class closureClass;
  10646. public virtual Class ClosureClass
  10647. {
  10648. get
  10649. {
  10650. //if (this.DeclaringMethod == null) return null;
  10651. Class c = this.closureClass;
  10652. if(c == null)
  10653. {
  10654. c = this.closureClass = new ClosureClass();
  10655. c.Name = Identifier.For("closure:" + this.UniqueKey);
  10656. c.BaseClass = CoreSystemTypes.Object;
  10657. Class bclass = this.BaseClass;
  10658. c.DeclaringModule = bclass.DeclaringModule;
  10659. TypeScope tscope = bclass as TypeScope;
  10660. if(tscope != null)
  10661. c.DeclaringType = tscope.Type;
  10662. else
  10663. {
  10664. MethodScope mscope = bclass as MethodScope;
  10665. if(mscope != null)
  10666. c.DeclaringType = mscope.ClosureClass;
  10667. else
  10668. c.DeclaringType = ((BlockScope)bclass).ClosureClass;
  10669. }
  10670. c.IsGeneric = c.DeclaringType.IsGeneric || this.DeclaringMethod.IsGeneric;
  10671. c.TemplateParameters = this.CopyMethodTemplateParameters(c.DeclaringModule, c.DeclaringType);
  10672. c.Flags = TypeFlags.NestedPrivate | TypeFlags.SpecialName | TypeFlags.Sealed;
  10673. c.Interfaces = new InterfaceList();
  10674. if(this.ThisType != null)
  10675. {
  10676. Field f = new Field(c, null, FieldFlags.CompilerControlled | FieldFlags.SpecialName, StandardIds.ThisValue, this.ThisType, null);
  10677. this.ThisField = f;
  10678. c.Members.Add(f);
  10679. }
  10680. }
  10681. return c;
  10682. }
  10683. }
  10684. private TypeNodeList CopyMethodTemplateParameters(Module/*!*/ module, TypeNode/*!*/ type)
  10685. //^ requires this.DeclaringMethod != null;
  10686. {
  10687. TypeNodeList methTemplParams = this.DeclaringMethod.TemplateParameters;
  10688. if(methTemplParams == null || methTemplParams.Count == 0)
  10689. return null;
  10690. this.tpDup = new TemplateParameterDuplicator(module, type);
  10691. return this.tpDup.VisitTypeParameterList(methTemplParams);
  10692. }
  10693. private TemplateParameterDuplicator tpDup;
  10694. private class TemplateParameterDuplicator : Duplicator
  10695. {
  10696. public TemplateParameterDuplicator(Module/*!*/ module, TypeNode/*!*/ type)
  10697. : base(module, type)
  10698. {
  10699. }
  10700. public override TypeNode VisitTypeParameter(TypeNode typeParameter)
  10701. {
  10702. if(typeParameter == null)
  10703. return null;
  10704. TypeNode result = (TypeNode)this.DuplicateFor[typeParameter.UniqueKey];
  10705. if(result != null)
  10706. return result;
  10707. MethodTypeParameter mtp = typeParameter as MethodTypeParameter;
  10708. if(mtp != null)
  10709. {
  10710. TypeParameter tp = new TypeParameter();
  10711. this.DuplicateFor[typeParameter.UniqueKey] = tp;
  10712. tp.Name = mtp.Name;
  10713. tp.Interfaces = this.VisitInterfaceReferenceList(mtp.Interfaces);
  10714. tp.TypeParameterFlags = mtp.TypeParameterFlags;
  10715. tp.DeclaringModule = mtp.DeclaringModule;
  10716. tp.DeclaringMember = this.TargetType;
  10717. result = tp;
  10718. }
  10719. else
  10720. {
  10721. MethodClassParameter mcp = typeParameter as MethodClassParameter;
  10722. if(mcp != null)
  10723. {
  10724. ClassParameter cp = new ClassParameter();
  10725. this.DuplicateFor[typeParameter.UniqueKey] = cp;
  10726. cp.Name = mcp.Name;
  10727. cp.BaseClass = (Class)this.VisitTypeReference(mcp.BaseClass);
  10728. cp.Interfaces = this.VisitInterfaceReferenceList(mcp.Interfaces);
  10729. cp.TypeParameterFlags = mcp.TypeParameterFlags;
  10730. cp.DeclaringModule = mcp.DeclaringModule;
  10731. cp.DeclaringMember = this.TargetType;
  10732. result = cp;
  10733. }
  10734. }
  10735. if(result == null)
  10736. return typeParameter;
  10737. return result;
  10738. }
  10739. public override TypeNode VisitTypeReference(TypeNode type)
  10740. {
  10741. TypeNode result = base.VisitTypeReference(type);
  10742. if(result == type && (type is MethodClassParameter || type is MethodTypeParameter))
  10743. return this.VisitTypeParameter(type);
  10744. return result;
  10745. }
  10746. }
  10747. public virtual Class ClosureClassTemplateInstance
  10748. {
  10749. get
  10750. {
  10751. if(this.closureClassTemplateInstance == null)
  10752. {
  10753. if(this.DeclaringMethod == null || !this.DeclaringMethod.IsGeneric)
  10754. this.closureClassTemplateInstance = this.ClosureClass;
  10755. else
  10756. this.closureClassTemplateInstance = (Class)this.ClosureClass.GetTemplateInstance(this.DeclaringMethod.DeclaringType, this.DeclaringMethod.TemplateParameters);
  10757. }
  10758. return this.closureClassTemplateInstance;
  10759. }
  10760. }
  10761. Class closureClassTemplateInstance;
  10762. public TypeNode FixTypeReference(TypeNode type)
  10763. {
  10764. if(this.tpDup == null)
  10765. return type;
  10766. return this.tpDup.VisitTypeReference(type);
  10767. }
  10768. public virtual Boolean CapturedForClosure
  10769. {
  10770. get
  10771. {
  10772. return this.closureClass != null;
  10773. }
  10774. }
  10775. public UsedNamespaceList UsedNamespaces;
  10776. public Field ThisField;
  10777. public TypeNode ThisType;
  10778. public TypeNode ThisTypeInstance;
  10779. public Method DeclaringMethod;
  10780. public MethodScope() { }
  10781. public MethodScope(Class/*!*/ parentScope, UsedNamespaceList usedNamespaces)
  10782. : this(parentScope, usedNamespaces, null)
  10783. {
  10784. }
  10785. public MethodScope(Class/*!*/ parentScope, UsedNamespaceList usedNamespaces, Method method)
  10786. {
  10787. this.baseClass = parentScope;
  10788. this.UsedNamespaces = usedNamespaces;
  10789. this.DeclaringModule = parentScope.DeclaringModule;
  10790. this.DeclaringMethod = method;
  10791. if(method != null && (method.Flags & MethodFlags.Static) == 0)
  10792. this.ThisType = this.ThisTypeInstance = method.DeclaringType;
  10793. if(method != null)
  10794. this.LexicalSourceExtent = method.SourceContext;
  10795. }
  10796. }
  10797. public class BlockScope : Scope
  10798. {
  10799. public Block AssociatedBlock;
  10800. public bool MembersArePinned;
  10801. public virtual Class ClosureClass
  10802. {
  10803. get
  10804. {
  10805. BlockScope bscope = this.BaseClass as BlockScope;
  10806. if(bscope != null)
  10807. return bscope.ClosureClass;
  10808. MethodScope mscope = this.BaseClass as MethodScope;
  10809. if(mscope != null)
  10810. return mscope.ClosureClass;
  10811. return ((TypeScope)this.BaseClass).Type as Class;
  10812. }
  10813. }
  10814. public virtual Boolean CapturedForClosure
  10815. {
  10816. get
  10817. {
  10818. BlockScope bscope = this.BaseClass as BlockScope;
  10819. if(bscope != null)
  10820. return bscope.CapturedForClosure;
  10821. MethodScope mscope = this.BaseClass as MethodScope;
  10822. if(mscope != null)
  10823. return mscope.CapturedForClosure;
  10824. return false;
  10825. }
  10826. }
  10827. public BlockScope()
  10828. {
  10829. }
  10830. public BlockScope(Scope/*!*/ parentScope, Block associatedBlock)
  10831. {
  10832. this.AssociatedBlock = associatedBlock;
  10833. if(associatedBlock != null)
  10834. {
  10835. associatedBlock.HasLocals = true; //TODO: set only if there really are locals
  10836. associatedBlock.Scope = this;
  10837. }
  10838. this.baseClass = parentScope;
  10839. this.DeclaringModule = parentScope.DeclaringModule;
  10840. if(associatedBlock != null)
  10841. this.LexicalSourceExtent = associatedBlock.SourceContext;
  10842. }
  10843. }
  10844. public class AttributeScope : Scope
  10845. {
  10846. public AttributeNode AssociatedAttribute;
  10847. public AttributeScope(Scope parentScope, AttributeNode associatedAttribute)
  10848. {
  10849. this.AssociatedAttribute = associatedAttribute;
  10850. this.baseClass = parentScope;
  10851. if(associatedAttribute != null)
  10852. this.LexicalSourceExtent = associatedAttribute.SourceContext;
  10853. }
  10854. }
  10855. public class NamespaceScope : Scope
  10856. {
  10857. public Namespace AssociatedNamespace;
  10858. public Module AssociatedModule;
  10859. public TrivialHashtable AliasedType;
  10860. public TrivialHashtable AliasedNamespace;
  10861. protected TrivialHashtable/*!*/ aliasFor = new TrivialHashtable();
  10862. protected TrivialHashtable/*!*/ typeFor = new TrivialHashtable();
  10863. protected TrivialHashtable/*!*/ namespaceFor = new TrivialHashtable();
  10864. protected TrivialHashtable/*!*/ nestedNamespaceFullName = new TrivialHashtable();
  10865. protected readonly static AliasDefinition/*!*/ noSuchAlias = new AliasDefinition();
  10866. public NamespaceScope()
  10867. {
  10868. }
  10869. public NamespaceScope(Scope outerScope, Namespace associatedNamespace, Module associatedModule)
  10870. : base(outerScope)
  10871. {
  10872. //^ base;
  10873. this.AssociatedNamespace = associatedNamespace;
  10874. this.AssociatedModule = associatedModule;
  10875. this.DeclaringModule = associatedModule; //TODO: make this go away
  10876. if(associatedNamespace != null)
  10877. this.LexicalSourceExtent = associatedNamespace.SourceContext;
  10878. }
  10879. public virtual AliasDefinition GetAliasFor(Identifier name)
  10880. {
  10881. if(name == null || this.AssociatedNamespace == null || this.AssociatedModule == null || this.aliasFor == null)
  10882. {
  10883. Debug.Assert(false);
  10884. return null;
  10885. }
  10886. AliasDefinition alias = (AliasDefinition)this.aliasFor[name.UniqueIdKey];
  10887. if(alias == noSuchAlias)
  10888. return null;
  10889. if(alias != null)
  10890. return alias;
  10891. //Check if there is an alias with this uri
  10892. Scope scope = this;
  10893. while(scope != null)
  10894. {
  10895. NamespaceScope nsScope = scope as NamespaceScope;
  10896. if(nsScope != null && nsScope.AssociatedNamespace != null)
  10897. {
  10898. AliasDefinitionList aliases = nsScope.AssociatedNamespace.AliasDefinitions;
  10899. if(aliases != null)
  10900. for(int i = 0, n = aliases.Count; i < n; i++)
  10901. {
  10902. AliasDefinition aliasDef = aliases[i];
  10903. if(aliasDef == null || aliasDef.Alias == null)
  10904. continue;
  10905. if(aliasDef.Alias.UniqueIdKey == name.UniqueIdKey) { alias = aliasDef; goto done; }
  10906. }
  10907. }
  10908. scope = scope.OuterScope;
  10909. }
  10910. done:
  10911. if(alias != null)
  10912. this.aliasFor[name.UniqueIdKey] = alias;
  10913. else
  10914. this.aliasFor[name.UniqueIdKey] = noSuchAlias;
  10915. return alias;
  10916. }
  10917. public virtual AliasDefinition GetConflictingAlias(Identifier name)
  10918. {
  10919. if(name == null || this.typeFor == null || this.AssociatedNamespace == null || this.AssociatedModule == null)
  10920. {
  10921. Debug.Assert(false);
  10922. return null;
  10923. }
  10924. TypeNode type = this.AssociatedModule.GetType(this.AssociatedNamespace.FullNameId, name);
  10925. if(type != null)
  10926. {
  10927. AliasDefinitionList aliases = this.AssociatedNamespace.AliasDefinitions;
  10928. for(int i = 0, n = aliases == null ? 0 : aliases.Count; i < n; i++)
  10929. {
  10930. //^ assert aliases != null;
  10931. AliasDefinition aliasDef = aliases[i];
  10932. if(aliasDef == null || aliasDef.Alias == null)
  10933. continue;
  10934. if(aliasDef.Alias.UniqueIdKey == name.UniqueIdKey)
  10935. return aliasDef;
  10936. }
  10937. }
  10938. Scope scope = this;
  10939. while(scope != null)
  10940. {
  10941. NamespaceScope outerScope = scope.OuterScope as NamespaceScope;
  10942. if(outerScope != null)
  10943. return outerScope.GetConflictingAlias(name);
  10944. scope = scope.OuterScope;
  10945. }
  10946. return null;
  10947. }
  10948. public virtual Identifier GetUriFor(Identifier name)
  10949. {
  10950. AliasDefinition aliasDef = this.GetAliasFor(name);
  10951. if(aliasDef == null)
  10952. return null;
  10953. return aliasDef.AliasedUri;
  10954. }
  10955. public virtual Identifier GetNamespaceFullNameFor(Identifier name)
  10956. {
  10957. if(name == null || this.AssociatedNamespace == null || this.AssociatedModule == null || this.nestedNamespaceFullName == null)
  10958. {
  10959. Debug.Assert(false);
  10960. return null;
  10961. }
  10962. Identifier fullName = (Identifier)this.nestedNamespaceFullName[name.UniqueIdKey];
  10963. if(fullName == Identifier.Empty)
  10964. return null;
  10965. if(fullName != null)
  10966. return fullName;
  10967. //Check if there is an alias with this namespace
  10968. AliasDefinition aliasDef = this.GetAliasFor(name);
  10969. if(aliasDef != null && aliasDef.AliasedUri == null && aliasDef.AliasedType == null)
  10970. return aliasDef.AliasedExpression as Identifier;
  10971. //Check if module has a type with namespace equal to this namespace + name
  10972. fullName = name;
  10973. if(this.AssociatedNamespace.Name != null && this.AssociatedNamespace.Name.UniqueIdKey != Identifier.Empty.UniqueIdKey)
  10974. fullName = Identifier.For(this.AssociatedNamespace.FullName + "." + name);
  10975. if(this.AssociatedModule.IsValidNamespace(fullName))
  10976. {
  10977. this.namespaceFor[fullName.UniqueIdKey] = new TrivialHashtable();
  10978. goto returnFullName;
  10979. }
  10980. // If an inner type shadows an outer namespace, don't return the namespace
  10981. if(this.AssociatedModule.IsValidTypeName(this.AssociatedNamespace.Name, name)) { return null; }
  10982. AssemblyReferenceList arefs = this.AssociatedModule.AssemblyReferences;
  10983. for(int i = 0, n = arefs == null ? 0 : arefs.Count; i < n; i++)
  10984. {
  10985. AssemblyReference ar = arefs[i];
  10986. if(ar == null || ar.Assembly == null)
  10987. continue;
  10988. if(ar.Assembly.IsValidNamespace(fullName))
  10989. goto returnFullName;
  10990. // If an inner type shadows an outer namespace, don't return the namespace
  10991. if(ar.Assembly.IsValidTypeName(this.AssociatedNamespace.Name, name)) { return null; }
  10992. }
  10993. ModuleReferenceList mrefs = this.AssociatedModule.ModuleReferences;
  10994. if(mrefs != null)
  10995. for(int i = 0, n = mrefs.Count; i < n; i++)
  10996. {
  10997. ModuleReference mr = mrefs[i];
  10998. if(mr == null || mr.Module == null)
  10999. continue;
  11000. if(mr.Module.IsValidNamespace(fullName))
  11001. goto returnFullName;
  11002. // If an inner type shadows an outer namespace, don't return the namespace
  11003. if(mr.Module.IsValidTypeName(this.AssociatedNamespace.Name, name)) { return null; }
  11004. }
  11005. Scope scope = this.OuterScope;
  11006. while(scope != null && !(scope is NamespaceScope))
  11007. scope = scope.OuterScope;
  11008. if(scope != null)
  11009. return ((NamespaceScope)scope).GetNamespaceFullNameFor(name);
  11010. return null;
  11011. returnFullName:
  11012. this.nestedNamespaceFullName[name.UniqueIdKey] = fullName;
  11013. return fullName;
  11014. }
  11015. /// <summary>
  11016. /// Search this namespace for a type with this name nested in the given namespace. Also considers used name spaces.
  11017. /// If more than one type is found, a list is returned in duplicates.
  11018. /// </summary>
  11019. public virtual TypeNode GetType(Identifier Namespace, Identifier name, out TypeNodeList duplicates)
  11020. {
  11021. duplicates = null;
  11022. if(Namespace == null || name == null || this.AssociatedNamespace == null || this.AssociatedModule == null)
  11023. {
  11024. Debug.Assert(false);
  11025. return null;
  11026. }
  11027. if(this.namespaceFor == null)
  11028. {
  11029. Debug.Assert(false);
  11030. this.namespaceFor = new TrivialHashtable();
  11031. }
  11032. TrivialHashtable typeFor = (TrivialHashtable)this.namespaceFor[Namespace.UniqueIdKey];
  11033. if(typeFor == null)
  11034. this.namespaceFor[Namespace.UniqueIdKey] = typeFor = new TrivialHashtable();
  11035. TypeNode result = (TypeNode)typeFor[name.UniqueIdKey];
  11036. if(result == Class.DoesNotExist)
  11037. return null;
  11038. if(result != null)
  11039. return result;
  11040. //If the associated module declares a type with the given name in a nested namespace, it wins
  11041. Scope scope = this;
  11042. while(scope != null)
  11043. {
  11044. NamespaceScope nsScope = scope as NamespaceScope;
  11045. if(nsScope != null && nsScope.AssociatedNamespace != null)
  11046. {
  11047. Identifier nestedNamespace = Namespace;
  11048. if(nsScope.AssociatedNamespace.FullNameId != null && nsScope.AssociatedNamespace.FullNameId.UniqueIdKey != Identifier.Empty.UniqueIdKey)
  11049. nestedNamespace = Identifier.For(nsScope.AssociatedNamespace.FullName + "." + Namespace);
  11050. result = this.AssociatedModule.GetType(nestedNamespace, name);
  11051. if(result != null)
  11052. break;
  11053. }
  11054. scope = scope.OuterScope;
  11055. }
  11056. if(result == null)
  11057. {
  11058. //Now get into situations where there might be duplicates.
  11059. duplicates = new TypeNodeList();
  11060. //Check the used namespaces of this and outer namespace scopes
  11061. TrivialHashtable alreadyUsed = new TrivialHashtable();
  11062. scope = this;
  11063. while(scope != null)
  11064. {
  11065. NamespaceScope nsScope = scope as NamespaceScope;
  11066. if(nsScope != null && nsScope.AssociatedNamespace != null)
  11067. {
  11068. UsedNamespaceList usedNamespaces = nsScope.AssociatedNamespace.UsedNamespaces;
  11069. int n = usedNamespaces == null ? 0 : usedNamespaces.Count;
  11070. if(usedNamespaces != null)
  11071. for(int i = 0; i < n; i++)
  11072. {
  11073. UsedNamespace usedNs = usedNamespaces[i];
  11074. if(usedNs == null || usedNs.Namespace == null)
  11075. continue;
  11076. int key = usedNs.Namespace.UniqueIdKey;
  11077. if(alreadyUsed[key] != null)
  11078. continue;
  11079. alreadyUsed[key] = usedNs.Namespace;
  11080. Identifier usedNestedNamespace = Identifier.For(usedNs.Namespace + "." + Namespace);
  11081. result = this.AssociatedModule.GetType(usedNestedNamespace, name);
  11082. if(result != null)
  11083. duplicates.Add(result);
  11084. }
  11085. }
  11086. scope = scope.OuterScope;
  11087. }
  11088. if(duplicates.Count > 0)
  11089. result = duplicates[0];
  11090. }
  11091. if(result == null)
  11092. {
  11093. //The associated module does not have a type by this name, so check its referenced modules and assemblies
  11094. int numDups = 0;
  11095. //Check this namespace and outer namespaces
  11096. scope = this;
  11097. while(scope != null && result == null)
  11098. {
  11099. NamespaceScope nsScope = scope as NamespaceScope;
  11100. if(nsScope != null && nsScope.AssociatedNamespace != null)
  11101. {
  11102. Identifier nestedNamespace = Namespace;
  11103. if(nsScope.AssociatedNamespace.FullNameId != null && nsScope.AssociatedNamespace.FullNameId.UniqueIdKey != Identifier.Empty.UniqueIdKey)
  11104. nestedNamespace = Identifier.For(nsScope.AssociatedNamespace.FullName + "." + Namespace);
  11105. nsScope.GetReferencedTypes(nestedNamespace, name, duplicates);
  11106. numDups = duplicates.Count;
  11107. for(int i = numDups - 1; i >= 0; i--)
  11108. {
  11109. TypeNode dup = duplicates[i];
  11110. if(dup == null || !dup.IsPublic)
  11111. numDups--;
  11112. result = dup;
  11113. }
  11114. }
  11115. scope = scope.OuterScope;
  11116. }
  11117. if(numDups == 0)
  11118. {
  11119. if(duplicates.Count > 0)
  11120. duplicates = new TypeNodeList();
  11121. //Check the used namespaces of this and outer namespace scopes
  11122. TrivialHashtable alreadyUsed = new TrivialHashtable();
  11123. scope = this;
  11124. while(scope != null)
  11125. {
  11126. NamespaceScope nsScope = scope as NamespaceScope;
  11127. if(nsScope != null && nsScope.AssociatedNamespace != null)
  11128. {
  11129. UsedNamespaceList usedNamespaces = this.AssociatedNamespace.UsedNamespaces;
  11130. int n = usedNamespaces == null ? 0 : usedNamespaces.Count;
  11131. if(usedNamespaces != null)
  11132. for(int i = 0; i < n; i++)
  11133. {
  11134. UsedNamespace usedNs = usedNamespaces[i];
  11135. if(usedNs == null)
  11136. continue;
  11137. int key = usedNs.Namespace.UniqueIdKey;
  11138. if(alreadyUsed[key] != null)
  11139. continue;
  11140. alreadyUsed[key] = usedNs.Namespace;
  11141. Identifier usedNestedNamespace = Identifier.For(usedNs.Namespace + "." + Namespace);
  11142. this.GetReferencedTypes(usedNestedNamespace, name, duplicates);
  11143. }
  11144. }
  11145. scope = scope.OuterScope;
  11146. }
  11147. numDups = duplicates.Count;
  11148. for(int i = numDups - 1; i >= 0; i--)
  11149. {
  11150. TypeNode dup = duplicates[i];
  11151. if(dup == null || !dup.IsPublic)
  11152. numDups--;
  11153. result = dup;
  11154. }
  11155. }
  11156. if(numDups <= 1)
  11157. duplicates = null;
  11158. }
  11159. if(result == null)
  11160. typeFor[name.UniqueIdKey] = Class.DoesNotExist;
  11161. else
  11162. typeFor[name.UniqueIdKey] = result;
  11163. return result;
  11164. }
  11165. /// <summary>
  11166. /// Searches this namespace for a type with this name. Also considers aliases and used name spaces, including those of outer namespaces.
  11167. /// If more than one type is found, a list is returned in duplicates. Types defined in the associated
  11168. /// module mask types defined in referenced modules and assemblies. Results are cached and duplicates are returned only when
  11169. /// there is a cache miss.
  11170. /// </summary>
  11171. public virtual TypeNode GetType(Identifier name, out TypeNodeList duplicates)
  11172. {
  11173. return this.GetType(name, out duplicates, false);
  11174. }
  11175. public virtual TypeNode GetType(Identifier name, out TypeNodeList duplicates, bool returnNullIfHiddenByNestedNamespace)
  11176. {
  11177. duplicates = null;
  11178. if(name == null || this.typeFor == null || this.AssociatedNamespace == null || this.AssociatedModule == null)
  11179. {
  11180. Debug.Assert(false);
  11181. return null;
  11182. }
  11183. AssemblyNode associatedAssembly = this.AssociatedModule as AssemblyNode;
  11184. TypeNode result = (TypeNode)this.typeFor[name.UniqueIdKey];
  11185. if(result == Class.DoesNotExist)
  11186. return null;
  11187. if(result != null)
  11188. return result;
  11189. //If the associated module declares a type with the given name in this namespace, it wins
  11190. result = this.AssociatedModule.GetType(this.AssociatedNamespace.FullNameId, name);
  11191. if(result == null && returnNullIfHiddenByNestedNamespace)
  11192. {
  11193. //Do not proceed to outer namespaces or look at aliases. The nested namespace hides these.
  11194. Identifier fullName = name;
  11195. if(this.AssociatedNamespace.FullName != null && this.AssociatedNamespace.Name.UniqueIdKey != Identifier.Empty.UniqueIdKey)
  11196. fullName = Identifier.For(this.AssociatedNamespace.FullName + "." + name);
  11197. if(this.AssociatedModule.IsValidNamespace(fullName))
  11198. result = Class.DoesNotExist;
  11199. }
  11200. if(result == null)
  11201. {
  11202. //If the namespace (or an outer namespace) has an alias definition with this name it wins. (Expected to be mutually exclusive with above.)
  11203. Scope scope = this;
  11204. while(scope != null && result == null)
  11205. {
  11206. NamespaceScope nsScope = scope as NamespaceScope;
  11207. if(nsScope != null && nsScope.AliasedType != null)
  11208. result = (TypeNode)nsScope.AliasedType[name.UniqueIdKey];
  11209. if(result == null && returnNullIfHiddenByNestedNamespace && nsScope != null &&
  11210. nsScope.AliasedNamespace != null && nsScope.AliasedNamespace[name.UniqueIdKey] != null)
  11211. result = Class.DoesNotExist;
  11212. scope = scope.OuterScope;
  11213. }
  11214. }
  11215. if(result == null)
  11216. {
  11217. //Now get into situations where there might be duplicates.
  11218. duplicates = new TypeNodeList();
  11219. //Check the used namespaces of this and outer namespace scopes
  11220. TrivialHashtable alreadyUsed = new TrivialHashtable();
  11221. Scope scope = this;
  11222. while(scope != null)
  11223. {
  11224. NamespaceScope nsScope = scope as NamespaceScope;
  11225. if(nsScope != null && nsScope.AssociatedNamespace != null && nsScope.AssociatedModule != null)
  11226. {
  11227. UsedNamespaceList usedNamespaces = nsScope.AssociatedNamespace.UsedNamespaces;
  11228. int n = usedNamespaces == null ? 0 : usedNamespaces.Count;
  11229. if(usedNamespaces != null)
  11230. for(int i = 0; i < n; i++)
  11231. {
  11232. UsedNamespace usedNs = usedNamespaces[i];
  11233. if(usedNs == null || usedNs.Namespace == null)
  11234. continue;
  11235. int key = usedNs.Namespace.UniqueIdKey;
  11236. if(alreadyUsed[key] != null)
  11237. continue;
  11238. alreadyUsed[key] = usedNs.Namespace;
  11239. result = this.AssociatedModule.GetType(usedNs.Namespace, name);
  11240. //^ assert duplicates != null;
  11241. if(result != null)
  11242. duplicates.Add(result);
  11243. }
  11244. }
  11245. if(returnNullIfHiddenByNestedNamespace)
  11246. break;
  11247. scope = scope.OuterScope;
  11248. }
  11249. if(duplicates.Count > 0)
  11250. result = duplicates[0];
  11251. }
  11252. if(result == null)
  11253. //First see if the the current module has a class by this name in the empty namespace
  11254. result = this.AssociatedModule.GetType(Identifier.Empty, name);
  11255. if(result == null)
  11256. {
  11257. //The associated module does not have a type by this name, so check its referenced modules and assemblies
  11258. //First check this namespace
  11259. this.GetReferencedTypes(this.AssociatedNamespace.FullNameId, name, duplicates);
  11260. int numDups = duplicates.Count;
  11261. if(numDups == 1)
  11262. {
  11263. result = duplicates[0];
  11264. if(this.IsNotAccessible(associatedAssembly, result)) { numDups--; result = null; }
  11265. }
  11266. else
  11267. {
  11268. for(int i = numDups - 1; i >= 0; i--)
  11269. {
  11270. TypeNode dup = duplicates[i];
  11271. if(this.IsNotAccessible(associatedAssembly, dup)) { numDups--; continue; }
  11272. result = dup;
  11273. }
  11274. if(numDups == 0 && duplicates.Count > 0)
  11275. {
  11276. result = duplicates[0];
  11277. numDups = duplicates.Count;
  11278. }
  11279. }
  11280. if(numDups == 0)
  11281. {
  11282. if(duplicates.Count > 0)
  11283. duplicates = new TypeNodeList();
  11284. //Check the used namespaces of this and outer namespace scopes
  11285. TrivialHashtable alreadyUsed = new TrivialHashtable();
  11286. Scope scope = this;
  11287. while(scope != null)
  11288. {
  11289. NamespaceScope nsScope = scope as NamespaceScope;
  11290. if(nsScope != null)
  11291. {
  11292. UsedNamespaceList usedNamespaces = nsScope.AssociatedNamespace.UsedNamespaces;
  11293. int n = usedNamespaces == null ? 0 : usedNamespaces.Count;
  11294. if(usedNamespaces != null)
  11295. for(int i = 0; i < n; i++)
  11296. {
  11297. UsedNamespace usedNs = usedNamespaces[i];
  11298. if(usedNs == null || usedNs.Namespace == null)
  11299. continue;
  11300. int key = usedNs.Namespace.UniqueIdKey;
  11301. if(alreadyUsed[key] != null)
  11302. continue;
  11303. alreadyUsed[key] = usedNs.Namespace;
  11304. this.GetReferencedTypes(usedNs.Namespace, name, duplicates);
  11305. }
  11306. }
  11307. scope = scope.OuterScope;
  11308. if(returnNullIfHiddenByNestedNamespace)
  11309. break;
  11310. }
  11311. numDups = duplicates.Count;
  11312. for(int i = numDups - 1; i >= 0; i--)
  11313. {
  11314. TypeNode dup = duplicates[i];
  11315. if(this.IsNotAccessible(associatedAssembly, dup))
  11316. {
  11317. numDups--;
  11318. continue;
  11319. }
  11320. result = dup;
  11321. }
  11322. }
  11323. if(numDups == 0)
  11324. {
  11325. if(duplicates.Count > 0)
  11326. duplicates = new TypeNodeList();
  11327. this.GetReferencedTypes(Identifier.Empty, name, duplicates);
  11328. numDups = duplicates.Count;
  11329. for(int i = numDups - 1; i >= 0; i--)
  11330. {
  11331. TypeNode dup = duplicates[i];
  11332. if(this.IsNotAccessible(associatedAssembly, dup))
  11333. {
  11334. numDups--;
  11335. continue;
  11336. }
  11337. result = dup;
  11338. }
  11339. }
  11340. if(numDups <= 1)
  11341. duplicates = null;
  11342. }
  11343. if(result == null)
  11344. this.typeFor[name.UniqueIdKey] = Class.DoesNotExist;
  11345. else
  11346. this.typeFor[name.UniqueIdKey] = result;
  11347. if(result == Class.DoesNotExist)
  11348. return null;
  11349. if(duplicates != null && duplicates.Count > 1 && this.AssociatedNamespace != null && this.AssociatedNamespace.Name != null && this.AssociatedNamespace.Name.Name != null)
  11350. {
  11351. result = null;
  11352. for(int i = 0, n = duplicates.Count; i < n; i++)
  11353. {
  11354. TypeNode t = duplicates[i];
  11355. if(t == null || t.Namespace == null)
  11356. continue;
  11357. if(this.AssociatedNamespace.Name.Name.StartsWith(t.Namespace.Name))
  11358. {
  11359. if(result != null)
  11360. {
  11361. result = null;
  11362. break;
  11363. }
  11364. result = t;
  11365. }
  11366. }
  11367. if(result != null)
  11368. duplicates = null;
  11369. else
  11370. result = duplicates[0];
  11371. }
  11372. return result;
  11373. }
  11374. private bool IsNotAccessible(AssemblyNode associatedAssembly, TypeNode dup)
  11375. {
  11376. if(dup == null)
  11377. return false;
  11378. return !dup.IsPublic && (associatedAssembly == null ||
  11379. !associatedAssembly.MayAccessInternalTypesOf(dup.DeclaringModule as AssemblyNode)) && !this.AssociatedModule.ContainsModule(dup.DeclaringModule);
  11380. }
  11381. /// <summary>
  11382. /// Searches the module and assembly references of the associated module to find types
  11383. /// </summary>
  11384. public virtual void GetReferencedTypes(Identifier Namespace, Identifier name, TypeNodeList types)
  11385. {
  11386. if(Namespace == null || name == null || types == null || this.AssociatedModule == null) { Debug.Assert(false); return; }
  11387. AssemblyReferenceList arefs = this.AssociatedModule.AssemblyReferences;
  11388. for(int i = 0, n = arefs == null ? 0 : arefs.Count; i < n; i++)
  11389. {
  11390. AssemblyReference ar = arefs[i];
  11391. if(ar == null || ar.Assembly == null)
  11392. continue;
  11393. TypeNode t = ar.Assembly.GetType(Namespace, name);
  11394. if(t == null)
  11395. continue;
  11396. //TODO: deal with type forwarding
  11397. types.Add(t);
  11398. }
  11399. ModuleReferenceList mrefs = this.AssociatedModule.ModuleReferences;
  11400. if(mrefs != null)
  11401. for(int i = 0, n = mrefs.Count; i < n; i++)
  11402. {
  11403. ModuleReference mr = mrefs[i];
  11404. if(mr == null || mr.Module == null)
  11405. continue;
  11406. TypeNode t = mr.Module.GetType(Namespace, name);
  11407. if(t == null)
  11408. continue;
  11409. types.Add(t);
  11410. }
  11411. }
  11412. }
  11413. public class DelegateNode : TypeNode
  11414. {
  11415. internal static readonly DelegateNode/*!*/ Dummy = new DelegateNode();
  11416. protected ParameterList parameters;
  11417. public virtual ParameterList Parameters
  11418. {
  11419. get
  11420. {
  11421. ParameterList pList = this.parameters;
  11422. if(pList == null)
  11423. {
  11424. MemberList members = this.Members; //Evaluate for side effect
  11425. if(members != null)
  11426. members = null;
  11427. lock(this)
  11428. {
  11429. if(this.parameters != null)
  11430. return this.parameters;
  11431. MemberList invokers = this.GetMembersNamed(StandardIds.Invoke);
  11432. for(int i = 0, n = invokers.Count; i < n; i++)
  11433. {
  11434. Method m = invokers[i] as Method;
  11435. if(m == null)
  11436. continue;
  11437. this.parameters = pList = m.Parameters;
  11438. this.returnType = m.ReturnType;
  11439. break;
  11440. }
  11441. }
  11442. }
  11443. return pList;
  11444. }
  11445. set
  11446. {
  11447. this.parameters = value;
  11448. }
  11449. }
  11450. protected TypeNode returnType;
  11451. public virtual TypeNode ReturnType
  11452. {
  11453. get
  11454. {
  11455. TypeNode rt = this.returnType;
  11456. if(rt == null)
  11457. {
  11458. ParameterList pars = this.Parameters; //Evaluate for side effect
  11459. if(pars != null)
  11460. pars = null;
  11461. rt = this.returnType;
  11462. }
  11463. return rt;
  11464. }
  11465. set
  11466. {
  11467. this.returnType = value;
  11468. }
  11469. }
  11470. public TypeNode ReturnTypeExpression;
  11471. public DelegateNode()
  11472. : base(NodeType.DelegateNode)
  11473. {
  11474. }
  11475. public DelegateNode(NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
  11476. : base(NodeType.DelegateNode, provideNestedTypes, provideAttributes, provideMembers, handle)
  11477. {
  11478. }
  11479. public DelegateNode(Module declaringModule, TypeNode declaringType, AttributeList attributes, TypeFlags flags,
  11480. Identifier Namespace, Identifier name, TypeNode returnType, ParameterList parameters)
  11481. : base(declaringModule, declaringType, attributes, flags, Namespace, name, null, null, NodeType.DelegateNode)
  11482. {
  11483. this.parameters = parameters;
  11484. this.returnType = returnType;
  11485. }
  11486. private bool membersAlreadyProvided;
  11487. public virtual void ProvideMembers()
  11488. {
  11489. if(this.membersAlreadyProvided)
  11490. return;
  11491. this.membersAlreadyProvided = true;
  11492. this.memberCount = 0;
  11493. MemberList members = this.members = new MemberList();
  11494. //ctor
  11495. ParameterList parameters = new ParameterList();
  11496. parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Object, CoreSystemTypes.Object, null, null));
  11497. parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Method, CoreSystemTypes.IntPtr, null, null));
  11498. InstanceInitializer ctor = new InstanceInitializer(this, null, parameters, null);
  11499. ctor.Flags |= MethodFlags.Public | MethodFlags.HideBySig;
  11500. ctor.CallingConvention = CallingConventionFlags.HasThis;
  11501. ctor.ImplFlags = MethodImplFlags.Runtime;
  11502. members.Add(ctor);
  11503. //Invoke
  11504. Method invoke = new Method(this, null, StandardIds.Invoke, this.Parameters, this.ReturnType, null);
  11505. invoke.Flags = MethodFlags.Public | MethodFlags.HideBySig | MethodFlags.Virtual;
  11506. invoke.CallingConvention = CallingConventionFlags.HasThis;
  11507. invoke.ImplFlags = MethodImplFlags.Runtime;
  11508. members.Add(invoke);
  11509. //BeginInvoke
  11510. ParameterList dparams = this.parameters;
  11511. int n = dparams == null ? 0 : dparams.Count;
  11512. parameters = new ParameterList();
  11513. for(int i = 0; i < n; i++)
  11514. {
  11515. //^ assert dparams != null;
  11516. Parameter p = dparams[i];
  11517. if(p == null)
  11518. continue;
  11519. parameters.Add((Parameter)p.Clone());
  11520. }
  11521. parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.callback, SystemTypes.AsyncCallback, null, null));
  11522. parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Object, CoreSystemTypes.Object, null, null));
  11523. Method beginInvoke = new Method(this, null, StandardIds.BeginInvoke, parameters, SystemTypes.IASyncResult, null);
  11524. beginInvoke.Flags = MethodFlags.Public | MethodFlags.HideBySig | MethodFlags.NewSlot | MethodFlags.Virtual;
  11525. beginInvoke.CallingConvention = CallingConventionFlags.HasThis;
  11526. beginInvoke.ImplFlags = MethodImplFlags.Runtime;
  11527. members.Add(beginInvoke);
  11528. //EndInvoke
  11529. parameters = new ParameterList();
  11530. for(int i = 0; i < n; i++)
  11531. {
  11532. Parameter p = dparams[i];
  11533. if(p == null || p.Type == null || !(p.Type is Reference))
  11534. continue;
  11535. parameters.Add((Parameter)p.Clone());
  11536. }
  11537. parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.result, SystemTypes.IASyncResult, null, null));
  11538. Method endInvoke = new Method(this, null, StandardIds.EndInvoke, parameters, this.ReturnType, null);
  11539. endInvoke.Flags = MethodFlags.Public | MethodFlags.HideBySig | MethodFlags.NewSlot | MethodFlags.Virtual;
  11540. endInvoke.CallingConvention = CallingConventionFlags.HasThis;
  11541. endInvoke.ImplFlags = MethodImplFlags.Runtime;
  11542. members.Add(endInvoke);
  11543. if(!this.IsGeneric)
  11544. {
  11545. TypeNodeList templPars = this.TemplateParameters;
  11546. for(int i = 0, m = templPars == null ? 0 : templPars.Count; i < m; i++)
  11547. {
  11548. //^ assert templPars != null;
  11549. TypeNode tpar = templPars[i];
  11550. if(tpar == null)
  11551. continue;
  11552. members.Add(tpar);
  11553. }
  11554. }
  11555. }
  11556. }
  11557. public class FunctionType : DelegateNode
  11558. {
  11559. private FunctionType(Identifier name, TypeNode returnType, ParameterList parameters)
  11560. {
  11561. this.Flags = TypeFlags.Public | TypeFlags.Sealed;
  11562. this.Namespace = StandardIds.StructuralTypes;
  11563. this.Name = name;
  11564. this.returnType = returnType;
  11565. this.parameters = parameters;
  11566. }
  11567. public static FunctionType For(TypeNode returnType, ParameterList parameters, TypeNode referringType)
  11568. {
  11569. if(returnType == null || referringType == null)
  11570. return null;
  11571. Module module = referringType.DeclaringModule;
  11572. if(module == null)
  11573. return null;
  11574. TypeFlags visibility = returnType.Flags & TypeFlags.VisibilityMask;
  11575. StringBuilder name = new StringBuilder();
  11576. name.Append("Function_");
  11577. name.Append(returnType.Name.ToString());
  11578. int n = parameters == null ? 0 : parameters.Count;
  11579. if(parameters != null)
  11580. for(int i = 0; i < n; i++)
  11581. {
  11582. Parameter p = parameters[i];
  11583. if(p == null || p.Type == null)
  11584. continue;
  11585. visibility = TypeNode.GetVisibilityIntersection(visibility, p.Type.Flags & TypeFlags.VisibilityMask);
  11586. name.Append('_');
  11587. name.Append(p.Type.Name.ToString());
  11588. }
  11589. FunctionType func = null;
  11590. int count = 0;
  11591. string fNameString = name.ToString();
  11592. Identifier fName = Identifier.For(fNameString);
  11593. TypeNode result = module.GetStructurallyEquivalentType(StandardIds.StructuralTypes, fName);
  11594. while(result != null)
  11595. {
  11596. //Mangled name is the same. But mangling is not unique (types are not qualified with assemblies), so check for equality.
  11597. func = result as FunctionType;
  11598. bool goodMatch = func != null && func.ReturnType == returnType;
  11599. if(goodMatch)
  11600. {
  11601. //^ assert func != null;
  11602. ParameterList fpars = func.Parameters;
  11603. int m = fpars == null ? 0 : fpars.Count;
  11604. goodMatch = n == m;
  11605. if(parameters != null && fpars != null)
  11606. for(int i = 0; i < n && goodMatch; i++)
  11607. {
  11608. Parameter p = parameters[i];
  11609. Parameter q = fpars[i];
  11610. goodMatch = p != null && q != null && p.Type == q.Type;
  11611. }
  11612. }
  11613. if(goodMatch)
  11614. return func;
  11615. //Mangle some more
  11616. fName = Identifier.For(fNameString + (++count).ToString());
  11617. result = module.GetStructurallyEquivalentType(StandardIds.StructuralTypes, fName);
  11618. }
  11619. if(parameters != null)
  11620. {
  11621. ParameterList clonedParams = new ParameterList();
  11622. for(int i = 0; i < n; i++)
  11623. {
  11624. Parameter p = parameters[i];
  11625. if(p != null)
  11626. p = (Parameter)p.Clone();
  11627. clonedParams.Add(p);
  11628. }
  11629. parameters = clonedParams;
  11630. }
  11631. func = new FunctionType(fName, returnType, parameters);
  11632. func.DeclaringModule = module;
  11633. switch(visibility)
  11634. {
  11635. case TypeFlags.NestedFamANDAssem:
  11636. case TypeFlags.NestedFamily:
  11637. case TypeFlags.NestedPrivate:
  11638. referringType.Members.Add(func);
  11639. func.DeclaringType = referringType;
  11640. func.Flags &= ~TypeFlags.VisibilityMask;
  11641. func.Flags |= TypeFlags.NestedPrivate;
  11642. break;
  11643. default:
  11644. module.Types.Add(func);
  11645. break;
  11646. }
  11647. module.StructurallyEquivalentType[func.Name.UniqueIdKey] = func;
  11648. func.ProvideMembers();
  11649. return func;
  11650. }
  11651. public override bool IsStructural
  11652. {
  11653. get { return true; }
  11654. }
  11655. protected TypeNodeList structuralElementTypes;
  11656. public override TypeNodeList StructuralElementTypes
  11657. {
  11658. get
  11659. {
  11660. TypeNodeList result = this.structuralElementTypes;
  11661. if(result != null)
  11662. return result;
  11663. this.structuralElementTypes = result = new TypeNodeList();
  11664. result.Add(this.ReturnType);
  11665. ParameterList pars = this.Parameters;
  11666. for(int i = 0, n = pars == null ? 0 : pars.Count; i < n; i++)
  11667. {
  11668. Parameter par = pars[i];
  11669. if(par == null || par.Type == null)
  11670. continue;
  11671. result.Add(par.Type);
  11672. }
  11673. return result;
  11674. }
  11675. }
  11676. public override bool IsStructurallyEquivalentTo(TypeNode type)
  11677. {
  11678. if(type == null)
  11679. return false;
  11680. if(this == type)
  11681. return true;
  11682. FunctionType t = type as FunctionType;
  11683. if(t == null)
  11684. return false;
  11685. if(this.Template != null)
  11686. return base.IsStructurallyEquivalentTo(t);
  11687. if(this.Flags != t.Flags)
  11688. return false;
  11689. if(this.ReturnType == null || t.ReturnType == null)
  11690. return false;
  11691. if(this.ReturnType != t.ReturnType && !this.ReturnType.IsStructurallyEquivalentTo(t.ReturnType))
  11692. return false;
  11693. if(this.Parameters == null)
  11694. return t.Parameters == null;
  11695. if(t.Parameters == null)
  11696. return false;
  11697. int n = this.Parameters.Count;
  11698. if(n != t.Parameters.Count)
  11699. return false;
  11700. for(int i = 0; i < n; i++)
  11701. {
  11702. Parameter p1 = this.Parameters[i];
  11703. Parameter p2 = t.Parameters[i];
  11704. if(p1 == null || p2 == null)
  11705. return false;
  11706. if(p1.Type == null || p2.Type == null)
  11707. return false;
  11708. if(p1.Type != p2.Type && !p1.Type.IsStructurallyEquivalentTo(p2.Type))
  11709. return false;
  11710. }
  11711. return true;
  11712. }
  11713. }
  11714. public class EnumNode : TypeNode
  11715. {
  11716. internal readonly static EnumNode/*!*/ Dummy = new EnumNode();
  11717. public EnumNode()
  11718. : base(NodeType.EnumNode)
  11719. {
  11720. this.typeCode = ElementType.ValueType;
  11721. this.Flags |= TypeFlags.Sealed;
  11722. }
  11723. public EnumNode(NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
  11724. : base(NodeType.EnumNode, provideNestedTypes, provideAttributes, provideMembers, handle)
  11725. {
  11726. this.typeCode = ElementType.ValueType;
  11727. this.Flags |= TypeFlags.Sealed;
  11728. }
  11729. public EnumNode(Module declaringModule, TypeNode declaringType, AttributeList attributes, TypeFlags typeAttributes,
  11730. Identifier Namespace, Identifier name, InterfaceList interfaces, MemberList members)
  11731. : base(declaringModule, declaringType, attributes, typeAttributes, Namespace, name, interfaces, members, NodeType.EnumNode)
  11732. {
  11733. this.typeCode = ElementType.ValueType;
  11734. this.Flags |= TypeFlags.Sealed;
  11735. }
  11736. public override bool IsUnmanaged
  11737. {
  11738. get
  11739. {
  11740. return true;
  11741. }
  11742. }
  11743. protected internal TypeNode underlyingType;
  11744. /// <summary>
  11745. /// The underlying integer type used to store values of this enumeration.
  11746. /// </summary>
  11747. public virtual TypeNode UnderlyingType
  11748. {
  11749. get
  11750. {
  11751. if(this.underlyingType == null)
  11752. {
  11753. if(this.template is EnumNode)
  11754. return this.underlyingType = ((EnumNode)this.template).UnderlyingType;
  11755. this.underlyingType = CoreSystemTypes.Int32;
  11756. MemberList members = this.Members;
  11757. for(int i = 0, n = members.Count; i < n; i++)
  11758. {
  11759. Member mem = members[i];
  11760. Field f = mem as Field;
  11761. if(f != null && (f.Flags & FieldFlags.Static) == 0)
  11762. return this.underlyingType = f.Type;
  11763. }
  11764. }
  11765. return this.underlyingType;
  11766. }
  11767. set
  11768. {
  11769. this.underlyingType = value;
  11770. MemberList members = this.Members;
  11771. for(int i = 0, n = members.Count; i < n; i++)
  11772. {
  11773. Member mem = members[i];
  11774. Field f = mem as Field;
  11775. if(f != null && (f.Flags & FieldFlags.Static) == 0)
  11776. {
  11777. f.Type = value;
  11778. return;
  11779. }
  11780. }
  11781. this.Members.Add(new Field(this, null, FieldFlags.Public | FieldFlags.SpecialName | FieldFlags.RTSpecialName, StandardIds.Value__, value, null));
  11782. }
  11783. }
  11784. public TypeNode UnderlyingTypeExpression;
  11785. }
  11786. public class Interface : TypeNode
  11787. {
  11788. protected TrivialHashtable jointMemberTable;
  11789. protected MemberList jointDefaultMembers;
  11790. internal static readonly Interface/*!*/ Dummy = new Interface();
  11791. public Interface()
  11792. : base(NodeType.Interface)
  11793. {
  11794. this.Flags = TypeFlags.Interface | TypeFlags.Abstract;
  11795. }
  11796. public Interface(InterfaceList baseInterfaces)
  11797. : base(NodeType.Interface)
  11798. {
  11799. this.Interfaces = baseInterfaces;
  11800. this.Flags = TypeFlags.Interface | TypeFlags.Abstract;
  11801. }
  11802. public Interface(InterfaceList baseInterfaces, NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
  11803. : base(NodeType.Interface, provideNestedTypes, provideAttributes, provideMembers, handle)
  11804. {
  11805. this.Interfaces = baseInterfaces;
  11806. }
  11807. public Interface(Module declaringModule, TypeNode declaringType, AttributeList attributes, TypeFlags flags,
  11808. Identifier Namespace, Identifier name, InterfaceList baseInterfaces, MemberList members)
  11809. : base(declaringModule, declaringType, attributes, flags, Namespace, name, baseInterfaces, members, NodeType.Interface)
  11810. {
  11811. this.Flags |= TypeFlags.Interface | TypeFlags.Abstract;
  11812. }
  11813. public override void GetAbstractMethods(MethodList/*!*/ result)
  11814. {
  11815. MemberList members = this.Members;
  11816. if(members == null)
  11817. return;
  11818. for(int i = 0, n = members.Count; i < n; i++)
  11819. {
  11820. Method m = members[i] as Method;
  11821. if(m != null)
  11822. result.Add(m);
  11823. }
  11824. }
  11825. public virtual MemberList GetAllDefaultMembers()
  11826. {
  11827. if(this.jointDefaultMembers == null)
  11828. {
  11829. this.jointDefaultMembers = new MemberList();
  11830. MemberList defs = this.DefaultMembers;
  11831. for(int i = 0, n = defs == null ? 0 : defs.Count; i < n; i++)
  11832. this.jointDefaultMembers.Add(defs[i]);
  11833. InterfaceList interfaces = this.Interfaces;
  11834. if(interfaces != null)
  11835. for(int j = 0, m = interfaces.Count; j < m; j++)
  11836. {
  11837. Interface iface = interfaces[j];
  11838. if(iface == null)
  11839. continue;
  11840. defs = iface.GetAllDefaultMembers();
  11841. if(defs == null)
  11842. continue;
  11843. for(int i = 0, n = defs.Count; i < n; i++)
  11844. this.jointDefaultMembers.Add(defs[i]);
  11845. }
  11846. }
  11847. return this.jointDefaultMembers;
  11848. }
  11849. public virtual MemberList GetAllMembersNamed(Identifier/*!*/ name)
  11850. {
  11851. lock(this)
  11852. {
  11853. TrivialHashtable memberTable = this.jointMemberTable;
  11854. if(memberTable == null)
  11855. this.jointMemberTable = memberTable = new TrivialHashtable();
  11856. MemberList result = (MemberList)memberTable[name.UniqueIdKey];
  11857. if(result != null)
  11858. return result;
  11859. memberTable[name.UniqueIdKey] = result = new MemberList();
  11860. MemberList members = this.GetMembersNamed(name);
  11861. for(int i = 0, n = members == null ? 0 : members.Count; i < n; i++)
  11862. result.Add(members[i]);
  11863. InterfaceList interfaces = this.Interfaces;
  11864. for(int j = 0, m = interfaces == null ? 0 : interfaces.Count; j < m; j++)
  11865. {
  11866. Interface iface = interfaces[j];
  11867. if(iface == null)
  11868. continue;
  11869. members = iface.GetAllMembersNamed(name);
  11870. if(members != null)
  11871. for(int i = 0, n = members.Count; i < n; i++)
  11872. result.Add(members[i]);
  11873. }
  11874. members = CoreSystemTypes.Object.GetMembersNamed(name);
  11875. for(int i = 0, n = members == null ? 0 : members.Count; i < n; i++)
  11876. result.Add(members[i]);
  11877. return result;
  11878. }
  11879. }
  11880. }
  11881. public class Struct : TypeNode
  11882. {
  11883. internal static readonly Struct/*!*/ Dummy = new Struct();
  11884. public Struct()
  11885. : base(NodeType.Struct)
  11886. {
  11887. this.typeCode = ElementType.ValueType;
  11888. this.Flags = TypeFlags.Sealed;
  11889. }
  11890. public Struct(NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
  11891. : base(NodeType.Struct, provideNestedTypes, provideAttributes, provideMembers, handle)
  11892. {
  11893. this.typeCode = ElementType.ValueType;
  11894. }
  11895. public Struct(Module declaringModule, TypeNode declaringType, AttributeList attributes, TypeFlags flags,
  11896. Identifier Namespace, Identifier name, InterfaceList interfaces, MemberList members)
  11897. : base(declaringModule, declaringType, attributes, flags, Namespace, name, interfaces, members, NodeType.Struct)
  11898. {
  11899. this.Interfaces = interfaces;
  11900. this.typeCode = ElementType.ValueType;
  11901. this.Flags |= TypeFlags.Sealed;
  11902. }
  11903. protected bool cachedUnmanaged;
  11904. protected bool cachedUnmanagedIsValid;
  11905. /// <summary>True if the type is a value type containing only fields of unmanaged types.</summary>
  11906. public override bool IsUnmanaged
  11907. {
  11908. get
  11909. {
  11910. if(this.cachedUnmanagedIsValid)
  11911. return this.cachedUnmanaged;
  11912. this.cachedUnmanagedIsValid = true; //protect against cycles
  11913. this.cachedUnmanaged = true; //Self references should not influence the answer
  11914. if(this.IsPrimitive)
  11915. return this.cachedUnmanaged = true;
  11916. MemberList members = this.Members;
  11917. bool isUnmanaged = true;
  11918. for(int i = 0, n = members == null ? 0 : members.Count; i < n; i++)
  11919. {
  11920. Field f = members[i] as Field;
  11921. if(f == null || f.Type == null || f.IsStatic)
  11922. continue;
  11923. if(!f.Type.IsUnmanaged) { isUnmanaged = false; break; }
  11924. }
  11925. return this.cachedUnmanaged = isUnmanaged;
  11926. }
  11927. }
  11928. }
  11929. public interface ITypeParameter
  11930. {
  11931. Member DeclaringMember { get; set; }
  11932. /// <summary>
  11933. /// Zero based index into a parameter list containing this parameter.
  11934. /// </summary>
  11935. int ParameterListIndex { get; set; }
  11936. TypeParameterFlags TypeParameterFlags { get; set; }
  11937. bool IsUnmanaged { get; }
  11938. Identifier Name { get; }
  11939. Module DeclaringModule { get; }
  11940. TypeNode DeclaringType { get; }
  11941. SourceContext SourceContext { get; }
  11942. int UniqueKey { get; }
  11943. TypeFlags Flags { get; }
  11944. }
  11945. public class TypeParameter : Interface, ITypeParameter
  11946. {
  11947. public TypeParameter()
  11948. : base()
  11949. {
  11950. this.NodeType = NodeType.TypeParameter;
  11951. this.Flags = TypeFlags.Interface | TypeFlags.NestedPublic | TypeFlags.Abstract;
  11952. this.Namespace = StandardIds.TypeParameter;
  11953. }
  11954. public TypeParameter(InterfaceList baseInterfaces, NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
  11955. : base(baseInterfaces, provideNestedTypes, provideAttributes, provideMembers, handle)
  11956. {
  11957. this.NodeType = NodeType.TypeParameter;
  11958. this.Flags = TypeFlags.Interface | TypeFlags.NestedPublic | TypeFlags.Abstract;
  11959. this.Namespace = StandardIds.TypeParameter;
  11960. }
  11961. public Member DeclaringMember
  11962. {
  11963. get { return this.declaringMember; }
  11964. set { this.declaringMember = value; }
  11965. }
  11966. private Member declaringMember;
  11967. public override Type GetRuntimeType()
  11968. {
  11969. TypeNode t = this.DeclaringMember as TypeNode;
  11970. if(t == null)
  11971. return null;
  11972. Type rt = t.GetRuntimeType();
  11973. if(rt == null)
  11974. return null;
  11975. System.Type[] typeParameters = rt.GetGenericArguments();
  11976. if(this.ParameterListIndex >= typeParameters.Length)
  11977. return null;
  11978. return typeParameters[this.ParameterListIndex];
  11979. }
  11980. /// <summary>
  11981. /// Zero based index into a parameter list containing this parameter.
  11982. /// </summary>
  11983. public int ParameterListIndex
  11984. {
  11985. get { return this.parameterListIndex; }
  11986. set { this.parameterListIndex = value; }
  11987. }
  11988. private int parameterListIndex;
  11989. public TypeParameterFlags TypeParameterFlags
  11990. {
  11991. get
  11992. {
  11993. return this.typeParameterFlags;
  11994. }
  11995. set
  11996. {
  11997. this.typeParameterFlags = value;
  11998. }
  11999. }
  12000. private TypeParameterFlags typeParameterFlags;
  12001. public override bool IsStructural
  12002. {
  12003. get { return true; }
  12004. }
  12005. /// <summary>True if the type serves as a parameter to a type template.</summary>
  12006. public override bool IsTemplateParameter
  12007. {
  12008. get
  12009. {
  12010. return true;
  12011. }
  12012. }
  12013. public override bool IsValueType
  12014. {
  12015. get
  12016. {
  12017. return ((this.TypeParameterFlags & TypeParameterFlags.ValueTypeConstraint) == TypeParameterFlags.ValueTypeConstraint);
  12018. }
  12019. }
  12020. public override XmlNode Documentation
  12021. {
  12022. get
  12023. {
  12024. if(this.documentation == null && this.declaringMember != null && this.Name != null)
  12025. {
  12026. XmlNode parentDoc = this.declaringMember.Documentation;
  12027. if(parentDoc != null && parentDoc.HasChildNodes)
  12028. {
  12029. string myName = this.Name.Name;
  12030. foreach(XmlNode child in parentDoc.ChildNodes)
  12031. {
  12032. if(child.Name == "typeparam" && child.Attributes != null)
  12033. {
  12034. foreach(XmlAttribute attr in child.Attributes)
  12035. {
  12036. if(attr != null && attr.Name == "name" && attr.Value == myName)
  12037. return this.documentation = child;
  12038. }
  12039. }
  12040. }
  12041. }
  12042. }
  12043. return this.documentation;
  12044. }
  12045. set
  12046. {
  12047. this.documentation = value;
  12048. }
  12049. }
  12050. public override string HelpText
  12051. {
  12052. get
  12053. {
  12054. if(this.helpText == null)
  12055. {
  12056. XmlNode doc = this.Documentation;
  12057. if(doc != null)
  12058. this.helpText = doc.InnerText;
  12059. }
  12060. return this.helpText;
  12061. }
  12062. set
  12063. {
  12064. this.helpText = value;
  12065. }
  12066. }
  12067. protected internal TypeNodeList structuralElementTypes;
  12068. public override TypeNodeList StructuralElementTypes
  12069. {
  12070. get
  12071. {
  12072. TypeNodeList result = this.structuralElementTypes;
  12073. if(result != null)
  12074. return result;
  12075. this.structuralElementTypes = result = new TypeNodeList();
  12076. if(this.BaseType != null)
  12077. result.Add(this.BaseType);
  12078. InterfaceList interfaces = this.Interfaces;
  12079. for(int i = 0, n = interfaces == null ? 0 : interfaces.Count; i < n; i++)
  12080. {
  12081. Interface iface = interfaces[i];
  12082. if(iface == null)
  12083. continue;
  12084. result.Add(iface);
  12085. }
  12086. return result;
  12087. }
  12088. }
  12089. internal override void AppendDocumentIdMangledName(StringBuilder/*!*/ sb, TypeNodeList methodTypeParameters, TypeNodeList typeParameters)
  12090. {
  12091. if(TargetPlatform.GenericTypeNamesMangleChar != 0)
  12092. {
  12093. int n = methodTypeParameters == null ? 0 : methodTypeParameters.Count;
  12094. for(int i = 0; i < n; i++)
  12095. {
  12096. //^ assert methodTypeParameters != null;
  12097. TypeNode mpar = methodTypeParameters[i];
  12098. if(mpar != this)
  12099. continue;
  12100. sb.Append(TargetPlatform.GenericTypeNamesMangleChar);
  12101. sb.Append(TargetPlatform.GenericTypeNamesMangleChar);
  12102. sb.Append(i);
  12103. return;
  12104. }
  12105. n = typeParameters == null ? 0 : typeParameters.Count;
  12106. for(int i = 0; i < n; i++)
  12107. {
  12108. TypeNode tpar = typeParameters[i];
  12109. if(tpar != this)
  12110. continue;
  12111. sb.Append(TargetPlatform.GenericTypeNamesMangleChar);
  12112. sb.Append(i);
  12113. return;
  12114. }
  12115. sb.Append("not found:");
  12116. }
  12117. sb.Append(this.FullName);
  12118. }
  12119. public override string GetFullUnmangledNameWithoutTypeParameters()
  12120. {
  12121. return this.GetUnmangledNameWithoutTypeParameters();
  12122. }
  12123. public override string GetFullUnmangledNameWithTypeParameters()
  12124. {
  12125. return this.GetUnmangledNameWithTypeParameters();
  12126. }
  12127. public override bool IsStructurallyEquivalentTo(TypeNode type)
  12128. {
  12129. if(null == (object)type)
  12130. return false;
  12131. if(this == type)
  12132. return true;
  12133. ITypeParameter itype = type as ITypeParameter;
  12134. if(null == (object)itype)
  12135. return false;
  12136. if(this.Name != null && type.Name != null && this.Name.UniqueIdKey != type.Name.UniqueIdKey)
  12137. {
  12138. if(this.DeclaringMember == itype.DeclaringMember)
  12139. return false;
  12140. }
  12141. TypeNode bType = this.BaseType;
  12142. TypeNode tbType = type.BaseType;
  12143. if(null == (object)bType)
  12144. bType = CoreSystemTypes.Object;
  12145. if(null == (object)tbType)
  12146. tbType = CoreSystemTypes.Object;
  12147. if(bType != tbType /*&& !bType.IsStructurallyEquivalentTo(tbType)*/)
  12148. return false;
  12149. if(this.Interfaces == null)
  12150. return type.Interfaces == null || type.Interfaces.Count == 0;
  12151. if(type.Interfaces == null)
  12152. return this.Interfaces.Count == 0;
  12153. int n = this.Interfaces.Count;
  12154. if(n != type.Interfaces.Count)
  12155. return false;
  12156. for(int i = 0; i < n; i++)
  12157. {
  12158. Interface i1 = this.Interfaces[i];
  12159. Interface i2 = type.Interfaces[i];
  12160. if(null == (object)i1 || null == (object)i2)
  12161. return false;
  12162. if(i1 != i2 /*&& !i1.IsStructurallyEquivalentTo(i2)*/)
  12163. return false;
  12164. }
  12165. return true;
  12166. }
  12167. Module ITypeParameter.DeclaringModule { get { return this.DeclaringModule; } }
  12168. TypeFlags ITypeParameter.Flags { get { return this.Flags; } }
  12169. SourceContext ITypeParameter.SourceContext { get { return this.SourceContext; } }
  12170. }
  12171. public class MethodTypeParameter : TypeParameter
  12172. {
  12173. public MethodTypeParameter()
  12174. : base()
  12175. {
  12176. this.NodeType = NodeType.TypeParameter;
  12177. this.Flags = TypeFlags.Interface | TypeFlags.NestedPublic | TypeFlags.Abstract;
  12178. this.Namespace = StandardIds.TypeParameter;
  12179. }
  12180. public MethodTypeParameter(InterfaceList baseInterfaces, NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
  12181. : base(baseInterfaces, provideNestedTypes, provideAttributes, provideMembers, handle)
  12182. {
  12183. this.NodeType = NodeType.TypeParameter;
  12184. this.Flags = TypeFlags.Interface | TypeFlags.NestedPublic | TypeFlags.Abstract;
  12185. this.Namespace = StandardIds.TypeParameter;
  12186. }
  12187. public override Type GetRuntimeType()
  12188. {
  12189. Method m = this.DeclaringMember as Method;
  12190. if(m == null)
  12191. return null;
  12192. System.Reflection.MethodInfo mi = m.GetMethodInfo();
  12193. if(mi == null)
  12194. return null;
  12195. System.Type[] typeParameters = mi.GetGenericArguments();
  12196. if(this.ParameterListIndex >= typeParameters.Length)
  12197. return null;
  12198. return typeParameters[this.ParameterListIndex];
  12199. }
  12200. public override bool IsStructurallyEquivalentTo(TypeNode type)
  12201. {
  12202. if(object.ReferenceEquals(this, type))
  12203. return true;
  12204. ITypeParameter tp = type as ITypeParameter;
  12205. if(tp == null)
  12206. return false;
  12207. if(this.ParameterListIndex == tp.ParameterListIndex && this.DeclaringMember == tp.DeclaringMember)
  12208. return true;
  12209. return base.IsStructurallyEquivalentTo(type as MethodTypeParameter);
  12210. }
  12211. }
  12212. public class ClassParameter : Class, ITypeParameter
  12213. {
  12214. protected TrivialHashtable jointMemberTable;
  12215. public ClassParameter()
  12216. : base()
  12217. {
  12218. this.NodeType = NodeType.ClassParameter;
  12219. this.baseClass = CoreSystemTypes.Object;
  12220. this.Flags = TypeFlags.NestedPublic | TypeFlags.Abstract;
  12221. this.Namespace = StandardIds.TypeParameter;
  12222. }
  12223. public ClassParameter(NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
  12224. : base(provideNestedTypes, provideAttributes, provideMembers, handle)
  12225. {
  12226. this.NodeType = NodeType.ClassParameter;
  12227. this.baseClass = CoreSystemTypes.Object;
  12228. this.Flags = TypeFlags.NestedPrivate | TypeFlags.Abstract | TypeFlags.SpecialName;
  12229. this.Namespace = StandardIds.TypeParameter;
  12230. }
  12231. public Member DeclaringMember
  12232. {
  12233. get { return this.declaringMember; }
  12234. set { this.declaringMember = value; }
  12235. }
  12236. private Member declaringMember;
  12237. public virtual MemberList GetAllMembersNamed(Identifier/*!*/ name)
  12238. {
  12239. lock(this)
  12240. {
  12241. TrivialHashtable memberTable = this.jointMemberTable;
  12242. if(memberTable == null)
  12243. this.jointMemberTable = memberTable = new TrivialHashtable();
  12244. MemberList result = (MemberList)memberTable[name.UniqueIdKey];
  12245. if(result != null)
  12246. return result;
  12247. memberTable[name.UniqueIdKey] = result = new MemberList();
  12248. TypeNode t = this;
  12249. while(t != null)
  12250. {
  12251. MemberList members = t.GetMembersNamed(name);
  12252. if(members != null)
  12253. for(int i = 0, n = members.Count; i < n; i++)
  12254. result.Add(members[i]);
  12255. t = t.BaseType;
  12256. }
  12257. InterfaceList interfaces = this.Interfaces;
  12258. if(interfaces != null)
  12259. for(int j = 0, m = interfaces.Count; j < m; j++)
  12260. {
  12261. Interface iface = interfaces[j];
  12262. if(iface == null)
  12263. continue;
  12264. members = iface.GetAllMembersNamed(name);
  12265. if(members != null)
  12266. for(int i = 0, n = members == null ? 0 : members.Count; i < n; i++)
  12267. result.Add(members[i]);
  12268. }
  12269. members = CoreSystemTypes.Object.GetMembersNamed(name);
  12270. if(members != null)
  12271. for(int i = 0, n = members.Count; i < n; i++)
  12272. result.Add(members[i]);
  12273. return result;
  12274. }
  12275. }
  12276. public override Type GetRuntimeType()
  12277. {
  12278. TypeNode t = this.DeclaringMember as TypeNode;
  12279. if(t == null)
  12280. return null;
  12281. Type rt = t.GetRuntimeType();
  12282. if(rt == null)
  12283. return null;
  12284. System.Type[] typeParameters = rt.GetGenericArguments();
  12285. if(this.ParameterListIndex >= typeParameters.Length)
  12286. return null;
  12287. return typeParameters[this.ParameterListIndex];
  12288. }
  12289. /// <summary>
  12290. /// Zero based index into a parameter list containing this parameter.
  12291. /// </summary>
  12292. public int ParameterListIndex
  12293. {
  12294. get { return this.parameterListIndex; }
  12295. set { this.parameterListIndex = value; }
  12296. }
  12297. private int parameterListIndex;
  12298. public TypeParameterFlags TypeParameterFlags
  12299. {
  12300. get { return this.typeParameterFlags; }
  12301. set { this.typeParameterFlags = value; }
  12302. }
  12303. private TypeParameterFlags typeParameterFlags;
  12304. public override bool IsValueType
  12305. {
  12306. get
  12307. {
  12308. return ((this.typeParameterFlags & TypeParameterFlags.SpecialConstraintMask) == TypeParameterFlags.ValueTypeConstraint);
  12309. }
  12310. }
  12311. public override bool IsStructural
  12312. {
  12313. get { return true; }
  12314. }
  12315. /// <summary>True if the type serves as a parameter to a type template.</summary>
  12316. public override bool IsTemplateParameter
  12317. {
  12318. get
  12319. {
  12320. return true;
  12321. }
  12322. }
  12323. public override XmlNode Documentation
  12324. {
  12325. get
  12326. {
  12327. if(this.documentation == null && this.declaringMember != null && this.Name != null)
  12328. {
  12329. XmlNode parentDoc = this.declaringMember.Documentation;
  12330. if(parentDoc != null && parentDoc.HasChildNodes)
  12331. {
  12332. string myName = this.Name.Name;
  12333. foreach(XmlNode child in parentDoc.ChildNodes)
  12334. {
  12335. if(child.Name == "typeparam" && child.Attributes != null)
  12336. {
  12337. foreach(XmlAttribute attr in child.Attributes)
  12338. {
  12339. if(attr != null && attr.Name == "name" && attr.Value == myName)
  12340. return this.documentation = child;
  12341. }
  12342. }
  12343. }
  12344. }
  12345. }
  12346. return this.documentation;
  12347. }
  12348. set
  12349. {
  12350. this.documentation = value;
  12351. }
  12352. }
  12353. public override string HelpText
  12354. {
  12355. get
  12356. {
  12357. if(this.helpText == null)
  12358. {
  12359. XmlNode doc = this.Documentation;
  12360. if(doc != null)
  12361. this.helpText = doc.InnerText;
  12362. }
  12363. return this.helpText;
  12364. }
  12365. set
  12366. {
  12367. this.helpText = value;
  12368. }
  12369. }
  12370. protected internal TypeNodeList structuralElementTypes;
  12371. public override TypeNodeList StructuralElementTypes
  12372. {
  12373. get
  12374. {
  12375. TypeNodeList result = this.structuralElementTypes;
  12376. if(result != null)
  12377. return result;
  12378. this.structuralElementTypes = result = new TypeNodeList();
  12379. if(this.BaseType != null)
  12380. result.Add(this.BaseType);
  12381. InterfaceList interfaces = this.Interfaces;
  12382. for(int i = 0, n = interfaces == null ? 0 : interfaces.Count; i < n; i++)
  12383. {
  12384. Interface iface = interfaces[i];
  12385. if(iface == null)
  12386. continue;
  12387. result.Add(iface);
  12388. }
  12389. return result;
  12390. }
  12391. }
  12392. internal override void AppendDocumentIdMangledName(StringBuilder/*!*/ sb, TypeNodeList methodTypeParameters, TypeNodeList typeParameters)
  12393. {
  12394. if(TargetPlatform.GenericTypeNamesMangleChar != 0)
  12395. {
  12396. int n = methodTypeParameters == null ? 0 : methodTypeParameters.Count;
  12397. for(int i = 0; i < n; i++)
  12398. {
  12399. //^ assert methodTypeParameters != null;
  12400. TypeNode mpar = methodTypeParameters[i];
  12401. if(mpar != this)
  12402. continue;
  12403. sb.Append(TargetPlatform.GenericTypeNamesMangleChar);
  12404. sb.Append(TargetPlatform.GenericTypeNamesMangleChar);
  12405. sb.Append(i);
  12406. return;
  12407. }
  12408. n = typeParameters == null ? 0 : typeParameters.Count;
  12409. for(int i = 0; i < n; i++)
  12410. {
  12411. TypeNode tpar = typeParameters[i];
  12412. if(tpar != this)
  12413. continue;
  12414. sb.Append(TargetPlatform.GenericTypeNamesMangleChar);
  12415. sb.Append(i);
  12416. return;
  12417. }
  12418. sb.Append("not found:");
  12419. }
  12420. sb.Append(this.FullName);
  12421. }
  12422. public override string GetFullUnmangledNameWithoutTypeParameters()
  12423. {
  12424. return this.GetUnmangledNameWithoutTypeParameters();
  12425. }
  12426. public override string GetFullUnmangledNameWithTypeParameters()
  12427. {
  12428. return this.GetUnmangledNameWithTypeParameters();
  12429. }
  12430. public override bool IsStructurallyEquivalentTo(TypeNode type)
  12431. {
  12432. if(null == (object)type)
  12433. return false;
  12434. if(this == type)
  12435. return true;
  12436. ITypeParameter itype = type as ITypeParameter;
  12437. if(null == (object)itype)
  12438. return false;
  12439. if(this.Name != null && type.Name != null && this.Name.UniqueIdKey != type.Name.UniqueIdKey)
  12440. {
  12441. if(this.DeclaringMember == itype.DeclaringMember)
  12442. return false;
  12443. }
  12444. TypeNode bType = this.BaseType;
  12445. TypeNode tbType = type.BaseType;
  12446. if(null == (object)bType)
  12447. bType = CoreSystemTypes.Object;
  12448. if(null == (object)tbType)
  12449. tbType = CoreSystemTypes.Object;
  12450. if(bType != tbType /*&& !bType.IsStructurallyEquivalentTo(tbType)*/)
  12451. return false;
  12452. if(this.Interfaces == null)
  12453. return type.Interfaces == null || type.Interfaces.Count == 0;
  12454. if(type.Interfaces == null)
  12455. return this.Interfaces.Count == 0;
  12456. int n = this.Interfaces.Count;
  12457. if(n != type.Interfaces.Count)
  12458. return false;
  12459. for(int i = 0; i < n; i++)
  12460. {
  12461. Interface i1 = this.Interfaces[i];
  12462. Interface i2 = type.Interfaces[i];
  12463. if(null == (object)i1 || null == (object)i2)
  12464. return false;
  12465. if(i1 != i2 /*&& !i1.IsStructurallyEquivalentTo(i2)*/)
  12466. return false;
  12467. }
  12468. return true;
  12469. }
  12470. SourceContext ITypeParameter.SourceContext { get { return this.SourceContext; } }
  12471. Module ITypeParameter.DeclaringModule { get { return this.DeclaringModule; } }
  12472. TypeFlags ITypeParameter.Flags { get { return this.Flags; } }
  12473. }
  12474. public class MethodClassParameter : ClassParameter
  12475. {
  12476. public MethodClassParameter()
  12477. : base()
  12478. {
  12479. this.NodeType = NodeType.ClassParameter;
  12480. this.baseClass = CoreSystemTypes.Object;
  12481. this.Flags = TypeFlags.NestedPublic | TypeFlags.Abstract;
  12482. this.Namespace = StandardIds.TypeParameter;
  12483. }
  12484. public override Type GetRuntimeType()
  12485. {
  12486. Method m = this.DeclaringMember as Method;
  12487. if(m == null)
  12488. return null;
  12489. System.Reflection.MethodInfo mi = m.GetMethodInfo();
  12490. if(mi == null)
  12491. return null;
  12492. System.Type[] typeParameters = mi.GetGenericArguments();
  12493. if(this.ParameterListIndex >= typeParameters.Length)
  12494. return null;
  12495. return typeParameters[this.ParameterListIndex];
  12496. }
  12497. public override bool IsStructurallyEquivalentTo(TypeNode type)
  12498. {
  12499. if(object.ReferenceEquals(this, type))
  12500. return true;
  12501. ITypeParameter tp = type as ITypeParameter;
  12502. if(tp == null)
  12503. return false;
  12504. if(this.ParameterListIndex == tp.ParameterListIndex /* && this.DeclaringMember == tp.DeclaringMember*/)
  12505. return true;
  12506. return base.IsStructurallyEquivalentTo(type as MethodClassParameter);
  12507. }
  12508. }
  12509. public class ArrayType : TypeNode
  12510. {
  12511. private TypeNode/*!*/ elementType;
  12512. private int rank;
  12513. private int[] lowerBounds;
  12514. private int[] sizes;
  12515. internal ArrayType()
  12516. : base(NodeType.ArrayType)
  12517. {
  12518. }
  12519. internal ArrayType(TypeNode/*!*/ elementType, int rank)
  12520. : this(elementType, rank, new int[0], new int[0])
  12521. {
  12522. if(rank == 1)
  12523. this.typeCode = Metadata.ElementType.SzArray;
  12524. else
  12525. this.typeCode = Metadata.ElementType.Array;
  12526. }
  12527. internal ArrayType(TypeNode/*!*/ elementType, int rank, int[] sizes)
  12528. : this(elementType, rank, sizes, new int[0])
  12529. {
  12530. }
  12531. internal ArrayType(TypeNode/*!*/ elementType, int rank, int[] sizes, int[] lowerBounds)
  12532. : base(null, null, null, elementType.Flags, null, null, null, null, NodeType.ArrayType)
  12533. {
  12534. Debug.Assert(elementType != null);
  12535. this.rank = rank;
  12536. this.elementType = elementType;
  12537. this.DeclaringModule = elementType.DeclaringModule;
  12538. this.lowerBounds = lowerBounds;
  12539. this.sizes = sizes;
  12540. if(rank == 1)
  12541. this.typeCode = Metadata.ElementType.SzArray;
  12542. else
  12543. this.typeCode = Metadata.ElementType.Array;
  12544. if(elementType == null || elementType.Name == null)
  12545. return;
  12546. StringBuilder name = new StringBuilder(this.ElementType.Name.ToString());
  12547. name.Append('[');
  12548. int k = this.Sizes == null ? 0 : this.Sizes.Length;
  12549. int m = this.LowerBounds == null ? 0 : this.LowerBounds.Length;
  12550. for(int i = 0, n = this.Rank; i < n; i++)
  12551. {
  12552. if(i < k && this.Sizes[i] != 0)
  12553. {
  12554. if(i < m && this.LowerBounds[i] != 0)
  12555. {
  12556. name.Append(this.LowerBounds[i]);
  12557. name.Append(':');
  12558. }
  12559. name.Append(this.Sizes[i]);
  12560. }
  12561. if(i < n - 1)
  12562. name.Append(',');
  12563. }
  12564. name.Append(']');
  12565. this.Name = Identifier.For(name.ToString());
  12566. this.Namespace = elementType.Namespace;
  12567. }
  12568. public TypeNode/*!*/ ElementType
  12569. {
  12570. get { return this.elementType; }
  12571. set { this.elementType = value; }
  12572. }
  12573. /// <summary>The interfaces implemented by this class or struct, or the extended by this interface.</summary>
  12574. public override InterfaceList Interfaces
  12575. {
  12576. get
  12577. {
  12578. if(this.interfaces == null)
  12579. {
  12580. this.interfaces = new InterfaceList(new[] { SystemTypes.ICloneable,
  12581. SystemTypes.IList, SystemTypes.ICollection, SystemTypes.IEnumerable });
  12582. if(this.Rank == 1)
  12583. {
  12584. if(SystemTypes.GenericIEnumerable != null && SystemTypes.GenericIEnumerable.DeclaringModule == CoreSystemTypes.SystemAssembly)
  12585. {
  12586. this.interfaces.Add((Interface)SystemTypes.GenericIEnumerable.GetTemplateInstance(this, elementType));
  12587. if(SystemTypes.GenericICollection != null)
  12588. this.interfaces.Add((Interface)SystemTypes.GenericICollection.GetTemplateInstance(this, elementType));
  12589. if(SystemTypes.GenericIList != null)
  12590. this.interfaces.Add((Interface)SystemTypes.GenericIList.GetTemplateInstance(this, elementType));
  12591. }
  12592. }
  12593. }
  12594. return this.interfaces;
  12595. }
  12596. set { this.interfaces = value; }
  12597. }
  12598. public int Rank
  12599. {
  12600. get { return this.rank; }
  12601. set { this.rank = value; }
  12602. }
  12603. public int[] LowerBounds
  12604. {
  12605. get { return this.lowerBounds; }
  12606. set { this.lowerBounds = value; }
  12607. }
  12608. public int[] Sizes
  12609. {
  12610. get { return this.sizes; }
  12611. set { this.sizes = value; }
  12612. }
  12613. public bool IsSzArray()
  12614. {
  12615. return this.typeCode == Metadata.ElementType.SzArray;
  12616. }
  12617. private MemberList ctorList = null;
  12618. private MemberList getterList = null;
  12619. private MemberList setterList = null;
  12620. private MemberList addressList = null;
  12621. public override MemberList Members
  12622. {
  12623. get
  12624. {
  12625. if(this.members == null || this.membersBeingPopulated)
  12626. {
  12627. lock(this)
  12628. {
  12629. if(this.members == null)
  12630. {
  12631. this.membersBeingPopulated = true;
  12632. MemberList members = this.members = new MemberList();
  12633. members.Add(this.Constructor);
  12634. //^ assume this.ctorList != null && this.ctorList.Length > 1;
  12635. members.Add(this.ctorList[1]);
  12636. members.Add(this.Getter);
  12637. members.Add(this.Setter);
  12638. members.Add(this.Address);
  12639. this.membersBeingPopulated = false;
  12640. }
  12641. }
  12642. }
  12643. return this.members;
  12644. }
  12645. set
  12646. {
  12647. this.members = value;
  12648. }
  12649. }
  12650. public override string/*!*/ FullName
  12651. {
  12652. get
  12653. {
  12654. if(this.ElementType != null && this.ElementType.DeclaringType != null)
  12655. return this.ElementType.DeclaringType.FullName + "+" + (this.Name == null ? "" : this.Name.ToString());
  12656. else if(this.Namespace != null && this.Namespace.UniqueIdKey != Identifier.Empty.UniqueIdKey)
  12657. return this.Namespace.ToString() + "." + (this.Name == null ? "" : this.Name.ToString());
  12658. else if(this.Name != null)
  12659. return this.Name.ToString();
  12660. else
  12661. return "";
  12662. }
  12663. }
  12664. internal override void AppendDocumentIdMangledName(StringBuilder/*!*/ sb, TypeNodeList methodTypeParameters, TypeNodeList typeParameters)
  12665. {
  12666. if(this.ElementType == null)
  12667. return;
  12668. this.ElementType.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
  12669. sb.Append('[');
  12670. int k = this.Sizes == null ? 0 : this.Sizes.Length;
  12671. int m = this.LowerBounds == null ? 0 : this.LowerBounds.Length;
  12672. for(int i = 0, n = this.Rank; i < n; i++)
  12673. {
  12674. if(i < k && this.Sizes[i] != 0)
  12675. {
  12676. if(i < m && this.LowerBounds[i] != 0)
  12677. {
  12678. sb.Append(this.LowerBounds[i]);
  12679. sb.Append(':');
  12680. }
  12681. sb.Append(this.Sizes[i]);
  12682. }
  12683. if(i < n - 1)
  12684. sb.Append(',');
  12685. }
  12686. sb.Append(']');
  12687. }
  12688. public virtual void SetLowerBoundToUnknown()
  12689. {
  12690. Debug.Assert(this.Rank == 1);
  12691. this.typeCode = Metadata.ElementType.Array;
  12692. }
  12693. public virtual int GetLowerBound(int dimension)
  12694. {
  12695. if(this.LowerBounds == null || this.LowerBounds.Length <= dimension)
  12696. return 0;
  12697. return this.LowerBounds[dimension];
  12698. }
  12699. public virtual int GetSize(int dimension)
  12700. {
  12701. if(this.Sizes == null || this.Sizes.Length <= dimension)
  12702. return 0;
  12703. return this.Sizes[dimension];
  12704. }
  12705. public override MemberList/*!*/ GetMembersNamed(Identifier name)
  12706. {
  12707. if(name == null)
  12708. return new MemberList();
  12709. if(name.UniqueIdKey == StandardIds.Get.UniqueIdKey)
  12710. {
  12711. if(this.getterList == null)
  12712. {
  12713. Method getter = this.Getter;
  12714. if(getter != null)
  12715. getter = null;
  12716. //^ assume this.getterList != null;
  12717. }
  12718. return this.getterList;
  12719. }
  12720. if(name.UniqueIdKey == StandardIds.Set.UniqueIdKey)
  12721. {
  12722. if(this.setterList == null)
  12723. {
  12724. Method setter = this.Setter;
  12725. if(setter != null)
  12726. setter = null;
  12727. //^ assume this.setterList != null;
  12728. }
  12729. return this.setterList;
  12730. }
  12731. if(name.UniqueIdKey == StandardIds.Ctor.UniqueIdKey)
  12732. {
  12733. if(this.ctorList == null)
  12734. {
  12735. Method ctor = this.Constructor;
  12736. if(ctor != null)
  12737. ctor = null;
  12738. //^ assume this.ctorList != null;
  12739. }
  12740. return this.ctorList;
  12741. }
  12742. if(name.UniqueIdKey == StandardIds.Address.UniqueIdKey)
  12743. {
  12744. if(this.addressList == null)
  12745. {
  12746. Method addr = this.Address;
  12747. if(addr != null)
  12748. addr = null;
  12749. //^ assume this.addressList != null;
  12750. }
  12751. return this.addressList;
  12752. }
  12753. return new MemberList();
  12754. }
  12755. public override Type GetRuntimeType()
  12756. {
  12757. if(this.runtimeType == null)
  12758. {
  12759. if(this.ElementType == null)
  12760. return null;
  12761. Type eType = this.ElementType.GetRuntimeType();
  12762. if(eType == null)
  12763. return null;
  12764. if(this.IsSzArray())
  12765. this.runtimeType = eType.MakeArrayType();
  12766. else
  12767. this.runtimeType = eType.MakeArrayType(this.Rank);
  12768. }
  12769. return this.runtimeType;
  12770. }
  12771. public Method Constructor
  12772. {
  12773. get
  12774. {
  12775. if(this.ctorList == null)
  12776. {
  12777. lock(this)
  12778. {
  12779. if(this.ctorList == null)
  12780. {
  12781. InstanceInitializer ctor = new InstanceInitializer();
  12782. ctor.DeclaringType = this;
  12783. ctor.Flags |= MethodFlags.Public;
  12784. int n = this.Rank;
  12785. ctor.Parameters = new ParameterList();
  12786. for(int i = 0; i < n; i++)
  12787. {
  12788. Parameter par = new Parameter();
  12789. par.DeclaringMethod = ctor;
  12790. par.Type = CoreSystemTypes.Int32;
  12791. ctor.Parameters.Add(par);
  12792. }
  12793. this.ctorList = new MemberList();
  12794. this.ctorList.Add(ctor);
  12795. ctor = new InstanceInitializer();
  12796. ctor.DeclaringType = this;
  12797. ctor.Flags |= MethodFlags.Public;
  12798. n = n * 2;
  12799. ctor.Parameters = new ParameterList();
  12800. for(int i = 0; i < n; i++)
  12801. {
  12802. Parameter par = new Parameter();
  12803. par.Type = CoreSystemTypes.Int32;
  12804. par.DeclaringMethod = ctor;
  12805. ctor.Parameters.Add(par);
  12806. }
  12807. this.ctorList.Add(ctor);
  12808. }
  12809. }
  12810. }
  12811. return (Method)this.ctorList[0];
  12812. }
  12813. }
  12814. public Method Getter
  12815. {
  12816. get
  12817. {
  12818. if(this.getterList == null)
  12819. {
  12820. lock(this)
  12821. {
  12822. if(this.getterList == null)
  12823. {
  12824. Method getter = new Method();
  12825. getter.Name = StandardIds.Get;
  12826. getter.DeclaringType = this;
  12827. getter.CallingConvention = CallingConventionFlags.HasThis;
  12828. getter.Flags = MethodFlags.Public;
  12829. getter.Parameters = new ParameterList();
  12830. for(int i = 0, n = this.Rank; i < n; i++)
  12831. {
  12832. Parameter par = new Parameter();
  12833. par.Type = CoreSystemTypes.Int32;
  12834. par.DeclaringMethod = getter;
  12835. getter.Parameters.Add(par);
  12836. }
  12837. getter.ReturnType = this.ElementType;
  12838. this.getterList = new MemberList();
  12839. this.getterList.Add(getter);
  12840. }
  12841. }
  12842. }
  12843. return (Method)this.getterList[0];
  12844. }
  12845. }
  12846. public Method Setter
  12847. {
  12848. get
  12849. {
  12850. if(this.setterList == null)
  12851. {
  12852. lock(this)
  12853. {
  12854. if(this.setterList == null)
  12855. {
  12856. Method setter = new Method();
  12857. setter.Name = StandardIds.Set;
  12858. setter.DeclaringType = this;
  12859. setter.CallingConvention = CallingConventionFlags.HasThis;
  12860. setter.Flags = MethodFlags.Public;
  12861. setter.Parameters = new ParameterList();
  12862. Parameter par;
  12863. for(int i = 0, n = this.Rank; i < n; i++)
  12864. {
  12865. par = new Parameter();
  12866. par.Type = CoreSystemTypes.Int32;
  12867. par.DeclaringMethod = setter;
  12868. setter.Parameters.Add(par);
  12869. }
  12870. par = new Parameter();
  12871. par.Type = this.ElementType;
  12872. par.DeclaringMethod = setter;
  12873. setter.Parameters.Add(par);
  12874. setter.ReturnType = CoreSystemTypes.Void;
  12875. this.setterList = new MemberList();
  12876. this.setterList.Add(setter);
  12877. }
  12878. }
  12879. }
  12880. return (Method)this.setterList[0];
  12881. }
  12882. }
  12883. public Method Address
  12884. {
  12885. get
  12886. {
  12887. if(this.addressList == null)
  12888. {
  12889. lock(this)
  12890. {
  12891. if(this.addressList == null)
  12892. {
  12893. Method address = new Method();
  12894. address.Name = StandardIds.Address;
  12895. address.DeclaringType = this;
  12896. address.CallingConvention = CallingConventionFlags.HasThis;
  12897. address.Flags = MethodFlags.Public;
  12898. address.Parameters = new ParameterList();
  12899. for(int i = 0, n = this.Rank; i < n; i++)
  12900. {
  12901. Parameter par = new Parameter();
  12902. par.Type = CoreSystemTypes.Int32;
  12903. par.DeclaringMethod = address;
  12904. address.Parameters.Add(par);
  12905. }
  12906. address.ReturnType = this.ElementType.GetReferenceType();
  12907. this.addressList = new MemberList();
  12908. this.addressList.Add(address);
  12909. }
  12910. }
  12911. }
  12912. return (Method)this.addressList[0];
  12913. }
  12914. }
  12915. public override bool IsAssignableTo(TypeNode targetType)
  12916. {
  12917. if(targetType == null)
  12918. return false;
  12919. if(targetType == this || targetType == CoreSystemTypes.Object || targetType == CoreSystemTypes.Array || targetType == SystemTypes.ICloneable)
  12920. return true;
  12921. if(CoreSystemTypes.Array.IsAssignableTo(targetType))
  12922. return true;
  12923. if(targetType.Template != null && SystemTypes.GenericIEnumerable != null && SystemTypes.GenericIEnumerable.DeclaringModule == CoreSystemTypes.SystemAssembly)
  12924. {
  12925. if(targetType.Template == SystemTypes.GenericIEnumerable || targetType.Template == SystemTypes.GenericICollection ||
  12926. targetType.Template == SystemTypes.GenericIList)
  12927. {
  12928. if(targetType.TemplateArguments == null || targetType.TemplateArguments.Count != 1)
  12929. {
  12930. Debug.Assert(false);
  12931. return false;
  12932. }
  12933. TypeNode ienumElementType = targetType.TemplateArguments[0];
  12934. if(this.ElementType == ienumElementType)
  12935. return true;
  12936. if(this.ElementType.IsValueType)
  12937. return false;
  12938. return this.ElementType.IsAssignableTo(ienumElementType);
  12939. }
  12940. }
  12941. ArrayType targetArrayType = targetType as ArrayType;
  12942. if(targetArrayType == null)
  12943. return false;
  12944. if(this.Rank != 1 || targetArrayType.Rank != 1)
  12945. return false;
  12946. TypeNode thisElementType = this.ElementType;
  12947. if(thisElementType == null)
  12948. return false;
  12949. if(thisElementType == targetArrayType.ElementType)
  12950. return true;
  12951. if(thisElementType.IsValueType)
  12952. return false;
  12953. return thisElementType.IsAssignableTo(targetArrayType.ElementType);
  12954. }
  12955. public override bool IsStructural
  12956. {
  12957. get { return true; }
  12958. }
  12959. protected TypeNodeList structuralElementTypes;
  12960. public override TypeNodeList StructuralElementTypes
  12961. {
  12962. get
  12963. {
  12964. TypeNodeList result = this.structuralElementTypes;
  12965. if(result != null)
  12966. return result;
  12967. this.structuralElementTypes = result = new TypeNodeList();
  12968. result.Add(this.ElementType);
  12969. return result;
  12970. }
  12971. }
  12972. public override bool IsStructurallyEquivalentTo(TypeNode type)
  12973. {
  12974. if(type == null)
  12975. return false;
  12976. if(this == type)
  12977. return true;
  12978. ArrayType t = type as ArrayType;
  12979. if(t == null)
  12980. return false;
  12981. if(this.Rank != t.Rank)
  12982. return false;
  12983. if(this.ElementType == null || t.ElementType == null)
  12984. return false;
  12985. if(this.ElementType != t.ElementType && !this.ElementType.IsStructurallyEquivalentTo(t.ElementType))
  12986. return false;
  12987. if(this.Sizes == null)
  12988. return t.Sizes == null;
  12989. if(t.Sizes == null)
  12990. return false;
  12991. int n = this.Sizes.Length;
  12992. if(n != t.Sizes.Length)
  12993. return false;
  12994. for(int i = 0; i < n; i++)
  12995. {
  12996. if(this.Sizes[i] != t.Sizes[i])
  12997. return false;
  12998. }
  12999. if(this.LowerBounds == null)
  13000. return t.LowerBounds == null;
  13001. if(t.LowerBounds == null)
  13002. return false;
  13003. n = this.LowerBounds.Length;
  13004. if(n != t.LowerBounds.Length)
  13005. return false;
  13006. for(int i = 0; i < n; i++)
  13007. {
  13008. if(this.LowerBounds[i] != t.LowerBounds[i])
  13009. return false;
  13010. }
  13011. return true;
  13012. }
  13013. }
  13014. public class Pointer : TypeNode
  13015. {
  13016. internal Pointer(TypeNode/*!*/ elementType)
  13017. : base(NodeType.Pointer)
  13018. {
  13019. this.elementType = elementType;
  13020. this.typeCode = Metadata.ElementType.Pointer;
  13021. this.Name = Identifier.For(elementType.Name + "*");
  13022. this.Namespace = elementType.Namespace;
  13023. }
  13024. private TypeNode/*!*/ elementType;
  13025. public TypeNode/*!*/ ElementType
  13026. {
  13027. get { return this.elementType; }
  13028. set { this.elementType = value; }
  13029. }
  13030. public override string/*!*/ FullName
  13031. {
  13032. get
  13033. {
  13034. if(this.ElementType != null && this.ElementType.DeclaringType != null)
  13035. return this.ElementType.DeclaringType.FullName + "+" + (this.Name == null ? "" : this.Name.ToString());
  13036. else if(this.Namespace != null && this.Namespace.UniqueIdKey != Identifier.Empty.UniqueIdKey)
  13037. return this.Namespace.ToString() + "." + (this.Name == null ? "" : this.Name.ToString());
  13038. else if(this.Name != null)
  13039. return this.Name.ToString();
  13040. else
  13041. return "";
  13042. }
  13043. }
  13044. internal override void AppendDocumentIdMangledName(StringBuilder/*!*/ sb, TypeNodeList methodTypeParameters, TypeNodeList typeParameters)
  13045. {
  13046. if(this.elementType == null)
  13047. return;
  13048. this.elementType.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
  13049. sb.Append('*');
  13050. }
  13051. public override Type GetRuntimeType()
  13052. {
  13053. if(this.runtimeType == null)
  13054. {
  13055. if(this.ElementType == null)
  13056. return null;
  13057. Type eType = this.ElementType.GetRuntimeType();
  13058. if(eType == null)
  13059. return null;
  13060. this.runtimeType = eType.MakePointerType();
  13061. }
  13062. return this.runtimeType;
  13063. }
  13064. public override bool IsAssignableTo(TypeNode targetType)
  13065. {
  13066. return targetType == this || (targetType is Pointer && ((Pointer)targetType).ElementType == CoreSystemTypes.Void);
  13067. }
  13068. public override bool IsUnmanaged
  13069. {
  13070. get
  13071. {
  13072. return true;
  13073. }
  13074. }
  13075. public override bool IsStructural
  13076. {
  13077. get { return true; }
  13078. }
  13079. public override bool IsPointerType
  13080. {
  13081. get
  13082. {
  13083. return true;
  13084. }
  13085. }
  13086. protected TypeNodeList structuralElementTypes;
  13087. public override TypeNodeList StructuralElementTypes
  13088. {
  13089. get
  13090. {
  13091. TypeNodeList result = this.structuralElementTypes;
  13092. if(result != null)
  13093. return result;
  13094. this.structuralElementTypes = result = new TypeNodeList();
  13095. result.Add(this.ElementType);
  13096. return result;
  13097. }
  13098. }
  13099. public override bool IsStructurallyEquivalentTo(TypeNode type)
  13100. {
  13101. if(type == null)
  13102. return false;
  13103. if(this == type)
  13104. return true;
  13105. Pointer t = type as Pointer;
  13106. if(t == null)
  13107. return false;
  13108. if(this.ElementType == null || t.ElementType == null)
  13109. return false;
  13110. return this.ElementType == t.ElementType || this.ElementType.IsStructurallyEquivalentTo(t.ElementType);
  13111. }
  13112. }
  13113. public class Reference : TypeNode
  13114. {
  13115. internal Reference(TypeNode/*!*/ elementType)
  13116. : base(NodeType.Reference)
  13117. {
  13118. this.elementType = elementType;
  13119. this.typeCode = Metadata.ElementType.Reference;
  13120. this.Name = Identifier.For(elementType.Name + "@");
  13121. this.Namespace = elementType.Namespace;
  13122. }
  13123. private TypeNode/*!*/ elementType;
  13124. public TypeNode/*!*/ ElementType
  13125. {
  13126. get { return this.elementType; }
  13127. set { this.elementType = value; }
  13128. }
  13129. internal override void AppendDocumentIdMangledName(StringBuilder/*!*/ sb, TypeNodeList methodTypeParameters, TypeNodeList typeParameters)
  13130. {
  13131. if(this.elementType == null)
  13132. return;
  13133. this.elementType.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
  13134. sb.Append('@');
  13135. }
  13136. public override bool IsAssignableTo(TypeNode targetType)
  13137. {
  13138. return targetType == this ||
  13139. (targetType is Pointer && (((Pointer)targetType).ElementType == this.ElementType ||
  13140. ((Pointer)targetType).ElementType == CoreSystemTypes.Void));
  13141. }
  13142. public override string/*!*/ FullName
  13143. {
  13144. get
  13145. {
  13146. if(this.ElementType != null && this.ElementType.DeclaringType != null)
  13147. return this.ElementType.DeclaringType.FullName + "+" + (this.Name == null ? "" : this.Name.ToString());
  13148. else if(this.Namespace != null && this.Namespace.UniqueIdKey != Identifier.Empty.UniqueIdKey)
  13149. return this.Namespace.ToString() + "." + (this.Name == null ? "" : this.Name.ToString());
  13150. else if(this.Name != null)
  13151. return this.Name.ToString();
  13152. else
  13153. return "";
  13154. }
  13155. }
  13156. public override Type GetRuntimeType()
  13157. {
  13158. if(this.runtimeType == null)
  13159. {
  13160. if(this.ElementType == null)
  13161. return null;
  13162. Type eType = this.ElementType.GetRuntimeType();
  13163. if(eType == null)
  13164. return null;
  13165. this.runtimeType = eType.MakeByRefType();
  13166. }
  13167. return this.runtimeType;
  13168. }
  13169. public override bool IsStructural
  13170. {
  13171. get { return true; }
  13172. }
  13173. protected TypeNodeList structuralElementTypes;
  13174. public override TypeNodeList StructuralElementTypes
  13175. {
  13176. get
  13177. {
  13178. TypeNodeList result = this.structuralElementTypes;
  13179. if(result != null)
  13180. return result;
  13181. this.structuralElementTypes = result = new TypeNodeList();
  13182. result.Add(this.ElementType);
  13183. return result;
  13184. }
  13185. }
  13186. public override bool IsStructurallyEquivalentTo(TypeNode type)
  13187. {
  13188. if(type == null)
  13189. return false;
  13190. if(this == type)
  13191. return true;
  13192. Reference t = type as Reference;
  13193. if(t == null)
  13194. return false;
  13195. if(this.ElementType == null || t.ElementType == null)
  13196. return false;
  13197. return this.ElementType == t.ElementType || this.ElementType.IsStructurallyEquivalentTo(t.ElementType);
  13198. }
  13199. }
  13200. public abstract class TypeModifier : TypeNode
  13201. {
  13202. private TypeNode/*!*/ modifier;
  13203. private TypeNode/*!*/ modifiedType;
  13204. public TypeNode ModifierExpression;
  13205. public TypeNode ModifiedTypeExpression;
  13206. internal TypeModifier(NodeType type, TypeNode/*!*/ modifier, TypeNode/*!*/ modified)
  13207. : base(type)
  13208. {
  13209. this.modifier = modifier;
  13210. this.modifiedType = modified;
  13211. this.DeclaringModule = modified.DeclaringModule;
  13212. this.Namespace = modified.Namespace;
  13213. if(type == NodeType.OptionalModifier)
  13214. {
  13215. this.typeCode = ElementType.OptionalModifier;
  13216. this.Name = Identifier.For("optional(" + modifier.Name + ") " + modified.Name);
  13217. this.fullName = "optional(" + modifier.FullName + ") " + modified.FullName;
  13218. }
  13219. else
  13220. {
  13221. this.typeCode = ElementType.RequiredModifier;
  13222. this.Name = Identifier.For("required(" + modifier.Name + ") " + modified.Name);
  13223. this.fullName = "required(" + modifier.FullName + ") " + modified.FullName;
  13224. }
  13225. this.Flags = modified.Flags;
  13226. }
  13227. public TypeNode/*!*/ Modifier
  13228. {
  13229. get { return this.modifier; }
  13230. set { this.modifier = value; }
  13231. }
  13232. public TypeNode/*!*/ ModifiedType
  13233. {
  13234. get { return this.modifiedType; }
  13235. set { this.modifiedType = value; }
  13236. }
  13237. public override Node/*!*/ Clone()
  13238. {
  13239. Debug.Assert(false);
  13240. return base.Clone();
  13241. }
  13242. public override string GetFullUnmangledNameWithoutTypeParameters()
  13243. {
  13244. return this.ModifiedType.GetFullUnmangledNameWithoutTypeParameters();
  13245. }
  13246. public override string GetFullUnmangledNameWithTypeParameters()
  13247. {
  13248. return this.ModifiedType.GetFullUnmangledNameWithTypeParameters();
  13249. }
  13250. public override string/*!*/ GetUnmangledNameWithoutTypeParameters()
  13251. {
  13252. return this.ModifiedType.GetUnmangledNameWithoutTypeParameters();
  13253. }
  13254. public override bool IsUnmanaged
  13255. {
  13256. get { return this.ModifiedType.IsUnmanaged; }
  13257. }
  13258. public override bool IsStructural
  13259. {
  13260. get { return true; }
  13261. }
  13262. public override bool IsStructurallyEquivalentTo(TypeNode type)
  13263. {
  13264. if(type == null)
  13265. return false;
  13266. if(this == type)
  13267. return true;
  13268. if(this.NodeType != type.NodeType)
  13269. return false;
  13270. TypeModifier t = type as TypeModifier;
  13271. if(t == null) { Debug.Assert(false); return false; }
  13272. if(this.Modifier != t.Modifier && (this.Modifier == null || !this.Modifier.IsStructurallyEquivalentTo(t.Modifier)))
  13273. return false;
  13274. if(this.ModifiedType != t.ModifiedType && (this.ModifiedType == null || !this.ModifiedType.IsStructurallyEquivalentTo(t.ModifiedType)))
  13275. return false;
  13276. return true;
  13277. }
  13278. public override bool IsValueType
  13279. {
  13280. get
  13281. {
  13282. return this.ModifiedType.IsValueType;
  13283. }
  13284. }
  13285. public override bool IsPointerType
  13286. {
  13287. get
  13288. {
  13289. return this.ModifiedType.IsPointerType;
  13290. }
  13291. }
  13292. public override bool IsTemplateParameter
  13293. {
  13294. get
  13295. {
  13296. return this.ModifiedType.IsTemplateParameter;
  13297. }
  13298. }
  13299. protected TypeNodeList structuralElementTypes;
  13300. public override TypeNodeList StructuralElementTypes
  13301. {
  13302. get
  13303. {
  13304. TypeNodeList result = this.structuralElementTypes;
  13305. if(result != null)
  13306. return result;
  13307. this.structuralElementTypes = result = new TypeNodeList();
  13308. result.Add(this.ModifiedType);
  13309. result.Add(this.Modifier);
  13310. return result;
  13311. }
  13312. }
  13313. }
  13314. public class OptionalModifier : TypeModifier
  13315. {
  13316. internal OptionalModifier(TypeNode/*!*/ modifier, TypeNode/*!*/ modified)
  13317. : base(NodeType.OptionalModifier, modifier, modified)
  13318. {
  13319. }
  13320. public static OptionalModifier/*!*/ For(TypeNode/*!*/ modifier, TypeNode/*!*/ modified)
  13321. {
  13322. return (OptionalModifier)modified.GetModified(modifier, true);
  13323. }
  13324. internal override void AppendDocumentIdMangledName(StringBuilder/*!*/ sb, TypeNodeList methodTypeParameters, TypeNodeList typeParameters)
  13325. {
  13326. this.ModifiedType.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
  13327. sb.Append('!');
  13328. this.Modifier.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
  13329. }
  13330. }
  13331. public class RequiredModifier : TypeModifier
  13332. {
  13333. internal RequiredModifier(TypeNode/*!*/ modifier, TypeNode/*!*/ modified)
  13334. : base(NodeType.RequiredModifier, modifier, modified)
  13335. {
  13336. }
  13337. public static RequiredModifier/*!*/ For(TypeNode/*!*/ modifier, TypeNode/*!*/ modified)
  13338. {
  13339. return (RequiredModifier)modified.GetModified(modifier, false);
  13340. }
  13341. internal override void AppendDocumentIdMangledName(StringBuilder/*!*/ sb, TypeNodeList methodTypeParameters, TypeNodeList typeParameters)
  13342. {
  13343. this.ModifiedType.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
  13344. sb.Append('|');
  13345. this.Modifier.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
  13346. }
  13347. }
  13348. public class OptionalModifierTypeExpression : TypeNode
  13349. {
  13350. public TypeNode ModifiedType;
  13351. public TypeNode Modifier;
  13352. public OptionalModifierTypeExpression(TypeNode elementType, TypeNode modifier)
  13353. : base(NodeType.OptionalModifierTypeExpression)
  13354. {
  13355. this.ModifiedType = elementType;
  13356. this.Modifier = modifier;
  13357. }
  13358. public OptionalModifierTypeExpression(TypeNode elementType, TypeNode modifier, SourceContext sctx)
  13359. : this(elementType, modifier)
  13360. {
  13361. this.SourceContext = sctx;
  13362. }
  13363. /// <summary>
  13364. /// Only needed because IsUnmanaged test is performed in the Looker rather than checker. Once the test
  13365. /// is moved, this code can be removed.
  13366. /// </summary>
  13367. public override bool IsUnmanaged
  13368. {
  13369. get
  13370. {
  13371. return this.ModifiedType == null ? false : this.ModifiedType.IsUnmanaged;
  13372. }
  13373. }
  13374. }
  13375. public class RequiredModifierTypeExpression : TypeNode
  13376. {
  13377. public TypeNode ModifiedType;
  13378. public TypeNode Modifier;
  13379. public RequiredModifierTypeExpression(TypeNode elementType, TypeNode modifier)
  13380. : base(NodeType.RequiredModifierTypeExpression)
  13381. {
  13382. this.ModifiedType = elementType;
  13383. this.Modifier = modifier;
  13384. }
  13385. public RequiredModifierTypeExpression(TypeNode elementType, TypeNode modifier, SourceContext sctx)
  13386. : this(elementType, modifier)
  13387. {
  13388. this.SourceContext = sctx;
  13389. }
  13390. /// <summary>
  13391. /// Can be removed once the Unmanaged check moves from Looker to Checker.
  13392. /// </summary>
  13393. public override bool IsUnmanaged
  13394. {
  13395. get
  13396. {
  13397. return this.ModifiedType == null ? false : this.ModifiedType.IsUnmanaged;
  13398. }
  13399. }
  13400. }
  13401. public class FunctionPointer : TypeNode
  13402. {
  13403. internal FunctionPointer(TypeNodeList parameterTypes, TypeNode/*!*/ returnType, Identifier name)
  13404. : base(NodeType.FunctionPointer)
  13405. {
  13406. this.Name = name;
  13407. this.Namespace = returnType.Namespace;
  13408. this.parameterTypes = parameterTypes;
  13409. this.returnType = returnType;
  13410. this.typeCode = ElementType.FunctionPointer;
  13411. this.varArgStart = int.MaxValue;
  13412. }
  13413. private CallingConventionFlags callingConvention;
  13414. public CallingConventionFlags CallingConvention
  13415. {
  13416. get { return this.callingConvention; }
  13417. set { this.callingConvention = value; }
  13418. }
  13419. private TypeNodeList parameterTypes;
  13420. public TypeNodeList ParameterTypes
  13421. {
  13422. get { return this.parameterTypes; }
  13423. set { this.parameterTypes = value; }
  13424. }
  13425. private TypeNode returnType;
  13426. public TypeNode ReturnType
  13427. {
  13428. get { return this.returnType; }
  13429. set { this.returnType = value; }
  13430. }
  13431. private int varArgStart;
  13432. public int VarArgStart
  13433. {
  13434. get { return this.varArgStart; }
  13435. set { this.varArgStart = value; }
  13436. }
  13437. public override bool IsStatic
  13438. {
  13439. get { return (this.CallingConvention & CallingConventionFlags.HasThis) == 0; }
  13440. }
  13441. public override bool IsStructural
  13442. {
  13443. get { return true; }
  13444. }
  13445. protected TypeNodeList structuralElementTypes;
  13446. public override TypeNodeList StructuralElementTypes
  13447. {
  13448. get
  13449. {
  13450. TypeNodeList result = this.structuralElementTypes;
  13451. if(result != null)
  13452. return result;
  13453. this.structuralElementTypes = result = new TypeNodeList();
  13454. result.Add(this.ReturnType);
  13455. TypeNodeList ptypes = this.ParameterTypes;
  13456. for(int i = 0, n = ptypes == null ? 0 : ptypes.Count; i < n; i++)
  13457. {
  13458. TypeNode ptype = ptypes[i];
  13459. if(ptype == null)
  13460. continue;
  13461. result.Add(ptype);
  13462. }
  13463. return result;
  13464. }
  13465. }
  13466. public override bool IsStructurallyEquivalentTo(TypeNode type)
  13467. {
  13468. if(type == null)
  13469. return false;
  13470. if(this == type)
  13471. return true;
  13472. FunctionPointer t = type as FunctionPointer;
  13473. if(t == null)
  13474. return false;
  13475. if(this.Flags != t.Flags || this.CallingConvention != t.CallingConvention || this.VarArgStart != t.VarArgStart)
  13476. return false;
  13477. if(this.ReturnType == null || t.ReturnType == null)
  13478. return false;
  13479. if(this.ReturnType != t.ReturnType && !this.ReturnType.IsStructurallyEquivalentTo(t.ReturnType))
  13480. return false;
  13481. return this.IsStructurallyEquivalentList(this.ParameterTypes, t.ParameterTypes);
  13482. }
  13483. public static FunctionPointer/*!*/ For(TypeNodeList/*!*/ parameterTypes, TypeNode/*!*/ returnType)
  13484. {
  13485. Module mod = returnType.DeclaringModule;
  13486. if(mod == null) { Debug.Fail(""); mod = new Module(); }
  13487. StringBuilder sb = new StringBuilder("function pointer ");
  13488. sb.Append(returnType.FullName);
  13489. sb.Append('(');
  13490. for(int i = 0, n = parameterTypes == null ? 0 : parameterTypes.Count; i < n; i++)
  13491. {
  13492. TypeNode type = parameterTypes[i];
  13493. if(type == null)
  13494. continue;
  13495. if(i != 0)
  13496. sb.Append(',');
  13497. sb.Append(type.FullName);
  13498. }
  13499. sb.Append(')');
  13500. Identifier name = Identifier.For(sb.ToString());
  13501. TypeNode t = mod.GetStructurallyEquivalentType(returnType.Namespace, name);
  13502. int counter = 1;
  13503. while(t != null)
  13504. {
  13505. FunctionPointer fp = t as FunctionPointer;
  13506. if(fp != null)
  13507. {
  13508. if(fp.ReturnType == returnType && FunctionPointer.ParameterTypesAreEquivalent(fp.ParameterTypes, parameterTypes))
  13509. return fp;
  13510. }
  13511. name = Identifier.For(name.ToString() + counter++);
  13512. t = mod.GetStructurallyEquivalentType(returnType.Namespace, name);
  13513. }
  13514. FunctionPointer result = t as FunctionPointer;
  13515. if(result == null)
  13516. {
  13517. result = new FunctionPointer(parameterTypes, returnType, name);
  13518. result.DeclaringModule = mod;
  13519. mod.StructurallyEquivalentType[name.UniqueIdKey] = result;
  13520. }
  13521. return result;
  13522. }
  13523. private static bool ParameterTypesAreEquivalent(TypeNodeList list1, TypeNodeList list2)
  13524. {
  13525. if(list1 == null || list2 == null)
  13526. return list1 == list2;
  13527. int n = list1.Count;
  13528. if(n != list2.Count)
  13529. return false;
  13530. for(int i = 0; i < n; i++)
  13531. if(list1[i] != list2[i])
  13532. return false;
  13533. return true;
  13534. }
  13535. }
  13536. public class ArrayTypeExpression : ArrayType
  13537. {
  13538. //TODO: add expressions for elementType, rank, sizes and lower bounds
  13539. public bool LowerBoundIsUnknown;
  13540. public ArrayTypeExpression()
  13541. : base()
  13542. {
  13543. this.NodeType = NodeType.ArrayTypeExpression;
  13544. }
  13545. public ArrayTypeExpression(TypeNode/*!*/ elementType, int rank)
  13546. : base(elementType, rank)
  13547. {
  13548. this.NodeType = NodeType.ArrayTypeExpression;
  13549. }
  13550. public ArrayTypeExpression(TypeNode/*!*/ elementType, int rank, int[] sizes)
  13551. : base(elementType, rank, sizes)
  13552. {
  13553. this.NodeType = NodeType.ArrayTypeExpression;
  13554. }
  13555. public ArrayTypeExpression(TypeNode/*!*/ elementType, int rank, int[] sizes, int[] lowerBounds)
  13556. : base(elementType, rank, sizes, sizes)
  13557. {
  13558. this.NodeType = NodeType.ArrayTypeExpression;
  13559. }
  13560. public ArrayTypeExpression(TypeNode/*!*/ elementType, int rank, SourceContext sctx)
  13561. : base(elementType, rank)
  13562. {
  13563. this.NodeType = NodeType.ArrayTypeExpression;
  13564. this.SourceContext = sctx;
  13565. }
  13566. public ArrayTypeExpression(TypeNode/*!*/ elementType, int rank, int[] sizes, SourceContext sctx)
  13567. : base(elementType, rank, sizes)
  13568. {
  13569. this.NodeType = NodeType.ArrayTypeExpression;
  13570. this.SourceContext = sctx;
  13571. }
  13572. public ArrayTypeExpression(TypeNode/*!*/ elementType, int rank, int[] sizes, int[] lowerBounds, SourceContext sctx)
  13573. : base(elementType, rank, sizes, sizes)
  13574. {
  13575. this.NodeType = NodeType.ArrayTypeExpression;
  13576. this.SourceContext = sctx;
  13577. }
  13578. }
  13579. public class ClassExpression : Class
  13580. {
  13581. public Expression Expression;
  13582. public ClassExpression(Expression expression)
  13583. {
  13584. this.NodeType = NodeType.ClassExpression;
  13585. this.Expression = expression;
  13586. }
  13587. public ClassExpression(Expression expression, TypeNodeList templateArguments)
  13588. {
  13589. this.NodeType = NodeType.ClassExpression;
  13590. this.Expression = expression;
  13591. this.TemplateArguments = templateArguments;
  13592. if(templateArguments != null)
  13593. this.TemplateArgumentExpressions = new TypeNodeList(templateArguments);
  13594. }
  13595. public ClassExpression(Expression expression, SourceContext sctx)
  13596. {
  13597. this.NodeType = NodeType.ClassExpression;
  13598. this.Expression = expression;
  13599. this.SourceContext = sctx;
  13600. }
  13601. public ClassExpression(Expression expression, TypeNodeList templateArguments, SourceContext sctx)
  13602. {
  13603. this.NodeType = NodeType.ClassExpression;
  13604. this.Expression = expression;
  13605. this.TemplateArguments = this.TemplateArgumentExpressions = templateArguments;
  13606. if(templateArguments != null)
  13607. this.TemplateArgumentExpressions = new TypeNodeList(templateArguments);
  13608. this.SourceContext = sctx;
  13609. }
  13610. }
  13611. public class InterfaceExpression : Interface
  13612. {
  13613. private Expression expression;
  13614. public InterfaceExpression(Expression expression)
  13615. : base(null)
  13616. {
  13617. this.NodeType = NodeType.InterfaceExpression;
  13618. this.Expression = expression;
  13619. }
  13620. public InterfaceExpression(Expression expression, SourceContext sctx)
  13621. : base(null)
  13622. {
  13623. this.NodeType = NodeType.InterfaceExpression;
  13624. this.Expression = expression;
  13625. this.SourceContext = sctx;
  13626. }
  13627. public Expression Expression
  13628. {
  13629. get { return this.expression; }
  13630. set { this.expression = value; }
  13631. }
  13632. }
  13633. public class FlexArrayTypeExpression : TypeNode
  13634. {
  13635. public TypeNode ElementType;
  13636. public FlexArrayTypeExpression(TypeNode elementType)
  13637. : base(NodeType.FlexArrayTypeExpression)
  13638. {
  13639. this.ElementType = elementType;
  13640. }
  13641. public FlexArrayTypeExpression(TypeNode elementType, SourceContext sctx)
  13642. : base(NodeType.FlexArrayTypeExpression)
  13643. {
  13644. this.ElementType = elementType;
  13645. this.SourceContext = sctx;
  13646. }
  13647. }
  13648. public class FunctionTypeExpression : TypeNode
  13649. {
  13650. public ParameterList Parameters;
  13651. public TypeNode ReturnType;
  13652. public FunctionTypeExpression(TypeNode returnType, ParameterList parameters)
  13653. : base(NodeType.FunctionTypeExpression)
  13654. {
  13655. this.ReturnType = returnType;
  13656. this.Parameters = parameters;
  13657. }
  13658. public FunctionTypeExpression(TypeNode returnType, ParameterList parameters, SourceContext sctx)
  13659. : base(NodeType.FunctionTypeExpression)
  13660. {
  13661. this.ReturnType = returnType;
  13662. this.Parameters = parameters;
  13663. this.SourceContext = sctx;
  13664. }
  13665. }
  13666. public class PointerTypeExpression : Pointer
  13667. {
  13668. public PointerTypeExpression(TypeNode/*!*/ elementType)
  13669. : base(elementType)
  13670. {
  13671. this.NodeType = NodeType.PointerTypeExpression;
  13672. }
  13673. public PointerTypeExpression(TypeNode/*!*/ elementType, SourceContext sctx)
  13674. : base(elementType)
  13675. {
  13676. this.NodeType = NodeType.PointerTypeExpression;
  13677. this.SourceContext = sctx;
  13678. }
  13679. /// <summary>
  13680. /// This is only needed because the Unmanaged test is done in the Looker rather than the checker.
  13681. /// (Once the check moves, this can be removed).
  13682. /// </summary>
  13683. public override bool IsUnmanaged
  13684. {
  13685. get
  13686. {
  13687. return true;
  13688. }
  13689. }
  13690. }
  13691. public class ReferenceTypeExpression : Reference
  13692. {
  13693. public ReferenceTypeExpression(TypeNode/*!*/ elementType)
  13694. : base(elementType)
  13695. {
  13696. this.NodeType = NodeType.ReferenceTypeExpression;
  13697. }
  13698. public ReferenceTypeExpression(TypeNode/*!*/ elementType, SourceContext sctx)
  13699. : base(elementType)
  13700. {
  13701. this.NodeType = NodeType.ReferenceTypeExpression;
  13702. this.SourceContext = sctx;
  13703. }
  13704. }
  13705. public class StreamTypeExpression : TypeNode
  13706. {
  13707. public TypeNode ElementType;
  13708. public StreamTypeExpression(TypeNode elementType)
  13709. : base(NodeType.StreamTypeExpression)
  13710. {
  13711. this.ElementType = elementType;
  13712. }
  13713. public StreamTypeExpression(TypeNode elementType, SourceContext sctx)
  13714. : base(NodeType.StreamTypeExpression)
  13715. {
  13716. this.ElementType = elementType;
  13717. this.SourceContext = sctx;
  13718. }
  13719. }
  13720. public class NonEmptyStreamTypeExpression : TypeNode
  13721. {
  13722. public TypeNode ElementType;
  13723. public NonEmptyStreamTypeExpression(TypeNode elementType)
  13724. : base(NodeType.NonEmptyStreamTypeExpression)
  13725. {
  13726. this.ElementType = elementType;
  13727. }
  13728. public NonEmptyStreamTypeExpression(TypeNode elementType, SourceContext sctx)
  13729. : base(NodeType.NonEmptyStreamTypeExpression)
  13730. {
  13731. this.ElementType = elementType;
  13732. this.SourceContext = sctx;
  13733. }
  13734. }
  13735. public class BoxedTypeExpression : TypeNode
  13736. {
  13737. public TypeNode ElementType;
  13738. public BoxedTypeExpression(TypeNode elementType)
  13739. : base(NodeType.BoxedTypeExpression)
  13740. {
  13741. this.ElementType = elementType;
  13742. }
  13743. public BoxedTypeExpression(TypeNode elementType, SourceContext sctx)
  13744. : base(NodeType.BoxedTypeExpression)
  13745. {
  13746. this.ElementType = elementType;
  13747. this.SourceContext = sctx;
  13748. }
  13749. }
  13750. public class InvariantTypeExpression : TypeNode
  13751. {
  13752. public TypeNode ElementType;
  13753. public InvariantTypeExpression(TypeNode elementType)
  13754. : base(NodeType.InvariantTypeExpression)
  13755. {
  13756. this.ElementType = elementType;
  13757. }
  13758. public InvariantTypeExpression(TypeNode elementType, SourceContext sctx)
  13759. : base(NodeType.InvariantTypeExpression)
  13760. {
  13761. this.ElementType = elementType;
  13762. this.SourceContext = sctx;
  13763. }
  13764. }
  13765. public class NonNullTypeExpression : TypeNode
  13766. {
  13767. public TypeNode ElementType;
  13768. public NonNullTypeExpression(TypeNode elementType)
  13769. : base(NodeType.NonNullTypeExpression)
  13770. {
  13771. this.ElementType = elementType;
  13772. }
  13773. public NonNullTypeExpression(TypeNode elementType, SourceContext sctx)
  13774. : base(NodeType.NonNullTypeExpression)
  13775. {
  13776. this.ElementType = elementType;
  13777. this.SourceContext = sctx;
  13778. }
  13779. }
  13780. public class NonNullableTypeExpression : TypeNode
  13781. {
  13782. public TypeNode ElementType;
  13783. public NonNullableTypeExpression(TypeNode elementType)
  13784. : base(NodeType.NonNullableTypeExpression)
  13785. {
  13786. this.ElementType = elementType;
  13787. }
  13788. public NonNullableTypeExpression(TypeNode elementType, SourceContext sctx)
  13789. : base(NodeType.NonNullableTypeExpression)
  13790. {
  13791. this.ElementType = elementType;
  13792. this.SourceContext = sctx;
  13793. }
  13794. }
  13795. public class NullableTypeExpression : TypeNode
  13796. {
  13797. public TypeNode ElementType;
  13798. public NullableTypeExpression(TypeNode elementType)
  13799. : base(NodeType.NullableTypeExpression)
  13800. {
  13801. this.ElementType = elementType;
  13802. }
  13803. public NullableTypeExpression(TypeNode elementType, SourceContext sctx)
  13804. : base(NodeType.NullableTypeExpression)
  13805. {
  13806. this.ElementType = elementType;
  13807. this.SourceContext = sctx;
  13808. }
  13809. }
  13810. public class TupleTypeExpression : TypeNode
  13811. {
  13812. public FieldList Domains;
  13813. public TupleTypeExpression(FieldList domains)
  13814. : base(NodeType.TupleTypeExpression)
  13815. {
  13816. this.Domains = domains;
  13817. }
  13818. public TupleTypeExpression(FieldList domains, SourceContext sctx)
  13819. : base(NodeType.TupleTypeExpression)
  13820. {
  13821. this.Domains = domains;
  13822. this.SourceContext = sctx;
  13823. }
  13824. }
  13825. public class TypeIntersectionExpression : TypeNode
  13826. {
  13827. public TypeNodeList Types;
  13828. public TypeIntersectionExpression(TypeNodeList types)
  13829. : base(NodeType.TypeIntersectionExpression)
  13830. {
  13831. this.Types = types;
  13832. }
  13833. public TypeIntersectionExpression(TypeNodeList types, SourceContext sctx)
  13834. : base(NodeType.TypeIntersectionExpression)
  13835. {
  13836. this.Types = types;
  13837. this.SourceContext = sctx;
  13838. }
  13839. }
  13840. public class TypeUnionExpression : TypeNode
  13841. {
  13842. public TypeNodeList Types;
  13843. public TypeUnionExpression(TypeNodeList types)
  13844. : base(NodeType.TypeUnionExpression)
  13845. {
  13846. this.Types = types;
  13847. }
  13848. public TypeUnionExpression(TypeNodeList types, SourceContext sctx)
  13849. : base(NodeType.TypeUnionExpression)
  13850. {
  13851. this.Types = types;
  13852. this.SourceContext = sctx;
  13853. }
  13854. }
  13855. public class TypeExpression : TypeNode
  13856. {
  13857. public Expression Expression;
  13858. public int Arity;
  13859. public TypeExpression(Expression expression)
  13860. : base(NodeType.TypeExpression)
  13861. {
  13862. this.Expression = expression;
  13863. }
  13864. public TypeExpression(Expression expression, TypeNodeList templateArguments)
  13865. : base(NodeType.TypeExpression)
  13866. {
  13867. this.Expression = expression;
  13868. this.templateArguments = this.TemplateArgumentExpressions = templateArguments;
  13869. }
  13870. public TypeExpression(Expression expression, int arity)
  13871. : base(NodeType.TypeExpression)
  13872. {
  13873. this.Expression = expression;
  13874. this.Arity = arity;
  13875. }
  13876. public TypeExpression(Expression expression, SourceContext sctx)
  13877. : base(NodeType.TypeExpression)
  13878. {
  13879. this.Expression = expression;
  13880. this.SourceContext = sctx;
  13881. }
  13882. public TypeExpression(Expression expression, TypeNodeList templateArguments, SourceContext sctx)
  13883. : base(NodeType.TypeExpression)
  13884. {
  13885. this.Expression = expression;
  13886. this.templateArguments = this.TemplateArgumentExpressions = templateArguments;
  13887. this.SourceContext = sctx;
  13888. }
  13889. public TypeExpression(Expression expression, int arity, SourceContext sctx)
  13890. : base(NodeType.TypeExpression)
  13891. {
  13892. this.Expression = expression;
  13893. this.Arity = arity;
  13894. this.SourceContext = sctx;
  13895. }
  13896. public override bool IsUnmanaged
  13897. {
  13898. get
  13899. {
  13900. Literal lit = this.Expression as Literal;
  13901. if(lit != null)
  13902. {
  13903. TypeNode t = lit.Value as TypeNode;
  13904. if(t != null)
  13905. return t.IsUnmanaged;
  13906. if(lit.Value is TypeCode)
  13907. return true;
  13908. }
  13909. return true;
  13910. }
  13911. }
  13912. }
  13913. public class TypeReference : Node
  13914. {
  13915. public TypeNode Type;
  13916. public TypeNode Expression;
  13917. public TypeReference(TypeNode typeExpression)
  13918. : base(NodeType.TypeReference)
  13919. {
  13920. this.Expression = typeExpression;
  13921. if(typeExpression != null)
  13922. this.SourceContext = typeExpression.SourceContext;
  13923. }
  13924. public TypeReference(TypeNode typeExpression, TypeNode type)
  13925. : base(NodeType.TypeReference)
  13926. {
  13927. this.Expression = typeExpression;
  13928. this.Type = type;
  13929. if(typeExpression != null)
  13930. this.SourceContext = typeExpression.SourceContext;
  13931. }
  13932. public static explicit operator TypeNode(TypeReference typeReference)
  13933. {
  13934. return null == (object)typeReference ? null : typeReference.Type;
  13935. }
  13936. public static bool operator ==(TypeReference typeReference, TypeNode type)
  13937. {
  13938. return null == (object)typeReference ? null == (object)type : typeReference.Type == type;
  13939. }
  13940. public static bool operator ==(TypeNode type, TypeReference typeReference)
  13941. {
  13942. return null == (object)typeReference ? null == (object)type : typeReference.Type == type;
  13943. }
  13944. public static bool operator !=(TypeReference typeReference, TypeNode type)
  13945. {
  13946. return null == (object)typeReference ? null != (object)type : typeReference.Type != type;
  13947. }
  13948. public static bool operator !=(TypeNode type, TypeReference typeReference)
  13949. {
  13950. return null == (object)typeReference ? null != (object)type : typeReference.Type != type;
  13951. }
  13952. public override bool Equals(object obj)
  13953. {
  13954. return obj == (object)this || obj == (object)this.Type;
  13955. }
  13956. public override int GetHashCode()
  13957. {
  13958. return base.GetHashCode();
  13959. }
  13960. }
  13961. public class ArglistArgumentExpression : NaryExpression
  13962. {
  13963. public ArglistArgumentExpression(ExpressionList args, SourceContext sctx)
  13964. : base(args, NodeType.ArglistArgumentExpression)
  13965. {
  13966. this.SourceContext = sctx;
  13967. }
  13968. }
  13969. public class ArglistExpression : Expression
  13970. {
  13971. public ArglistExpression(SourceContext sctx)
  13972. : base(NodeType.ArglistExpression)
  13973. {
  13974. this.SourceContext = sctx;
  13975. }
  13976. }
  13977. public class RefValueExpression : BinaryExpression
  13978. {
  13979. public RefValueExpression(Expression typedreference, Expression type, SourceContext sctx)
  13980. : base(typedreference, type, NodeType.RefValueExpression)
  13981. {
  13982. this.SourceContext = sctx;
  13983. }
  13984. }
  13985. public class RefTypeExpression : UnaryExpression
  13986. {
  13987. public RefTypeExpression(Expression typedreference, SourceContext sctx)
  13988. : base(typedreference, NodeType.RefTypeExpression)
  13989. {
  13990. this.SourceContext = sctx;
  13991. }
  13992. }
  13993. public class Event : Member
  13994. {
  13995. private EventFlags flags;
  13996. private Method handlerAdder;
  13997. private Method handlerCaller;
  13998. private MethodFlags handlerFlags;
  13999. private Method handlerRemover;
  14000. private TypeNode handlerType;
  14001. private MethodList otherMethods;
  14002. public TypeNode HandlerTypeExpression;
  14003. /// <summary>The list of types (just one in C#) that contain abstract or virtual events that are explicitly implemented or overridden by this event.</summary>
  14004. public TypeNodeList ImplementedTypes;
  14005. public TypeNodeList ImplementedTypeExpressions;
  14006. /// <summary>Provides a delegate instance that is added to the event upon initialization.</summary>
  14007. public Expression InitialHandler;
  14008. public Field BackingField;
  14009. public Event() : base(NodeType.Event)
  14010. {
  14011. }
  14012. public Event(TypeNode declaringType, AttributeList attributes, EventFlags flags, Identifier name,
  14013. Method handlerAdder, Method handlerCaller, Method handlerRemover, TypeNode handlerType)
  14014. : base(declaringType, attributes, name, NodeType.Event)
  14015. {
  14016. this.Flags = flags;
  14017. this.HandlerAdder = handlerAdder;
  14018. this.HandlerCaller = handlerCaller;
  14019. this.HandlerRemover = handlerRemover;
  14020. this.HandlerType = handlerType;
  14021. }
  14022. /// <summary>Bits characterizing this event.</summary>
  14023. public EventFlags Flags
  14024. {
  14025. get { return this.flags; }
  14026. set { this.flags = value; }
  14027. }
  14028. /// <summary>The method to be called in order to add a handler to an event. Corresponds to the add clause of a C# event declaration.</summary>
  14029. public Method HandlerAdder
  14030. {
  14031. get { return this.handlerAdder; }
  14032. set { this.handlerAdder = value; }
  14033. }
  14034. /// <summary>The method that gets called to fire an event. There is no corresponding C# syntax.</summary>
  14035. public Method HandlerCaller
  14036. {
  14037. get { return this.handlerCaller; }
  14038. set { this.handlerCaller = value; }
  14039. }
  14040. public MethodFlags HandlerFlags
  14041. {
  14042. get { return this.handlerFlags; }
  14043. set { this.handlerFlags = value; }
  14044. }
  14045. /// <summary>The method to be called in order to remove a handler from an event. Corresponds to the remove clause of a C# event declaration.</summary>
  14046. public Method HandlerRemover
  14047. {
  14048. get { return this.handlerRemover; }
  14049. set { this.handlerRemover = value; }
  14050. }
  14051. /// <summary>The delegate type that a handler for this event must have. Corresponds to the type clause of C# event declaration.</summary>
  14052. public TypeNode HandlerType
  14053. {
  14054. get { return this.handlerType; }
  14055. set { this.handlerType = value; }
  14056. }
  14057. public MethodList OtherMethods
  14058. {
  14059. get { return this.otherMethods; }
  14060. set { this.otherMethods = value; }
  14061. }
  14062. protected string fullName;
  14063. public override string/*!*/ FullName
  14064. {
  14065. get
  14066. {
  14067. string result = this.fullName;
  14068. if(result == null)
  14069. this.fullName = result = this.DeclaringType.FullName + "." + (this.Name == null ? "" : this.Name.ToString());
  14070. return result;
  14071. }
  14072. }
  14073. protected override Identifier GetDocumentationId()
  14074. {
  14075. StringBuilder sb = new StringBuilder();
  14076. sb.Append("E:");
  14077. if(this.DeclaringType == null)
  14078. return Identifier.Empty;
  14079. this.DeclaringType.AppendDocumentIdMangledName(sb, null, null);
  14080. sb.Append(".");
  14081. if(this.Name == null)
  14082. return Identifier.Empty;
  14083. sb.Append(this.Name.Name);
  14084. return Identifier.For(sb.ToString());
  14085. }
  14086. public static Event GetEvent(System.Reflection.EventInfo eventInfo)
  14087. {
  14088. if(eventInfo == null)
  14089. return null;
  14090. TypeNode tn = TypeNode.GetTypeNode(eventInfo.DeclaringType);
  14091. if(tn == null)
  14092. return null;
  14093. return tn.GetEvent(Identifier.For(eventInfo.Name));
  14094. }
  14095. protected System.Reflection.EventInfo eventInfo;
  14096. public virtual System.Reflection.EventInfo GetEventInfo()
  14097. {
  14098. if(this.eventInfo == null)
  14099. {
  14100. TypeNode tn = this.DeclaringType;
  14101. if(tn == null)
  14102. return null;
  14103. Type t = tn.GetRuntimeType();
  14104. if(t == null)
  14105. return null;
  14106. System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.DeclaredOnly;
  14107. if(this.IsPublic)
  14108. flags |= System.Reflection.BindingFlags.Public;
  14109. else
  14110. flags |= System.Reflection.BindingFlags.NonPublic;
  14111. if(this.IsStatic)
  14112. flags |= System.Reflection.BindingFlags.Static;
  14113. else
  14114. flags |= System.Reflection.BindingFlags.Instance;
  14115. this.eventInfo = t.GetEvent(this.Name.ToString(), flags);
  14116. }
  14117. return this.eventInfo;
  14118. }
  14119. /// <summary>
  14120. /// True if the methods constituting this event are abstract.
  14121. /// </summary>
  14122. public bool IsAbstract
  14123. {
  14124. get { return (this.HandlerFlags & MethodFlags.Abstract) != 0; }
  14125. }
  14126. public override bool IsAssembly
  14127. {
  14128. get { return (this.HandlerFlags & MethodFlags.MethodAccessMask) == MethodFlags.Assembly; }
  14129. }
  14130. public override bool IsCompilerControlled
  14131. {
  14132. get { return (this.HandlerFlags & MethodFlags.MethodAccessMask) == MethodFlags.CompilerControlled; }
  14133. }
  14134. public override bool IsFamily
  14135. {
  14136. get { return (this.HandlerFlags & MethodFlags.MethodAccessMask) == MethodFlags.Family; }
  14137. }
  14138. public override bool IsFamilyAndAssembly
  14139. {
  14140. get { return (this.HandlerFlags & MethodFlags.MethodAccessMask) == MethodFlags.FamANDAssem; }
  14141. }
  14142. public override bool IsFamilyOrAssembly
  14143. {
  14144. get { return (this.HandlerFlags & MethodFlags.MethodAccessMask) == MethodFlags.FamORAssem; }
  14145. }
  14146. public bool IsFinal
  14147. {
  14148. get { return (this.HandlerFlags & MethodFlags.Final) != 0; }
  14149. }
  14150. public override bool IsPrivate
  14151. {
  14152. get { return (this.HandlerFlags & MethodFlags.MethodAccessMask) == MethodFlags.Private; }
  14153. }
  14154. public override bool IsPublic
  14155. {
  14156. get { return (this.HandlerFlags & MethodFlags.MethodAccessMask) == MethodFlags.Public; }
  14157. }
  14158. public override bool IsSpecialName
  14159. {
  14160. get { return (this.Flags & EventFlags.SpecialName) != 0; }
  14161. }
  14162. public override bool IsStatic
  14163. {
  14164. get { return (this.HandlerFlags & MethodFlags.Static) != 0; }
  14165. }
  14166. /// <summary>
  14167. /// True if that the methods constituting this event are virtual.
  14168. /// </summary>
  14169. public bool IsVirtual
  14170. {
  14171. get { return (this.HandlerFlags & MethodFlags.Virtual) != 0; }
  14172. }
  14173. public override bool IsVisibleOutsideAssembly
  14174. {
  14175. get
  14176. {
  14177. return (this.HandlerAdder != null && this.HandlerAdder.IsVisibleOutsideAssembly) ||
  14178. (this.HandlerCaller != null && this.HandlerCaller.IsVisibleOutsideAssembly) ||
  14179. (this.HandlerRemover != null && this.HandlerRemover.IsVisibleOutsideAssembly);
  14180. }
  14181. }
  14182. public static readonly Event NotSpecified = new Event();
  14183. public override Member HiddenMember
  14184. {
  14185. get
  14186. {
  14187. return this.HiddenEvent;
  14188. }
  14189. set
  14190. {
  14191. this.HiddenEvent = (Event)value;
  14192. }
  14193. }
  14194. protected Property hiddenEvent;
  14195. public virtual Event HiddenEvent
  14196. {
  14197. get
  14198. {
  14199. if(this.hiddenMember == Event.NotSpecified)
  14200. return null;
  14201. Event hiddenEvent = this.hiddenMember as Event;
  14202. if(hiddenEvent != null)
  14203. return hiddenEvent;
  14204. Method hiddenAdder = this.HandlerAdder == null ? null : this.HandlerAdder.HiddenMethod;
  14205. Method hiddenCaller = this.HandlerCaller == null ? null : this.HandlerCaller.HiddenMethod;
  14206. Method hiddenRemover = this.HandlerRemover == null ? null : this.HandlerRemover.HiddenMethod;
  14207. Event hiddenAdderEvent = hiddenAdder == null ? null : hiddenAdder.DeclaringMember as Event;
  14208. Event hiddenCallerEvent = hiddenCaller == null ? null : hiddenCaller.DeclaringMember as Event;
  14209. Event hiddenRemoverEvent = hiddenRemover == null ? null : hiddenRemover.DeclaringMember as Event;
  14210. hiddenEvent = hiddenAdderEvent;
  14211. if(hiddenCallerEvent != null)
  14212. {
  14213. if(hiddenEvent == null ||
  14214. (hiddenCallerEvent.DeclaringType != null && hiddenCallerEvent.DeclaringType.IsDerivedFrom(hiddenEvent.DeclaringType)))
  14215. hiddenEvent = hiddenCallerEvent;
  14216. }
  14217. if(hiddenRemoverEvent != null)
  14218. {
  14219. if(hiddenEvent == null ||
  14220. (hiddenRemoverEvent.DeclaringType != null && hiddenRemoverEvent.DeclaringType.IsDerivedFrom(hiddenEvent.DeclaringType)))
  14221. hiddenEvent = hiddenRemoverEvent;
  14222. }
  14223. if(hiddenEvent == null)
  14224. {
  14225. this.hiddenMember = Event.NotSpecified;
  14226. return null;
  14227. }
  14228. this.hiddenMember = hiddenEvent;
  14229. return hiddenEvent;
  14230. }
  14231. set
  14232. {
  14233. this.hiddenMember = value;
  14234. }
  14235. }
  14236. public override Member OverriddenMember
  14237. {
  14238. get
  14239. {
  14240. return this.OverriddenEvent;
  14241. }
  14242. set
  14243. {
  14244. this.OverriddenEvent = (Event)value;
  14245. }
  14246. }
  14247. protected Property overriddenEvent;
  14248. public virtual Event OverriddenEvent
  14249. {
  14250. get
  14251. {
  14252. if(this.overriddenMember == Event.NotSpecified)
  14253. return null;
  14254. Event overriddenEvent = this.overriddenMember as Event;
  14255. if(overriddenEvent != null)
  14256. return overriddenEvent;
  14257. Method overriddenAdder = this.HandlerAdder == null ? null : this.HandlerAdder.OverriddenMethod;
  14258. Method overriddenCaller = this.HandlerCaller == null ? null : this.HandlerCaller.OverriddenMethod;
  14259. Method overriddenRemover = this.HandlerRemover == null ? null : this.HandlerRemover.OverriddenMethod;
  14260. Event overriddenAdderEvent = overriddenAdder == null ? null : overriddenAdder.DeclaringMember as Event;
  14261. Event overriddenCallerEvent = overriddenCaller == null ? null : overriddenCaller.DeclaringMember as Event;
  14262. Event overriddenRemoverEvent = overriddenRemover == null ? null : overriddenRemover.DeclaringMember as Event;
  14263. overriddenEvent = overriddenAdderEvent;
  14264. if(overriddenCallerEvent != null)
  14265. {
  14266. if(overriddenEvent == null ||
  14267. (overriddenCallerEvent.DeclaringType != null && overriddenCallerEvent.DeclaringType.IsDerivedFrom(overriddenEvent.DeclaringType)))
  14268. overriddenEvent = overriddenCallerEvent;
  14269. }
  14270. if(overriddenRemoverEvent != null)
  14271. {
  14272. if(overriddenEvent == null ||
  14273. (overriddenRemoverEvent.DeclaringType != null && overriddenRemoverEvent.DeclaringType.IsDerivedFrom(overriddenEvent.DeclaringType)))
  14274. overriddenEvent = overriddenRemoverEvent;
  14275. }
  14276. if(overriddenEvent == null)
  14277. {
  14278. this.overriddenMember = Event.NotSpecified;
  14279. return null;
  14280. }
  14281. this.overriddenMember = overriddenEvent;
  14282. return overriddenEvent;
  14283. }
  14284. set
  14285. {
  14286. this.overriddenMember = value;
  14287. }
  14288. }
  14289. }
  14290. public class Method : Member
  14291. {
  14292. public TypeNodeList ImplementedTypes;
  14293. public TypeNodeList ImplementedTypeExpressions;
  14294. public bool HasCompilerGeneratedSignature = true;
  14295. public TypeNode ReturnTypeExpression;
  14296. /// <summary>Provides a way to retrieve the parameters and local variables defined in this method given their names.</summary>
  14297. public MethodScope Scope;
  14298. public bool HasOutOfBandContract = false;
  14299. protected TrivialHashtable/*!*/ Locals = new TrivialHashtable();
  14300. public LocalList LocalList;
  14301. protected SecurityAttributeList securityAttributes;
  14302. /// <summary>Contains declarative security information associated with the type.</summary>
  14303. public SecurityAttributeList SecurityAttributes
  14304. {
  14305. get
  14306. {
  14307. if(this.securityAttributes != null)
  14308. return this.securityAttributes;
  14309. if(this.attributes == null)
  14310. {
  14311. // Getting the type attributes also gets the security attributes in the case of a type that
  14312. // was read in by the Reader.
  14313. AttributeList al = this.Attributes;
  14314. if(al != null)
  14315. al = null;
  14316. if(this.securityAttributes != null)
  14317. return this.securityAttributes;
  14318. }
  14319. return this.securityAttributes = new SecurityAttributeList();
  14320. }
  14321. set
  14322. {
  14323. this.securityAttributes = value;
  14324. }
  14325. }
  14326. public delegate void MethodBodyProvider(Method/*!*/ method, object/*!*/ handle, bool asInstructionList);
  14327. public MethodBodyProvider ProvideBody;
  14328. public object ProviderHandle; //Opaque information to be used by the method body provider
  14329. public Method()
  14330. : base(NodeType.Method)
  14331. {
  14332. }
  14333. public Method(MethodBodyProvider provider, object handle)
  14334. : base(NodeType.Method)
  14335. {
  14336. this.ProvideBody = provider;
  14337. this.ProviderHandle = handle;
  14338. }
  14339. public Method(TypeNode declaringType, AttributeList attributes, Identifier name, ParameterList parameters, TypeNode returnType, Block body)
  14340. : base(declaringType, attributes, name, NodeType.Method)
  14341. {
  14342. this.body = body;
  14343. this.Parameters = parameters; // important to use setter here.
  14344. this.returnType = returnType;
  14345. }
  14346. private MethodFlags flags;
  14347. public MethodFlags Flags
  14348. {
  14349. get { return this.flags; }
  14350. set { this.flags = value; }
  14351. }
  14352. private MethodImplFlags implFlags;
  14353. public MethodImplFlags ImplFlags
  14354. {
  14355. get { return this.implFlags; }
  14356. set { this.implFlags = value; }
  14357. }
  14358. private MethodList implementedInterfaceMethods;
  14359. public MethodList ImplementedInterfaceMethods
  14360. {
  14361. get { return this.implementedInterfaceMethods; }
  14362. set { this.implementedInterfaceMethods = value; }
  14363. }
  14364. private MethodList implicitlyImplementedInterfaceMethods;
  14365. /// <summary>
  14366. /// Computes the implicitly implemented methods for any method, not necessarily being compiled.
  14367. /// </summary>
  14368. public MethodList ImplicitlyImplementedInterfaceMethods
  14369. {
  14370. get
  14371. {
  14372. if(this.implicitlyImplementedInterfaceMethods == null)
  14373. {
  14374. this.implicitlyImplementedInterfaceMethods = new MethodList();
  14375. // There are several reasons that this method cannot implicitly implement any interface
  14376. // method.
  14377. if((this.ImplementedInterfaceMethods == null ||
  14378. this.ImplementedInterfaceMethods.Count == 0) && this.IsPublic && !this.IsStatic)
  14379. {
  14380. // It can implicitly implement an interface method for those interfaces that
  14381. // the method's type explicitly declares it implements
  14382. if(this.DeclaringType != null && this.DeclaringType.Interfaces != null)
  14383. {
  14384. foreach(Interface i in this.DeclaringType.Interfaces)
  14385. {
  14386. if(i == null)
  14387. continue;
  14388. Method match = i.GetMatchingMethod(this);
  14389. // !EFW - Bug Fix. Interface methods returning a generic type fail the
  14390. // ReturnType comparison as the types are considered unique. I added an
  14391. // extra check based on the full name to catch those cases so that it does
  14392. // include the implemented generic method. I suppose I could modify the
  14393. // equality operator for TypeNode but I don't want to inadvertently break
  14394. // anything so I'm playing it safe and only fixing the immediate issue here.
  14395. // But it cannot implicitly implement an interface method if there is
  14396. // an explicit implementation in the same type.
  14397. if(match != null && (match.ReturnType == this.ReturnType ||
  14398. match.ReturnType.FullName == this.ReturnType.FullName) &&
  14399. !this.DeclaringType.ImplementsExplicitly(match))
  14400. this.implicitlyImplementedInterfaceMethods.Add(match);
  14401. }
  14402. }
  14403. // It can implicitly implement an interface method if it overrides a base class
  14404. // method and *that* method implicitly implements the interface method.
  14405. // (Note: if this method's type does *not* explicitly declare that it implements
  14406. // the interface, then unless the method overrides a method that does, it is *not*
  14407. // used as an implicit implementation.)
  14408. if(this.OverriddenMethod != null)
  14409. {
  14410. foreach(Method method in this.OverriddenMethod.ImplicitlyImplementedInterfaceMethods)
  14411. // But it cannot implicitly implement an interface method if there is
  14412. // an explicit implementation in the same type.
  14413. if(!this.DeclaringType.ImplementsExplicitly(method))
  14414. this.implicitlyImplementedInterfaceMethods.Add(method);
  14415. }
  14416. }
  14417. }
  14418. return this.implicitlyImplementedInterfaceMethods;
  14419. }
  14420. set
  14421. {
  14422. this.implicitlyImplementedInterfaceMethods = value;
  14423. }
  14424. }
  14425. private CallingConventionFlags callingConvention;
  14426. public CallingConventionFlags CallingConvention
  14427. {
  14428. get { return this.callingConvention; }
  14429. set { this.callingConvention = value; }
  14430. }
  14431. private bool initLocals = true;
  14432. /// <summary>True if all local variables are to be initialized to default values before executing the method body.</summary>
  14433. public bool InitLocals
  14434. {
  14435. get { return this.initLocals; }
  14436. set { this.initLocals = value; }
  14437. }
  14438. private bool isGeneric;
  14439. /// <summary>True if this method is a template that conforms to the rules for a CLR generic method.</summary>
  14440. public bool IsGeneric
  14441. {
  14442. get { return this.isGeneric; }
  14443. set { this.isGeneric = value; }
  14444. }
  14445. private ParameterList parameters;
  14446. /// <summary>The parameters this method has to be called with.</summary>
  14447. public ParameterList Parameters
  14448. {
  14449. get { return this.parameters; }
  14450. set
  14451. {
  14452. this.parameters = value;
  14453. if(value != null)
  14454. {
  14455. for(int i = 0, n = value.Count; i < n; i++)
  14456. {
  14457. Parameter par = parameters[i];
  14458. if(par == null)
  14459. continue;
  14460. par.DeclaringMethod = this;
  14461. }
  14462. }
  14463. }
  14464. }
  14465. private PInvokeFlags pInvokeFlags = PInvokeFlags.None;
  14466. public PInvokeFlags PInvokeFlags
  14467. {
  14468. get { return this.pInvokeFlags; }
  14469. set { this.pInvokeFlags = value; }
  14470. }
  14471. private Module pInvokeModule;
  14472. public Module PInvokeModule
  14473. {
  14474. get { return this.pInvokeModule; }
  14475. set { this.pInvokeModule = value; }
  14476. }
  14477. private string pInvokeImportName;
  14478. public string PInvokeImportName
  14479. {
  14480. get { return this.pInvokeImportName; }
  14481. set { this.pInvokeImportName = value; }
  14482. }
  14483. private AttributeList returnAttributes;
  14484. /// <summary>Attributes that apply to the return value of this method.</summary>
  14485. public AttributeList ReturnAttributes
  14486. {
  14487. get { return this.returnAttributes; }
  14488. set { this.returnAttributes = value; }
  14489. }
  14490. private MarshallingInformation returnTypeMarshallingInformation;
  14491. public MarshallingInformation ReturnTypeMarshallingInformation
  14492. {
  14493. get { return this.returnTypeMarshallingInformation; }
  14494. set { this.returnTypeMarshallingInformation = value; }
  14495. }
  14496. private TypeNode returnType;
  14497. /// <summary>The type of value that this method may return.</summary>
  14498. public TypeNode ReturnType
  14499. {
  14500. get { return this.returnType; }
  14501. set { this.returnType = value; }
  14502. }
  14503. private Member declaringMember;
  14504. /// <summary>Provides the declaring event or property of an accessor.</summary>
  14505. public Member DeclaringMember
  14506. {
  14507. get { return this.declaringMember; }
  14508. set { this.declaringMember = value; }
  14509. }
  14510. private This thisParameter;
  14511. public This ThisParameter
  14512. {
  14513. get
  14514. {
  14515. if(this.thisParameter == null && !this.IsStatic && this.DeclaringType != null)
  14516. {
  14517. if(this.DeclaringType.IsValueType)
  14518. this.ThisParameter = new This(this.DeclaringType.GetReferenceType());
  14519. else
  14520. this.ThisParameter = new This(this.DeclaringType);
  14521. }
  14522. return this.thisParameter;
  14523. }
  14524. set
  14525. {
  14526. if(value != null)
  14527. value.DeclaringMethod = this;
  14528. this.thisParameter = value;
  14529. }
  14530. }
  14531. protected internal Block body;
  14532. /// <summary>The instructions constituting the body of this method, in the form of a tree.</summary>
  14533. public virtual Block Body
  14534. {
  14535. get
  14536. {
  14537. if(this.body != null)
  14538. return this.body;
  14539. if(this.ProvideBody != null && this.ProviderHandle != null)
  14540. {
  14541. lock(Module.GlobalLock)
  14542. {
  14543. if(this.body == null)
  14544. this.ProvideBody(this, this.ProviderHandle, false);
  14545. }
  14546. }
  14547. return this.body;
  14548. }
  14549. set
  14550. {
  14551. this.body = value;
  14552. }
  14553. }
  14554. /// <summary>
  14555. /// A delegate that is called the first time Attributes is accessed, if non-null.
  14556. /// Provides for incremental construction of the type node.
  14557. /// Must not leave Attributes null.
  14558. /// </summary>
  14559. public MethodAttributeProvider ProvideMethodAttributes;
  14560. /// <summary>
  14561. /// The type of delegates that fill in the Attributes property of the given method.
  14562. /// </summary>
  14563. public delegate void MethodAttributeProvider(Method/*!*/ method, object/*!*/ handle);
  14564. public override AttributeList Attributes
  14565. {
  14566. get
  14567. {
  14568. if(this.attributes == null)
  14569. {
  14570. if(this.ProvideMethodAttributes != null && this.ProviderHandle != null)
  14571. {
  14572. lock(Module.GlobalLock)
  14573. {
  14574. if(this.attributes == null)
  14575. this.ProvideMethodAttributes(this, this.ProviderHandle);
  14576. }
  14577. }
  14578. else
  14579. this.attributes = new AttributeList();
  14580. }
  14581. return this.attributes;
  14582. }
  14583. set
  14584. {
  14585. this.attributes = value;
  14586. }
  14587. }
  14588. public void ClearBody()
  14589. {
  14590. lock(Module.GlobalLock)
  14591. {
  14592. this.Body = null;
  14593. this.Instructions = null;
  14594. this.LocalList = null;
  14595. }
  14596. }
  14597. protected string conditionalSymbol;
  14598. protected bool doesNotHaveAConditionalSymbol;
  14599. public string ConditionalSymbol
  14600. {
  14601. get
  14602. {
  14603. if(this.doesNotHaveAConditionalSymbol)
  14604. return null;
  14605. if(this.conditionalSymbol == null)
  14606. {
  14607. lock(this)
  14608. {
  14609. if(this.conditionalSymbol != null)
  14610. return this.conditionalSymbol;
  14611. AttributeNode condAttr = this.GetAttribute(SystemTypes.ConditionalAttribute);
  14612. if(condAttr != null && condAttr.Expressions != null && condAttr.Expressions.Count > 0)
  14613. {
  14614. Literal lit = condAttr.Expressions[0] as Literal;
  14615. if(lit != null)
  14616. {
  14617. this.conditionalSymbol = lit.Value as string;
  14618. if(this.conditionalSymbol != null)
  14619. return this.conditionalSymbol;
  14620. }
  14621. }
  14622. this.doesNotHaveAConditionalSymbol = true;
  14623. }
  14624. }
  14625. return this.conditionalSymbol;
  14626. }
  14627. set
  14628. {
  14629. this.conditionalSymbol = value;
  14630. }
  14631. }
  14632. protected InstructionList instructions;
  14633. /// <summary>The instructions constituting the body of this method, in the form of a linear list of Instruction nodes.</summary>
  14634. public virtual InstructionList Instructions
  14635. {
  14636. get
  14637. {
  14638. if(this.instructions != null)
  14639. return this.instructions;
  14640. if(this.ProvideBody != null && this.ProviderHandle != null)
  14641. {
  14642. lock(Module.GlobalLock)
  14643. {
  14644. if(this.instructions == null)
  14645. this.ProvideBody(this, this.ProviderHandle, true);
  14646. }
  14647. }
  14648. return this.instructions;
  14649. }
  14650. set
  14651. {
  14652. this.instructions = value;
  14653. }
  14654. }
  14655. protected ExceptionHandlerList exceptionHandlers;
  14656. public virtual ExceptionHandlerList ExceptionHandlers
  14657. {
  14658. get
  14659. {
  14660. if(this.exceptionHandlers != null)
  14661. return this.exceptionHandlers;
  14662. Block dummy = this.Body;
  14663. if(this.exceptionHandlers == null)
  14664. this.exceptionHandlers = new ExceptionHandlerList();
  14665. return this.exceptionHandlers;
  14666. }
  14667. set
  14668. {
  14669. this.exceptionHandlers = value;
  14670. }
  14671. }
  14672. protected override Identifier GetDocumentationId()
  14673. {
  14674. if(this.Template != null)
  14675. return this.Template.GetDocumentationId();
  14676. StringBuilder sb = new StringBuilder(this.DeclaringType.DocumentationId.ToString());
  14677. sb[0] = 'M';
  14678. sb.Append('.');
  14679. if(this.NodeType == NodeType.InstanceInitializer)
  14680. sb.Append("#ctor");
  14681. else if(this.Name != null)
  14682. {
  14683. sb.Append(this.Name.ToString());
  14684. if(TargetPlatform.GenericTypeNamesMangleChar != 0 && this.TemplateParameters != null && this.TemplateParameters.Count > 0)
  14685. {
  14686. sb.Append(TargetPlatform.GenericTypeNamesMangleChar);
  14687. sb.Append(TargetPlatform.GenericTypeNamesMangleChar);
  14688. sb.Append(this.TemplateParameters.Count);
  14689. }
  14690. }
  14691. ParameterList parameters = this.Parameters;
  14692. for(int i = 0, n = parameters == null ? 0 : parameters.Count; i < n; i++)
  14693. {
  14694. Parameter par = parameters[i];
  14695. if(par == null || par.Type == null)
  14696. continue;
  14697. if(i == 0)
  14698. sb.Append('(');
  14699. else
  14700. sb.Append(',');
  14701. par.Type.AppendDocumentIdMangledName(sb, this.TemplateParameters, this.DeclaringType.TemplateParameters);
  14702. if(i == n - 1)
  14703. sb.Append(')');
  14704. }
  14705. if(this.IsSpecialName && this.ReturnType != null && this.Name != null &&
  14706. (this.Name.UniqueIdKey == StandardIds.opExplicit.UniqueIdKey || this.Name.UniqueIdKey == StandardIds.opImplicit.UniqueIdKey))
  14707. {
  14708. sb.Append('~');
  14709. this.ReturnType.AppendDocumentIdMangledName(sb, this.TemplateParameters, this.DeclaringType.TemplateParameters);
  14710. }
  14711. return Identifier.For(sb.ToString());
  14712. }
  14713. protected internal string fullName;
  14714. public override string/*!*/ FullName
  14715. {
  14716. get
  14717. {
  14718. if(this.fullName != null)
  14719. return this.fullName;
  14720. StringBuilder sb = new StringBuilder();
  14721. if(this.DeclaringType != null)
  14722. {
  14723. sb.Append(this.DeclaringType.FullName);
  14724. sb.Append('.');
  14725. if(this.NodeType == NodeType.InstanceInitializer)
  14726. sb.Append("#ctor");
  14727. else if(this.Name != null)
  14728. sb.Append(this.Name.ToString());
  14729. ParameterList parameters = this.Parameters;
  14730. for(int i = 0, n = parameters == null ? 0 : parameters.Count; i < n; i++)
  14731. {
  14732. Parameter par = parameters[i];
  14733. if(par == null || par.Type == null)
  14734. continue;
  14735. if(i == 0)
  14736. sb.Append('(');
  14737. else
  14738. sb.Append(',');
  14739. sb.Append(par.Type.FullName);
  14740. if(i == n - 1)
  14741. sb.Append(')');
  14742. }
  14743. }
  14744. return this.fullName = sb.ToString();
  14745. }
  14746. }
  14747. public virtual string GetUnmangledNameWithoutTypeParameters()
  14748. {
  14749. return this.GetUnmangledNameWithoutTypeParameters(false);
  14750. }
  14751. public virtual string GetUnmangledNameWithoutTypeParameters(bool omitParameterTypes)
  14752. {
  14753. StringBuilder sb = new StringBuilder();
  14754. if(this.NodeType == NodeType.InstanceInitializer)
  14755. sb.Append("#ctor");
  14756. else if(this.Name != null)
  14757. {
  14758. string name = this.Name.ToString();
  14759. int lastDot = name.LastIndexOf('.');
  14760. int lastMangle = name.LastIndexOf('>');
  14761. // explicit interface method overrides will have type names in
  14762. // their method name, which may also contain type parameters
  14763. if(lastMangle < lastDot)
  14764. lastMangle = -1;
  14765. if(lastMangle > 0)
  14766. sb.Append(name.Substring(0, lastMangle + 1));
  14767. else
  14768. sb.Append(name);
  14769. }
  14770. if(omitParameterTypes)
  14771. return sb.ToString();
  14772. ParameterList parameters = this.Parameters;
  14773. for(int i = 0, n = parameters == null ? 0 : parameters.Count; i < n; i++)
  14774. {
  14775. Parameter par = parameters[i];
  14776. if(par == null || par.Type == null)
  14777. continue;
  14778. if(i == 0)
  14779. sb.Append('(');
  14780. else
  14781. sb.Append(',');
  14782. sb.Append(par.Type.GetFullUnmangledNameWithTypeParameters());
  14783. if(i == n - 1)
  14784. {
  14785. if(this.IsVarArg)
  14786. {
  14787. sb.Append(", __arglist");
  14788. }
  14789. sb.Append(')');
  14790. }
  14791. }
  14792. return sb.ToString();
  14793. }
  14794. public virtual string GetUnmangledNameWithTypeParameters()
  14795. {
  14796. return this.GetUnmangledNameWithTypeParameters(false);
  14797. }
  14798. public virtual string GetUnmangledNameWithTypeParameters(bool omitParameterTypes)
  14799. {
  14800. StringBuilder sb = new StringBuilder();
  14801. sb.Append(this.GetUnmangledNameWithoutTypeParameters(true));
  14802. TypeNodeList templateParameters = this.TemplateParameters;
  14803. for(int i = 0, n = templateParameters == null ? 0 : templateParameters.Count; i < n; i++)
  14804. {
  14805. TypeNode tpar = templateParameters[i];
  14806. if(tpar == null)
  14807. continue;
  14808. if(i == 0)
  14809. sb.Append('<');
  14810. else
  14811. sb.Append(',');
  14812. sb.Append(tpar.Name.ToString());
  14813. if(i == n - 1)
  14814. sb.Append('>');
  14815. }
  14816. if(omitParameterTypes)
  14817. return sb.ToString();
  14818. ParameterList parameters = this.Parameters;
  14819. for(int i = 0, n = parameters == null ? 0 : parameters.Count; i < n; i++)
  14820. {
  14821. Parameter par = parameters[i];
  14822. if(par == null || par.Type == null)
  14823. continue;
  14824. if(i == 0)
  14825. sb.Append('(');
  14826. else
  14827. sb.Append(',');
  14828. sb.Append(par.Type.GetFullUnmangledNameWithTypeParameters());
  14829. if(i == n - 1)
  14830. sb.Append(')');
  14831. }
  14832. return sb.ToString();
  14833. }
  14834. public virtual string GetFullUnmangledNameWithTypeParameters()
  14835. {
  14836. return this.GetFullUnmangledNameWithTypeParameters(false);
  14837. }
  14838. public virtual string GetFullUnmangledNameWithTypeParameters(bool omitParameterTypes)
  14839. {
  14840. StringBuilder sb = new StringBuilder();
  14841. sb.Append(this.DeclaringType.GetFullUnmangledNameWithTypeParameters());
  14842. sb.Append('.');
  14843. sb.Append(this.GetUnmangledNameWithTypeParameters());
  14844. return sb.ToString();
  14845. }
  14846. public static MethodFlags GetVisibilityUnion(Method m1, Method m2)
  14847. {
  14848. if(m1 == null && m2 != null)
  14849. return m2.Flags & MethodFlags.MethodAccessMask;
  14850. if(m2 == null && m1 != null)
  14851. return m1.Flags & MethodFlags.MethodAccessMask;
  14852. if(m1 == null || m2 == null)
  14853. return MethodFlags.CompilerControlled;
  14854. return Method.GetVisibilityUnion(m1.Flags, m2.Flags);
  14855. }
  14856. public static MethodFlags GetVisibilityUnion(MethodFlags vis1, MethodFlags vis2)
  14857. {
  14858. vis1 &= MethodFlags.MethodAccessMask;
  14859. vis2 &= MethodFlags.MethodAccessMask;
  14860. switch(vis1)
  14861. {
  14862. case MethodFlags.Public:
  14863. return MethodFlags.Public;
  14864. case MethodFlags.Assembly:
  14865. switch(vis2)
  14866. {
  14867. case MethodFlags.Public:
  14868. return MethodFlags.Public;
  14869. case MethodFlags.FamORAssem:
  14870. case MethodFlags.Family:
  14871. return MethodFlags.FamORAssem;
  14872. default:
  14873. return vis1;
  14874. }
  14875. case MethodFlags.FamANDAssem:
  14876. switch(vis2)
  14877. {
  14878. case MethodFlags.Public:
  14879. return MethodFlags.Public;
  14880. case MethodFlags.Assembly:
  14881. return MethodFlags.Assembly;
  14882. case MethodFlags.FamORAssem:
  14883. return MethodFlags.FamORAssem;
  14884. case MethodFlags.Family:
  14885. return MethodFlags.Family;
  14886. default:
  14887. return vis1;
  14888. }
  14889. case MethodFlags.FamORAssem:
  14890. switch(vis2)
  14891. {
  14892. case MethodFlags.Public:
  14893. return MethodFlags.Public;
  14894. default:
  14895. return vis1;
  14896. }
  14897. case MethodFlags.Family:
  14898. switch(vis2)
  14899. {
  14900. case MethodFlags.Public:
  14901. return MethodFlags.Public;
  14902. case MethodFlags.FamORAssem:
  14903. case MethodFlags.Assembly:
  14904. return MethodFlags.FamORAssem;
  14905. default:
  14906. return vis1;
  14907. }
  14908. default:
  14909. return vis2;
  14910. }
  14911. }
  14912. public virtual object Invoke(object targetObject, params object[] arguments)
  14913. {
  14914. System.Reflection.MethodInfo methInfo = this.GetMethodInfo();
  14915. if(methInfo == null)
  14916. return null;
  14917. return methInfo.Invoke(targetObject, arguments);
  14918. }
  14919. public virtual Literal Invoke(Literal/*!*/ targetObject, params Literal[] arguments)
  14920. {
  14921. int n = arguments == null ? 0 : arguments.Length;
  14922. object[] args = n == 0 ? null : new object[n];
  14923. if(args != null && arguments != null)
  14924. for(int i = 0; i < n; i++)
  14925. {
  14926. Literal lit = arguments[i];
  14927. args[i] = lit == null ? null : lit.Value;
  14928. }
  14929. return new Literal(this.Invoke(targetObject.Value, args));
  14930. }
  14931. protected bool isNormalized;
  14932. public virtual bool IsNormalized
  14933. {
  14934. get
  14935. {
  14936. if(this.isNormalized)
  14937. return true;
  14938. if(this.DeclaringType == null || this.SourceContext.Document != null)
  14939. return false;
  14940. return this.isNormalized = this.DeclaringType.IsNormalized;
  14941. }
  14942. set
  14943. {
  14944. this.isNormalized = value;
  14945. }
  14946. }
  14947. public virtual bool IsAbstract
  14948. {
  14949. get { return (this.Flags & MethodFlags.Abstract) != 0; }
  14950. }
  14951. public override bool IsAssembly
  14952. {
  14953. get { return (this.Flags & MethodFlags.MethodAccessMask) == MethodFlags.Assembly; }
  14954. }
  14955. public override bool IsCompilerControlled
  14956. {
  14957. get { return (this.Flags & MethodFlags.MethodAccessMask) == MethodFlags.CompilerControlled; }
  14958. }
  14959. public virtual bool IsExtern
  14960. {
  14961. get { return (this.Flags & MethodFlags.PInvokeImpl) != 0 || (this.ImplFlags & (MethodImplFlags.Runtime | MethodImplFlags.InternalCall)) != 0; }
  14962. }
  14963. public override bool IsFamily
  14964. {
  14965. get { return (this.Flags & MethodFlags.MethodAccessMask) == MethodFlags.Family; }
  14966. }
  14967. public override bool IsFamilyAndAssembly
  14968. {
  14969. get { return (this.Flags & MethodFlags.MethodAccessMask) == MethodFlags.FamANDAssem; }
  14970. }
  14971. public override bool IsFamilyOrAssembly
  14972. {
  14973. get { return (this.Flags & MethodFlags.MethodAccessMask) == MethodFlags.FamORAssem; }
  14974. }
  14975. public virtual bool IsFinal
  14976. {
  14977. get { return (this.Flags & MethodFlags.Final) != 0; }
  14978. }
  14979. public virtual bool IsInternalCall
  14980. {
  14981. get { return (this.ImplFlags & MethodImplFlags.InternalCall) != 0; }
  14982. }
  14983. public override bool IsPrivate
  14984. {
  14985. get { return (this.Flags & MethodFlags.MethodAccessMask) == MethodFlags.Private; }
  14986. }
  14987. public override bool IsPublic
  14988. {
  14989. get { return (this.Flags & MethodFlags.MethodAccessMask) == MethodFlags.Public; }
  14990. }
  14991. public override bool IsSpecialName
  14992. {
  14993. get { return (this.Flags & MethodFlags.SpecialName) != 0; }
  14994. }
  14995. public override bool IsStatic
  14996. {
  14997. get { return (this.Flags & MethodFlags.Static) != 0; }
  14998. }
  14999. /// <summary>
  15000. /// True if this method can in principle be overridden by a method in a derived class.
  15001. /// </summary>
  15002. public virtual bool IsVirtual
  15003. {
  15004. get { return (this.Flags & MethodFlags.Virtual) != 0; }
  15005. }
  15006. public virtual bool IsNonSealedVirtual
  15007. {
  15008. get
  15009. {
  15010. return (this.Flags & MethodFlags.Virtual) != 0 && (this.Flags & MethodFlags.Final) == 0 &&
  15011. (this.DeclaringType == null || (this.DeclaringType.Flags & TypeFlags.Sealed) == 0);
  15012. }
  15013. }
  15014. public virtual bool IsVirtualAndNotDeclaredInStruct
  15015. {
  15016. get
  15017. {
  15018. return (this.Flags & MethodFlags.Virtual) != 0 && (this.DeclaringType == null || !(this.DeclaringType is Struct));
  15019. }
  15020. }
  15021. public override bool IsVisibleOutsideAssembly
  15022. {
  15023. get
  15024. {
  15025. if(this.DeclaringType != null && !this.DeclaringType.IsVisibleOutsideAssembly)
  15026. return false;
  15027. switch(this.Flags & MethodFlags.MethodAccessMask)
  15028. {
  15029. case MethodFlags.Public:
  15030. return true;
  15031. case MethodFlags.Family:
  15032. case MethodFlags.FamORAssem:
  15033. if(this.DeclaringType != null && !this.DeclaringType.IsSealed)
  15034. return true;
  15035. goto default;
  15036. default:
  15037. for(int i = 0, n = this.ImplementedInterfaceMethods == null ? 0 : this.ImplementedInterfaceMethods.Count; i < n; i++)
  15038. {
  15039. Method m = this.ImplementedInterfaceMethods[i];
  15040. if(m == null)
  15041. continue;
  15042. if(m.DeclaringType != null && !m.DeclaringType.IsVisibleOutsideAssembly)
  15043. continue;
  15044. if(m.IsVisibleOutsideAssembly)
  15045. return true;
  15046. }
  15047. return false;
  15048. }
  15049. }
  15050. }
  15051. public bool IsVarArg
  15052. {
  15053. get { return (this.CallingConvention & CallingConventionFlags.VarArg) != 0; }
  15054. }
  15055. // whether this is a FieldInitializerMethod (declared in Sing#)
  15056. public virtual bool IsFieldInitializerMethod
  15057. {
  15058. get
  15059. {
  15060. return false;
  15061. }
  15062. }
  15063. public override Member HiddenMember
  15064. {
  15065. get
  15066. {
  15067. return this.HiddenMethod;
  15068. }
  15069. set
  15070. {
  15071. this.HiddenMethod = (Method)value;
  15072. }
  15073. }
  15074. public virtual Method HiddenMethod
  15075. {
  15076. get
  15077. {
  15078. if(this.hiddenMember == Method.NotSpecified)
  15079. return null;
  15080. Method hiddenMethod = this.hiddenMember as Method;
  15081. if(hiddenMethod != null)
  15082. return hiddenMethod;
  15083. if(this.ProvideBody == null)
  15084. return null;
  15085. if(this.IsVirtual && (this.Flags & MethodFlags.VtableLayoutMask) != MethodFlags.NewSlot)
  15086. return null;
  15087. TypeNode baseType = this.DeclaringType.BaseType;
  15088. while(baseType != null)
  15089. {
  15090. MemberList baseMembers = baseType.GetMembersNamed(this.Name);
  15091. if(baseMembers != null)
  15092. for(int i = 0, n = baseMembers.Count; i < n; i++)
  15093. {
  15094. Method bmeth = baseMembers[i] as Method;
  15095. if(bmeth == null)
  15096. continue;
  15097. if(!bmeth.ParametersMatch(this.Parameters))
  15098. {
  15099. if(this.TemplateParameters != null && this.TemplateParametersMatch(bmeth.TemplateParameters))
  15100. {
  15101. if(!bmeth.ParametersMatchStructurally(this.Parameters))
  15102. continue;
  15103. }
  15104. else
  15105. continue;
  15106. }
  15107. hiddenMethod = bmeth;
  15108. goto done;
  15109. }
  15110. baseType = baseType.BaseType;
  15111. }
  15112. done:
  15113. if(hiddenMethod == null)
  15114. {
  15115. this.hiddenMember = Method.NotSpecified;
  15116. return null;
  15117. }
  15118. this.hiddenMember = hiddenMethod;
  15119. return hiddenMethod;
  15120. }
  15121. set
  15122. {
  15123. this.hiddenMember = value;
  15124. }
  15125. }
  15126. public override Member OverriddenMember
  15127. {
  15128. get
  15129. {
  15130. return this.OverriddenMethod;
  15131. }
  15132. set
  15133. {
  15134. this.OverriddenMethod = (Method)value;
  15135. }
  15136. }
  15137. public virtual Method OverriddenMethod
  15138. {
  15139. get
  15140. {
  15141. if((this.Flags & MethodFlags.VtableLayoutMask) == MethodFlags.NewSlot)
  15142. return null;
  15143. if(this.overriddenMember == Method.NotSpecified)
  15144. return null;
  15145. Method overriddenMethod = this.overriddenMember as Method;
  15146. if(overriddenMethod != null)
  15147. return overriddenMethod;
  15148. if(this.ProvideBody == null)
  15149. return null;
  15150. if(!this.IsVirtual)
  15151. return null;
  15152. TypeNode baseType = this.DeclaringType.BaseType;
  15153. while(baseType != null)
  15154. {
  15155. MemberList baseMembers = baseType.GetMembersNamed(this.Name);
  15156. if(baseMembers != null)
  15157. for(int i = 0, n = baseMembers.Count; i < n; i++)
  15158. {
  15159. Method bmeth = baseMembers[i] as Method;
  15160. if(bmeth == null)
  15161. continue;
  15162. if(!bmeth.ParametersMatch(this.Parameters))
  15163. {
  15164. if(this.TemplateParameters != null && this.TemplateParametersMatch(bmeth.TemplateParameters))
  15165. {
  15166. if(!bmeth.ParametersMatchStructurally(this.Parameters))
  15167. continue;
  15168. }
  15169. else
  15170. continue;
  15171. }
  15172. overriddenMethod = bmeth;
  15173. goto done;
  15174. }
  15175. baseType = baseType.BaseType;
  15176. }
  15177. done:
  15178. if(overriddenMethod == null)
  15179. {
  15180. this.overriddenMember = Method.NotSpecified;
  15181. return null;
  15182. }
  15183. this.overriddenMember = overriddenMethod;
  15184. return overriddenMethod;
  15185. }
  15186. set
  15187. {
  15188. this.overriddenMember = value;
  15189. }
  15190. }
  15191. public static Method GetMethod(System.Reflection.MethodInfo methodInfo)
  15192. {
  15193. if(methodInfo == null)
  15194. return null;
  15195. if(methodInfo.IsGenericMethod && !methodInfo.IsGenericMethodDefinition)
  15196. {
  15197. try
  15198. {
  15199. Method template = Method.GetMethod(methodInfo.GetGenericMethodDefinition());
  15200. if(template == null)
  15201. return null;
  15202. TypeNodeList templateArguments = new TypeNodeList();
  15203. foreach(Type arg in methodInfo.GetGenericArguments())
  15204. templateArguments.Add(TypeNode.GetTypeNode(arg));
  15205. return template.GetTemplateInstance(template.DeclaringType, templateArguments);
  15206. }
  15207. catch
  15208. {
  15209. //TODO: log error
  15210. return null;
  15211. }
  15212. }
  15213. TypeNode tn = TypeNode.GetTypeNode(methodInfo.DeclaringType);
  15214. if(tn == null)
  15215. return null;
  15216. System.Reflection.ParameterInfo[] paramInfos = methodInfo.GetParameters();
  15217. int n = paramInfos == null ? 0 : paramInfos.Length;
  15218. TypeNode[] parameterTypes = new TypeNode[n];
  15219. for(int i = 0; i < n; i++)
  15220. {
  15221. System.Reflection.ParameterInfo param = paramInfos[i];
  15222. if(param == null)
  15223. return null;
  15224. parameterTypes[i] = TypeNode.GetTypeNode(param.ParameterType);
  15225. }
  15226. TypeNodeList paramTypes = new TypeNodeList(parameterTypes);
  15227. TypeNode returnType = TypeNode.GetTypeNode(methodInfo.ReturnType);
  15228. MemberList members = tn.GetMembersNamed(Identifier.For(methodInfo.Name));
  15229. for(int i = 0, m = members == null ? 0 : members.Count; i < m; i++)
  15230. {
  15231. Method meth = members[i] as Method;
  15232. if(meth == null)
  15233. continue;
  15234. if(!meth.ParameterTypesMatch(paramTypes))
  15235. continue;
  15236. if(meth.ReturnType != returnType)
  15237. continue;
  15238. return meth;
  15239. }
  15240. return null;
  15241. }
  15242. protected System.Reflection.Emit.DynamicMethod dynamicMethod;
  15243. protected System.Reflection.MethodInfo methodInfo;
  15244. public virtual System.Reflection.MethodInfo GetMethodInfo()
  15245. {
  15246. if(this.methodInfo == null)
  15247. {
  15248. if(this.DeclaringType == null)
  15249. return null;
  15250. if(this.IsGeneric && this.Template != null)
  15251. {
  15252. try
  15253. {
  15254. System.Reflection.MethodInfo templateInfo = this.Template.GetMethodInfo();
  15255. if(templateInfo == null)
  15256. return null;
  15257. TypeNodeList args = this.TemplateArguments;
  15258. Type[] arguments = new Type[args.Count];
  15259. for(int i = 0; i < args.Count; i++)
  15260. arguments[i] = args[i].GetRuntimeType();
  15261. return templateInfo.MakeGenericMethod(arguments);
  15262. }
  15263. catch
  15264. {
  15265. //TODO: log error
  15266. return null;
  15267. }
  15268. }
  15269. Type t = this.DeclaringType.GetRuntimeType();
  15270. if(t == null)
  15271. return null;
  15272. Type retType = typeof(object);
  15273. if(!this.isGeneric)
  15274. {
  15275. //Can't do this for generic methods since it may involve a method type parameter
  15276. retType = this.ReturnType.GetRuntimeType();
  15277. if(retType == null)
  15278. return null;
  15279. }
  15280. ParameterList pars = this.Parameters;
  15281. int n = pars == null ? 0 : pars.Count;
  15282. Type[] types = new Type[n];
  15283. for(int i = 0; i < n; i++)
  15284. {
  15285. Parameter p = pars[i];
  15286. if(p == null || p.Type == null)
  15287. return null;
  15288. Type pt;
  15289. if(this.isGeneric)
  15290. pt = types[i] = typeof(object); //Have to cheat here since the type might involve a type parameter of the method and getting the runtime type for that is a problem
  15291. //unless we already have the method info in hand
  15292. else
  15293. pt = types[i] = p.Type.GetRuntimeType();
  15294. if(pt == null)
  15295. return null;
  15296. }
  15297. System.Reflection.MemberInfo[] members = t.GetMember(this.Name.ToString(), System.Reflection.MemberTypes.Method,
  15298. BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
  15299. foreach(System.Reflection.MethodInfo meth in members)
  15300. {
  15301. if(meth == null)
  15302. continue;
  15303. if(meth.IsStatic != this.IsStatic)
  15304. continue;
  15305. if(meth.ReturnType != retType)
  15306. continue;
  15307. if(meth.IsGenericMethodDefinition)
  15308. {
  15309. TypeNodeList templateParams = this.TemplateParameters;
  15310. Type[] genericArgs = meth.GetGenericArguments();
  15311. if(templateParams == null || genericArgs == null || templateParameters.Count != genericArgs.Length)
  15312. goto tryNext;
  15313. for(int i = 0, m = genericArgs.Length; i < m; i++)
  15314. {
  15315. TypeNode t1 = templateParameters[i];
  15316. Type t2 = genericArgs[i];
  15317. if(t1 == null || t2 == null || t1.Name == null || t1.Name.Name != t2.Name)
  15318. goto tryNext;
  15319. }
  15320. }
  15321. System.Reflection.ParameterInfo[] parameters = meth.GetParameters();
  15322. int parCount = parameters == null ? 0 : parameters.Length;
  15323. if(parCount != n)
  15324. continue;
  15325. for(int i = 0; i < n; i++)
  15326. {
  15327. //^ assert parameters != null;
  15328. System.Reflection.ParameterInfo par = parameters[i];
  15329. if(par == null)
  15330. goto tryNext;
  15331. if(this.isGeneric)
  15332. {
  15333. //We don't have the runtime type for the parameter, so just check that the name is the same
  15334. Parameter p = pars[i];
  15335. if(par.Name != p.Name.Name)
  15336. goto tryNext;
  15337. }
  15338. else
  15339. {
  15340. if(par.ParameterType != types[i])
  15341. goto tryNext;
  15342. }
  15343. }
  15344. return this.methodInfo = meth;
  15345. tryNext:
  15346. ;
  15347. }
  15348. }
  15349. return this.methodInfo;
  15350. }
  15351. protected TypeNode[] parameterTypes;
  15352. public virtual TypeNode[]/*!*/ GetParameterTypes()
  15353. {
  15354. if(this.parameterTypes != null)
  15355. return this.parameterTypes;
  15356. ParameterList pars = this.Parameters;
  15357. int n = pars == null ? 0 : pars.Count;
  15358. TypeNode[] types = this.parameterTypes = new TypeNode[n];
  15359. for(int i = 0; i < n; i++)
  15360. {
  15361. Parameter p = pars[i];
  15362. if(p == null)
  15363. continue;
  15364. types[i] = p.Type;
  15365. }
  15366. return types;
  15367. }
  15368. public virtual bool ParametersMatch(ParameterList parameters)
  15369. {
  15370. ParameterList pars = this.Parameters;
  15371. int n = pars == null ? 0 : pars.Count;
  15372. int m = parameters == null ? 0 : parameters.Count;
  15373. if(n != m)
  15374. return false;
  15375. if(parameters == null)
  15376. return true;
  15377. for(int i = 0; i < n; i++)
  15378. {
  15379. Parameter par1 = pars[i];
  15380. Parameter par2 = parameters[i];
  15381. if(par1 == null || par2 == null)
  15382. return false;
  15383. if(par1.Type != par2.Type)
  15384. return false;
  15385. }
  15386. return true;
  15387. }
  15388. public virtual bool ParametersMatchExceptLast(ParameterList parameters)
  15389. {
  15390. ParameterList pars = this.Parameters;
  15391. int n = pars == null ? 0 : pars.Count;
  15392. int m = parameters == null ? 0 : parameters.Count;
  15393. if(n != m)
  15394. return false;
  15395. if(parameters == null)
  15396. return true;
  15397. for(int i = 0; i < n - 1; i++)
  15398. {
  15399. Parameter par1 = pars[i];
  15400. Parameter par2 = parameters[i];
  15401. if(par1 == null || par2 == null)
  15402. return false;
  15403. if(par1.Type != par2.Type)
  15404. return false;
  15405. }
  15406. return true;
  15407. }
  15408. public virtual bool ParametersMatchStructurally(ParameterList parameters)
  15409. {
  15410. ParameterList pars = this.Parameters;
  15411. int n = pars == null ? 0 : pars.Count;
  15412. int m = parameters == null ? 0 : parameters.Count;
  15413. if(n != m)
  15414. return false;
  15415. if(parameters == null)
  15416. return true;
  15417. for(int i = 0; i < n; i++)
  15418. {
  15419. Parameter par1 = pars[i];
  15420. Parameter par2 = parameters[i];
  15421. if(par1 == null || par2 == null)
  15422. return false;
  15423. if(par1.Type == null || par2.Type == null)
  15424. return false;
  15425. if(par1.Type != par2.Type && !par1.Type.IsStructurallyEquivalentTo(par2.Type))
  15426. return false;
  15427. }
  15428. return true;
  15429. }
  15430. public virtual bool ParametersMatchStructurallyIncludingOutFlag(ParameterList parameters)
  15431. {
  15432. return this.ParametersMatchStructurallyIncludingOutFlag(parameters, false);
  15433. }
  15434. public virtual bool ParametersMatchStructurallyIncludingOutFlag(ParameterList parameters, bool allowCoVariance)
  15435. {
  15436. ParameterList pars = this.Parameters;
  15437. int n = pars == null ? 0 : pars.Count;
  15438. int m = parameters == null ? 0 : parameters.Count;
  15439. if(n != m)
  15440. return false;
  15441. if(parameters == null)
  15442. return true;
  15443. for(int i = 0; i < n; i++)
  15444. {
  15445. Parameter par1 = pars[i];
  15446. Parameter par2 = parameters[i];
  15447. if(par1 == null || par2 == null)
  15448. return false;
  15449. if(par1.Type == null || par2.Type == null)
  15450. return false;
  15451. if((par1.Flags & ParameterFlags.Out) != (par2.Flags & ParameterFlags.Out))
  15452. return false;
  15453. if(par1.Type != par2.Type && !par1.Type.IsStructurallyEquivalentTo(par2.Type))
  15454. {
  15455. if(allowCoVariance && !par2.Type.IsValueType)
  15456. return par2.Type.IsAssignableTo(par1.Type);
  15457. return false;
  15458. }
  15459. }
  15460. return true;
  15461. }
  15462. public virtual bool ParametersMatchStructurallyExceptLast(ParameterList parameters)
  15463. {
  15464. ParameterList pars = this.Parameters;
  15465. int n = pars == null ? 0 : pars.Count;
  15466. int m = parameters == null ? 0 : parameters.Count;
  15467. if(n != m)
  15468. return false;
  15469. if(parameters == null)
  15470. return true;
  15471. for(int i = 0; i < n - 1; i++)
  15472. {
  15473. Parameter par1 = pars[i];
  15474. Parameter par2 = parameters[i];
  15475. if(par1 == null || par2 == null)
  15476. return false;
  15477. if(par1.Type == null || par2.Type == null)
  15478. return false;
  15479. if(par1.Type != par2.Type && !par1.Type.IsStructurallyEquivalentTo(par2.Type))
  15480. return false;
  15481. }
  15482. return true;
  15483. }
  15484. public virtual bool ParametersMatchIncludingOutFlag(ParameterList parameters)
  15485. {
  15486. ParameterList pars = this.Parameters;
  15487. int n = pars == null ? 0 : pars.Count;
  15488. int m = parameters == null ? 0 : parameters.Count;
  15489. if(n != m)
  15490. return false;
  15491. if(parameters == null)
  15492. return true;
  15493. for(int i = 0; i < n; i++)
  15494. {
  15495. Parameter par1 = pars[i];
  15496. Parameter par2 = parameters[i];
  15497. if(par1.Type != par2.Type)
  15498. return false;
  15499. if((par1.Flags & ParameterFlags.Out) != (par2.Flags & ParameterFlags.Out))
  15500. return false;
  15501. }
  15502. return true;
  15503. }
  15504. public virtual bool ParameterTypesMatch(TypeNodeList argumentTypes)
  15505. {
  15506. int n = this.Parameters == null ? 0 : this.Parameters.Count;
  15507. int m = argumentTypes == null ? 0 : argumentTypes.Count;
  15508. if(n != m)
  15509. return false;
  15510. if(argumentTypes == null)
  15511. return true;
  15512. for(int i = 0; i < n; i++)
  15513. {
  15514. Parameter par = this.Parameters[i];
  15515. if(par == null)
  15516. return false;
  15517. TypeNode argType = argumentTypes[i];
  15518. if(par.Type != argType)
  15519. {
  15520. TypeNode pType = TypeNode.StripModifiers(par.Type);
  15521. argType = TypeNode.StripModifiers(argType);
  15522. if(pType != argType)
  15523. return false;
  15524. }
  15525. }
  15526. return true;
  15527. }
  15528. public virtual bool ParameterTypesMatchStructurally(TypeNodeList argumentTypes)
  15529. {
  15530. int n = this.Parameters == null ? 0 : this.Parameters.Count;
  15531. int m = argumentTypes == null ? 0 : argumentTypes.Count;
  15532. if(n != m)
  15533. return false;
  15534. if(argumentTypes == null)
  15535. return true;
  15536. for(int i = 0; i < n; i++)
  15537. {
  15538. Parameter par = this.Parameters[i];
  15539. TypeNode argType = argumentTypes[i];
  15540. if(par.Type != argType)
  15541. {
  15542. TypeNode pType = TypeNode.StripModifiers(par.Type);
  15543. argType = TypeNode.StripModifiers(argType);
  15544. if(pType == null || !pType.IsStructurallyEquivalentTo(argType))
  15545. return false;
  15546. }
  15547. }
  15548. return true;
  15549. }
  15550. public virtual bool TemplateParametersMatch(TypeNodeList templateParameters)
  15551. {
  15552. TypeNodeList locPars = this.TemplateParameters;
  15553. if(locPars == null)
  15554. return templateParameters == null || templateParameters.Count == 0;
  15555. if(templateParameters == null)
  15556. return false;
  15557. int n = locPars.Count;
  15558. if(n != templateParameters.Count)
  15559. return false;
  15560. for(int i = 0; i < n; i++)
  15561. {
  15562. TypeNode tp1 = locPars[i];
  15563. TypeNode tp2 = templateParameters[i];
  15564. if(tp1 == null || tp2 == null)
  15565. return false;
  15566. if(tp1 != tp2 && !tp1.IsStructurallyEquivalentTo(tp2))
  15567. return false;
  15568. }
  15569. return true;
  15570. }
  15571. internal TrivialHashtable contextForOffset;
  15572. internal void RecordSequencePoints(ISymUnmanagedMethod methodInfo)
  15573. {
  15574. if(methodInfo == null || this.contextForOffset != null)
  15575. return;
  15576. this.contextForOffset = new TrivialHashtable();
  15577. uint count = methodInfo.GetSequencePointCount();
  15578. IntPtr[] docPtrs = new IntPtr[count];
  15579. uint[] startLines = new uint[count];
  15580. uint[] startCols = new uint[count];
  15581. uint[] endLines = new uint[count];
  15582. uint[] endCols = new uint[count];
  15583. uint[] offsets = new uint[count];
  15584. uint numPoints;
  15585. methodInfo.GetSequencePoints(count, out numPoints, offsets, docPtrs, startLines, startCols, endLines, endCols);
  15586. Debug.Assert(count == numPoints);
  15587. for(int i = 0; i < count; i++)
  15588. {
  15589. //The magic hex constant below works around weird data reported from GetSequencePoints.
  15590. //The constant comes from ILDASM's source code, which performs essentially the same test.
  15591. const uint Magic = 0xFEEFEE;
  15592. if(startLines[i] >= Magic || endLines[i] >= Magic)
  15593. continue;
  15594. UnmanagedDocument doc = new UnmanagedDocument(docPtrs[i]);
  15595. this.contextForOffset[(int)offsets[i] + 1] = new SourceContext(doc,
  15596. doc.GetOffset(startLines[i], startCols[i]), doc.GetOffset(endLines[i], endCols[i]));
  15597. }
  15598. for(int i = 0; i < count; i++)
  15599. System.Runtime.InteropServices.Marshal.Release(docPtrs[i]);
  15600. }
  15601. private static Method NotSpecified = new Method();
  15602. private Method template;
  15603. /// <summary>The (generic) method template from which this method was instantiated. Null if this is not a (generic) method template instance.</summary>
  15604. public Method Template
  15605. {
  15606. get
  15607. {
  15608. Method result = this.template;
  15609. if(result == Method.NotSpecified)
  15610. return null;
  15611. return result;
  15612. }
  15613. set
  15614. {
  15615. this.template = value;
  15616. }
  15617. }
  15618. private TypeNodeList templateArguments;
  15619. /// <summary>
  15620. /// The arguments used when this (generic) method template instance was instantiated.
  15621. /// </summary>
  15622. public TypeNodeList TemplateArguments
  15623. {
  15624. get { return this.templateArguments; }
  15625. set { this.templateArguments = value; }
  15626. }
  15627. internal TypeNodeList templateParameters;
  15628. public virtual TypeNodeList TemplateParameters
  15629. {
  15630. get
  15631. {
  15632. TypeNodeList result = this.templateParameters;
  15633. return result;
  15634. }
  15635. set
  15636. {
  15637. this.templateParameters = value;
  15638. }
  15639. }
  15640. public virtual Method/*!*/ GetTemplateInstance(TypeNode referringType, params TypeNode[] typeArguments)
  15641. {
  15642. return this.GetTemplateInstance(referringType, new TypeNodeList(typeArguments));
  15643. }
  15644. public virtual Method/*!*/ GetTemplateInstance(TypeNode referringType, TypeNodeList typeArguments)
  15645. {
  15646. if(referringType == null || this.DeclaringType == null) { Debug.Assert(false); return this; }
  15647. if(this.IsGeneric)
  15648. referringType = this.DeclaringType;
  15649. if(referringType != this.DeclaringType && referringType.DeclaringModule == this.DeclaringType.DeclaringModule)
  15650. return this.GetTemplateInstance(this.DeclaringType, typeArguments);
  15651. if(referringType.structurallyEquivalentMethod == null)
  15652. referringType.structurallyEquivalentMethod = new TrivialHashtableUsingWeakReferences();
  15653. Module module = referringType.DeclaringModule;
  15654. if(module == null)
  15655. return this;
  15656. int n = typeArguments == null ? 0 : typeArguments.Count;
  15657. if(n == 0 || typeArguments == null)
  15658. return this;
  15659. StringBuilder sb = new StringBuilder(this.Name.ToString());
  15660. sb.Append('<');
  15661. for(int i = 0; i < n; i++)
  15662. {
  15663. TypeNode ta = typeArguments[i];
  15664. if(ta == null)
  15665. continue;
  15666. sb.Append(ta.FullName);
  15667. if(i < n - 1)
  15668. sb.Append(',');
  15669. }
  15670. sb.Append('>');
  15671. Identifier mangledName = Identifier.For(sb.ToString());
  15672. lock(this)
  15673. {
  15674. Method m = (Method)referringType.structurallyEquivalentMethod[mangledName.UniqueIdKey];
  15675. int counter = 1;
  15676. while(m != null)
  15677. {
  15678. if(m.template == this && Method.TypeListsAreEquivalent(m.TemplateArguments, typeArguments))
  15679. return m;
  15680. mangledName = Identifier.For(mangledName.ToString() + counter++);
  15681. m = (Method)referringType.structurallyEquivalentMethod[mangledName.UniqueIdKey];
  15682. }
  15683. Duplicator duplicator = new Duplicator(referringType.DeclaringModule, referringType);
  15684. duplicator.RecordOriginalAsTemplate = true;
  15685. duplicator.SkipBodies = true;
  15686. Method result = duplicator.VisitMethod(this);
  15687. //^ assume result != null;
  15688. result.Attributes = this.Attributes; //These do not get specialized, but may need to get normalized
  15689. result.Name = mangledName;
  15690. result.fullName = null;
  15691. result.template = this;
  15692. result.TemplateArguments = typeArguments;
  15693. TypeNodeList templateParameters = result.TemplateParameters;
  15694. result.TemplateParameters = null;
  15695. result.IsNormalized = true;
  15696. if(!this.IsGeneric)
  15697. {
  15698. ParameterList pars = this.Parameters;
  15699. ParameterList rpars = result.Parameters;
  15700. if(pars != null && rpars != null && rpars.Count >= pars.Count)
  15701. for(int i = 0, count = pars.Count; i < count; i++)
  15702. {
  15703. Parameter p = pars[i];
  15704. Parameter rp = rpars[i];
  15705. if(p == null || rp == null)
  15706. continue;
  15707. rp.Attributes = p.Attributes; //These do not get specialized, but may need to get normalized
  15708. }
  15709. }
  15710. if(!this.IsGeneric && !(result.IsStatic) && this.DeclaringType != referringType)
  15711. {
  15712. result.Flags &= ~(MethodFlags.Virtual | MethodFlags.NewSlot);
  15713. result.Flags |= MethodFlags.Static;
  15714. result.CallingConvention &= ~CallingConventionFlags.HasThis;
  15715. result.CallingConvention |= CallingConventionFlags.ExplicitThis;
  15716. ParameterList pars = result.Parameters;
  15717. if(pars == null)
  15718. result.Parameters = pars = new ParameterList();
  15719. Parameter thisPar = new Parameter(StandardIds.This, this.DeclaringType);
  15720. pars.Add(thisPar);
  15721. for(int i = pars.Count - 1; i > 0; i--)
  15722. pars[i] = pars[i - 1];
  15723. pars[0] = thisPar;
  15724. }
  15725. referringType.structurallyEquivalentMethod[mangledName.UniqueIdKey] = result;
  15726. Specializer specializer = new Specializer(module, templateParameters, typeArguments);
  15727. specializer.VisitMethod(result);
  15728. if(this.IsGeneric) { result.DeclaringType = this.DeclaringType; return result; }
  15729. if(this.IsAbstract)
  15730. return result;
  15731. referringType.Members.Add(result);
  15732. return result;
  15733. }
  15734. }
  15735. private static bool TypeListsAreEquivalent(TypeNodeList list1, TypeNodeList list2)
  15736. {
  15737. if(list1 == null || list2 == null)
  15738. return list1 == list2;
  15739. int n = list1.Count;
  15740. if(n != list2.Count)
  15741. return false;
  15742. for(int i = 0; i < n; i++)
  15743. if(list1[i] != list2[i])
  15744. return false;
  15745. return true;
  15746. }
  15747. /// <summary>
  15748. /// Returns the local associated with the given field, allocating a new local if necessary.
  15749. /// </summary>
  15750. public virtual Local/*!*/ GetLocalForField(Field/*!*/ f)
  15751. {
  15752. Local loc = (Local)this.Locals[f.UniqueKey];
  15753. if(loc == null)
  15754. {
  15755. this.Locals[f.UniqueKey] = loc = new Local(f.Name, f.Type);
  15756. loc.SourceContext = f.Name.SourceContext;
  15757. }
  15758. return loc;
  15759. }
  15760. //TODO: Also need to add a method for allocating locals
  15761. public Method CreateExplicitImplementation(TypeNode implementingType, ParameterList parameters, StatementList body)
  15762. {
  15763. Method m = new Method(implementingType, null, this.Name, parameters, this.ReturnType, new Block(body));
  15764. m.CallingConvention = CallingConventionFlags.HasThis;
  15765. m.Flags = MethodFlags.Public | MethodFlags.HideBySig | MethodFlags.Virtual | MethodFlags.NewSlot | MethodFlags.Final;
  15766. m.ImplementedInterfaceMethods = new MethodList(new[] { this });
  15767. //m.ImplementedTypes = new TypeNodeList(this.DeclaringType);
  15768. return m;
  15769. }
  15770. public virtual bool TypeParameterCountsMatch(Method meth2)
  15771. {
  15772. if(meth2 == null)
  15773. return false;
  15774. int n = this.TemplateParameters == null ? 0 : this.TemplateParameters.Count;
  15775. int m = meth2.TemplateParameters == null ? 0 : meth2.TemplateParameters.Count;
  15776. return n == m;
  15777. }
  15778. public override string ToString()
  15779. {
  15780. return this.DeclaringType.GetFullUnmangledNameWithTypeParameters() + "." + this.Name;
  15781. }
  15782. public bool GetIsCompilerGenerated()
  15783. {
  15784. InstanceInitializer ii = this as InstanceInitializer;
  15785. return this.HasCompilerGeneratedSignature || (ii != null && ii.IsCompilerGenerated);
  15786. }
  15787. }
  15788. public class ProxyMethod : Method
  15789. {
  15790. public Method ProxyFor;
  15791. public ProxyMethod(TypeNode declaringType, AttributeList attributes, Identifier name, ParameterList parameters, TypeNode returnType, Block body)
  15792. : base(declaringType, attributes, name, parameters, returnType, body) { }
  15793. }
  15794. public class InstanceInitializer : Method
  15795. {
  15796. /// <summary>
  15797. /// True if this constructor calls a constructor declared in the same class, as opposed to the base class.
  15798. /// </summary>
  15799. public bool IsDeferringConstructor;
  15800. /// <summary>
  15801. /// When the source uses the C# compatibility mode, base calls cannot be put after non-null
  15802. /// field initialization, but must be put before the body. But the user can specify where
  15803. /// the base ctor call should be performed by using "base;" as a marker. During parsing
  15804. /// this flag is set so the right code transformations can be performed at code generation.
  15805. /// </summary>
  15806. public bool ContainsBaseMarkerBecauseOfNonNullFields;
  15807. public Block BaseOrDefferingCallBlock;
  15808. public bool IsCompilerGenerated = false;
  15809. public InstanceInitializer()
  15810. : base()
  15811. {
  15812. this.NodeType = NodeType.InstanceInitializer;
  15813. this.CallingConvention = CallingConventionFlags.HasThis;
  15814. this.Flags = MethodFlags.SpecialName | MethodFlags.RTSpecialName;
  15815. this.Name = StandardIds.Ctor;
  15816. this.ReturnType = CoreSystemTypes.Void;
  15817. }
  15818. public InstanceInitializer(MethodBodyProvider provider, object handle)
  15819. : base(provider, handle)
  15820. {
  15821. this.NodeType = NodeType.InstanceInitializer;
  15822. }
  15823. public InstanceInitializer(TypeNode declaringType, AttributeList attributes, ParameterList parameters, Block body)
  15824. : this(declaringType, attributes, parameters, body, CoreSystemTypes.Void)
  15825. {
  15826. }
  15827. public InstanceInitializer(TypeNode declaringType, AttributeList attributes, ParameterList parameters, Block body, TypeNode returnType)
  15828. : base(declaringType, attributes, StandardIds.Ctor, parameters, null, body)
  15829. {
  15830. this.NodeType = NodeType.InstanceInitializer;
  15831. this.CallingConvention = CallingConventionFlags.HasThis;
  15832. this.Flags = MethodFlags.SpecialName | MethodFlags.RTSpecialName;
  15833. this.Name = StandardIds.Ctor;
  15834. this.ReturnType = returnType;
  15835. }
  15836. protected System.Reflection.ConstructorInfo constructorInfo;
  15837. public virtual System.Reflection.ConstructorInfo GetConstructorInfo()
  15838. {
  15839. if(this.constructorInfo == null)
  15840. {
  15841. if(this.DeclaringType == null)
  15842. return null;
  15843. Type t = this.DeclaringType.GetRuntimeType();
  15844. if(t == null)
  15845. return null;
  15846. ParameterList pars = this.Parameters;
  15847. int n = pars == null ? 0 : pars.Count;
  15848. Type[] types = new Type[n];
  15849. for(int i = 0; i < n; i++)
  15850. {
  15851. Parameter p = pars[i];
  15852. if(p == null || p.Type == null)
  15853. return null;
  15854. Type pt = types[i] = p.Type.GetRuntimeType();
  15855. if(pt == null)
  15856. return null;
  15857. }
  15858. System.Reflection.MemberInfo[] members = t.GetMember(this.Name.ToString(), System.Reflection.MemberTypes.Constructor,
  15859. BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
  15860. foreach(System.Reflection.ConstructorInfo cons in members)
  15861. {
  15862. if(cons == null)
  15863. continue;
  15864. System.Reflection.ParameterInfo[] parameters = cons.GetParameters();
  15865. if(parameters != null)
  15866. {
  15867. if(parameters.Length != n)
  15868. continue;
  15869. for(int i = 0; i < n; i++)
  15870. {
  15871. System.Reflection.ParameterInfo par = parameters[i];
  15872. if(par == null || par.ParameterType != types[i])
  15873. goto tryNext;
  15874. }
  15875. }
  15876. return this.constructorInfo = cons;
  15877. tryNext:
  15878. ;
  15879. }
  15880. }
  15881. return this.constructorInfo;
  15882. }
  15883. public override System.Reflection.MethodInfo GetMethodInfo()
  15884. {
  15885. return null;
  15886. }
  15887. public virtual object Invoke(params object[] arguments)
  15888. {
  15889. System.Reflection.ConstructorInfo constr = this.GetConstructorInfo();
  15890. if(constr == null)
  15891. return null;
  15892. return constr.Invoke(arguments);
  15893. }
  15894. public virtual Literal Invoke(params Literal[] arguments)
  15895. {
  15896. int n = arguments == null ? 0 : arguments.Length;
  15897. object[] args = n == 0 ? null : new object[n];
  15898. if(args != null && arguments != null)
  15899. for(int i = 0; i < n; i++)
  15900. {
  15901. Literal lit = arguments[i];
  15902. args[i] = lit == null ? null : lit.Value;
  15903. }
  15904. return new Literal(this.Invoke(args));
  15905. }
  15906. //initializers never override a base class initializer
  15907. public override bool OverridesBaseClassMember
  15908. {
  15909. get { return false; }
  15910. set { }
  15911. }
  15912. public override Member OverriddenMember
  15913. {
  15914. get { return null; }
  15915. set { }
  15916. }
  15917. public override Method OverriddenMethod
  15918. {
  15919. get { return null; }
  15920. set { }
  15921. }
  15922. public override string ToString()
  15923. {
  15924. return this.DeclaringType.GetFullUnmangledNameWithTypeParameters() + "(" + this.Parameters + ")";
  15925. }
  15926. public virtual MemberList GetAttributeConstructorNamedParameters()
  15927. {
  15928. TypeNode type = this.DeclaringType;
  15929. if(type == null || !type.IsAssignableTo(SystemTypes.Attribute) || type.Members == null)
  15930. return null;
  15931. MemberList memList = type.Members;
  15932. int n = memList.Count;
  15933. MemberList ml = new MemberList();
  15934. for(int i = 0; i < n; ++i)
  15935. {
  15936. Property p = memList[i] as Property;
  15937. if(p != null && p.IsPublic)
  15938. {
  15939. if(p.Setter != null && p.Getter != null)
  15940. ml.Add(p);
  15941. continue;
  15942. }
  15943. Field f = memList[i] as Field;
  15944. if(f != null && !f.IsInitOnly && f.IsPublic)
  15945. ml.Add(f);
  15946. }
  15947. return ml;
  15948. }
  15949. }
  15950. public class StaticInitializer : Method
  15951. {
  15952. public StaticInitializer()
  15953. : base()
  15954. {
  15955. this.NodeType = NodeType.StaticInitializer;
  15956. this.Flags = MethodFlags.SpecialName | MethodFlags.RTSpecialName | MethodFlags.Static | MethodFlags.HideBySig | MethodFlags.Private;
  15957. this.Name = StandardIds.CCtor;
  15958. this.ReturnType = CoreSystemTypes.Void;
  15959. }
  15960. public StaticInitializer(MethodBodyProvider provider, object handle)
  15961. : base(provider, handle)
  15962. {
  15963. this.NodeType = NodeType.StaticInitializer;
  15964. }
  15965. public StaticInitializer(TypeNode declaringType, AttributeList attributes, Block body)
  15966. : base(declaringType, attributes, StandardIds.CCtor, null, null, body)
  15967. {
  15968. this.NodeType = NodeType.StaticInitializer;
  15969. this.Flags = MethodFlags.SpecialName | MethodFlags.RTSpecialName | MethodFlags.Static | MethodFlags.HideBySig | MethodFlags.Private;
  15970. this.Name = StandardIds.CCtor;
  15971. this.ReturnType = CoreSystemTypes.Void;
  15972. }
  15973. public StaticInitializer(TypeNode declaringType, AttributeList attributes, Block body, TypeNode voidTypeExpression)
  15974. : base(declaringType, attributes, StandardIds.CCtor, null, null, body)
  15975. {
  15976. this.NodeType = NodeType.StaticInitializer;
  15977. this.Flags = MethodFlags.SpecialName | MethodFlags.RTSpecialName | MethodFlags.Static | MethodFlags.HideBySig | MethodFlags.Private;
  15978. this.Name = StandardIds.CCtor;
  15979. this.ReturnType = voidTypeExpression;
  15980. }
  15981. protected System.Reflection.ConstructorInfo constructorInfo;
  15982. public virtual System.Reflection.ConstructorInfo GetConstructorInfo()
  15983. {
  15984. if(this.constructorInfo == null)
  15985. {
  15986. if(this.DeclaringType == null)
  15987. return null;
  15988. Type t = this.DeclaringType.GetRuntimeType();
  15989. if(t == null)
  15990. return null;
  15991. ParameterList pars = this.Parameters;
  15992. int n = pars == null ? 0 : pars.Count;
  15993. Type[] types = new Type[n];
  15994. for(int i = 0; i < n; i++)
  15995. {
  15996. Parameter p = pars[i];
  15997. if(p == null || p.Type == null)
  15998. return null;
  15999. Type pt = types[i] = p.Type.GetRuntimeType();
  16000. if(pt == null)
  16001. return null;
  16002. }
  16003. System.Reflection.MemberInfo[] members = t.GetMember(this.Name.ToString(), System.Reflection.MemberTypes.Constructor,
  16004. BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
  16005. foreach(System.Reflection.ConstructorInfo cons in members)
  16006. {
  16007. if(cons == null)
  16008. continue;
  16009. System.Reflection.ParameterInfo[] parameters = cons.GetParameters();
  16010. int numPars = parameters == null ? 0 : parameters.Length;
  16011. if(numPars != n)
  16012. continue;
  16013. if(parameters != null)
  16014. for(int i = 0; i < n; i++)
  16015. {
  16016. System.Reflection.ParameterInfo par = parameters[i];
  16017. if(par == null || par.ParameterType != types[i])
  16018. goto tryNext;
  16019. }
  16020. return this.constructorInfo = cons;
  16021. tryNext:
  16022. ;
  16023. }
  16024. }
  16025. return this.constructorInfo;
  16026. }
  16027. public override System.Reflection.MethodInfo GetMethodInfo()
  16028. {
  16029. return null;
  16030. }
  16031. //initializers never override a base class initializer
  16032. public override bool OverridesBaseClassMember
  16033. {
  16034. get { return false; }
  16035. set { }
  16036. }
  16037. public override Member OverriddenMember
  16038. {
  16039. get { return null; }
  16040. set { }
  16041. }
  16042. public override Method OverriddenMethod
  16043. {
  16044. get { return null; }
  16045. set { }
  16046. }
  16047. }
  16048. public class FieldInitializerBlock : Block
  16049. {
  16050. public TypeNode Type;
  16051. public bool IsStatic;
  16052. public FieldInitializerBlock()
  16053. : base()
  16054. {
  16055. this.NodeType = NodeType.FieldInitializerBlock;
  16056. }
  16057. public FieldInitializerBlock(TypeNode type, bool isStatic)
  16058. : base()
  16059. {
  16060. this.NodeType = NodeType.FieldInitializerBlock;
  16061. this.Type = type;
  16062. this.IsStatic = isStatic;
  16063. }
  16064. }
  16065. public class ParameterField : Field
  16066. {
  16067. protected Parameter parameter;
  16068. public ParameterField()
  16069. {
  16070. }
  16071. public ParameterField(TypeNode declaringType, AttributeList attributes, FieldFlags flags, Identifier name,
  16072. TypeNode Type, Literal defaultValue)
  16073. : base(declaringType, attributes, flags, name, Type, defaultValue)
  16074. {
  16075. }
  16076. public virtual Parameter Parameter
  16077. {
  16078. get
  16079. {
  16080. return this.parameter;
  16081. }
  16082. set
  16083. {
  16084. this.parameter = value;
  16085. }
  16086. }
  16087. }
  16088. public class Field : Member
  16089. {
  16090. /// <summary>Provides a value that is assigned to the field upon initialization.</summary>
  16091. public Expression Initializer;
  16092. public TypeNode TypeExpression;
  16093. public bool HasOutOfBandContract;
  16094. public InterfaceList ImplementedInterfaces;
  16095. public InterfaceList ImplementedInterfaceExpressions;
  16096. // if this is the backing field for some event, then ForEvent is that event
  16097. public Event ForEvent;
  16098. public bool IsModelfield = false; //set to true if this field serves as the representation of a modelfield in a class
  16099. public Field()
  16100. : base(NodeType.Field)
  16101. {
  16102. }
  16103. public Field(Identifier name)
  16104. : base(NodeType.Field)
  16105. {
  16106. this.Name = name;
  16107. }
  16108. public Field(TypeNode declaringType, AttributeList attributes, FieldFlags flags, Identifier name,
  16109. TypeNode type, Literal defaultValue)
  16110. : base(declaringType, attributes, name, NodeType.Field)
  16111. {
  16112. this.defaultValue = defaultValue;
  16113. this.flags = flags;
  16114. this.type = type;
  16115. }
  16116. private Literal defaultValue;
  16117. /// <summary>The compile-time value to be substituted for references to this field if it is a literal.</summary>
  16118. public Literal DefaultValue
  16119. { //TODO: rename this to LiteralValue
  16120. get { return this.defaultValue; }
  16121. set { this.defaultValue = value; }
  16122. }
  16123. private FieldFlags flags;
  16124. public FieldFlags Flags
  16125. {
  16126. get { return this.flags; }
  16127. set { this.flags = value; }
  16128. }
  16129. private int offset;
  16130. public int Offset
  16131. {
  16132. get { return this.offset; }
  16133. set { this.offset = value; }
  16134. }
  16135. private bool isVolatile;
  16136. /// <summary>True if the field may not be cached. Used for sharing data between multiple threads.</summary>
  16137. public bool IsVolatile
  16138. {
  16139. get { return this.isVolatile; }
  16140. set { this.isVolatile = value; }
  16141. }
  16142. private TypeNode type;
  16143. /// <summary>The type of values that may be stored in the field.</summary>
  16144. public TypeNode Type
  16145. {
  16146. get { return this.type; }
  16147. set { this.type = value; }
  16148. }
  16149. private MarshallingInformation marshallingInformation;
  16150. public MarshallingInformation MarshallingInformation
  16151. {
  16152. get { return this.marshallingInformation; }
  16153. set { this.marshallingInformation = value; }
  16154. }
  16155. private byte[] initialData;
  16156. public byte[] InitialData
  16157. {
  16158. get { return this.initialData; }
  16159. set { this.initialData = value; }
  16160. }
  16161. internal PESection section;
  16162. public PESection Section
  16163. {
  16164. get { return this.section; }
  16165. set { this.section = value; }
  16166. }
  16167. protected string fullName;
  16168. public override string/*!*/ FullName
  16169. {
  16170. get
  16171. {
  16172. string result = this.fullName;
  16173. if(result == null)
  16174. this.fullName = result = this.DeclaringType.FullName + "." + (this.Name == null ? "" : this.Name.ToString());
  16175. return result;
  16176. }
  16177. }
  16178. protected override Identifier GetDocumentationId()
  16179. {
  16180. StringBuilder sb = new StringBuilder();
  16181. sb.Append("F:");
  16182. if(this.DeclaringType == null)
  16183. return Identifier.Empty;
  16184. sb.Append(this.DeclaringType.FullName);
  16185. sb.Append(".");
  16186. if(this.Name == null)
  16187. return Identifier.Empty;
  16188. sb.Append(this.Name.Name);
  16189. return Identifier.For(sb.ToString());
  16190. }
  16191. public static Field GetField(System.Reflection.FieldInfo fieldInfo)
  16192. {
  16193. if(fieldInfo == null)
  16194. return null;
  16195. TypeNode tn = TypeNode.GetTypeNode(fieldInfo.DeclaringType);
  16196. if(tn == null)
  16197. return null;
  16198. return tn.GetField(Identifier.For(fieldInfo.Name));
  16199. }
  16200. protected System.Reflection.FieldInfo fieldInfo;
  16201. public virtual System.Reflection.FieldInfo GetFieldInfo()
  16202. {
  16203. if(this.fieldInfo == null)
  16204. {
  16205. TypeNode tn = this.DeclaringType;
  16206. if(tn == null)
  16207. return null;
  16208. Type t = tn.GetRuntimeType();
  16209. if(t == null)
  16210. return null;
  16211. System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.DeclaredOnly;
  16212. if(this.IsPublic)
  16213. flags |= System.Reflection.BindingFlags.Public;
  16214. else
  16215. flags |= System.Reflection.BindingFlags.NonPublic;
  16216. if(this.IsStatic)
  16217. flags |= System.Reflection.BindingFlags.Static;
  16218. else
  16219. flags |= System.Reflection.BindingFlags.Instance;
  16220. this.fieldInfo = t.GetField(this.Name.ToString(), flags);
  16221. }
  16222. return this.fieldInfo;
  16223. }
  16224. /// <summary>True if all references to the field are replaced with a value that is determined at compile-time.</summary>
  16225. public virtual bool IsLiteral
  16226. {
  16227. get { return (this.Flags & FieldFlags.Literal) != 0; }
  16228. }
  16229. public override bool IsAssembly
  16230. {
  16231. get { return (this.Flags & FieldFlags.FieldAccessMask) == FieldFlags.Assembly; }
  16232. }
  16233. public override bool IsCompilerControlled
  16234. {
  16235. get { return (this.Flags & FieldFlags.FieldAccessMask) == FieldFlags.CompilerControlled; }
  16236. }
  16237. public override bool IsFamily
  16238. {
  16239. get { return (this.Flags & FieldFlags.FieldAccessMask) == FieldFlags.Family; }
  16240. }
  16241. public override bool IsFamilyAndAssembly
  16242. {
  16243. get { return (this.Flags & FieldFlags.FieldAccessMask) == FieldFlags.FamANDAssem; }
  16244. }
  16245. public override bool IsFamilyOrAssembly
  16246. {
  16247. get { return (this.Flags & FieldFlags.FieldAccessMask) == FieldFlags.FamORAssem; }
  16248. }
  16249. /// <summary>True if the field may only be assigned to inside the constructor.</summary>
  16250. public virtual bool IsInitOnly
  16251. {
  16252. get { return (this.Flags & FieldFlags.InitOnly) != 0; }
  16253. }
  16254. public override bool IsPrivate
  16255. {
  16256. get { return (this.Flags & FieldFlags.FieldAccessMask) == FieldFlags.Private; }
  16257. }
  16258. public override bool IsPublic
  16259. {
  16260. get { return (this.Flags & FieldFlags.FieldAccessMask) == FieldFlags.Public; }
  16261. }
  16262. public override bool IsSpecialName
  16263. {
  16264. get { return (this.Flags & FieldFlags.SpecialName) != 0; }
  16265. }
  16266. public override bool IsStatic
  16267. {
  16268. get { return (this.Flags & FieldFlags.Static) != 0; }
  16269. }
  16270. public override bool IsVisibleOutsideAssembly
  16271. {
  16272. get
  16273. {
  16274. if(this.DeclaringType != null && !this.DeclaringType.IsVisibleOutsideAssembly)
  16275. return false;
  16276. switch(this.Flags & FieldFlags.FieldAccessMask)
  16277. {
  16278. case FieldFlags.Public:
  16279. return true;
  16280. case FieldFlags.Family:
  16281. case FieldFlags.FamORAssem:
  16282. return this.DeclaringType != null && !this.DeclaringType.IsSealed;
  16283. default:
  16284. return false;
  16285. }
  16286. }
  16287. }
  16288. public virtual object GetValue(object targetObject)
  16289. {
  16290. System.Reflection.FieldInfo fieldInfo = this.GetFieldInfo();
  16291. if(fieldInfo == null)
  16292. return null;
  16293. return fieldInfo.GetValue(targetObject);
  16294. }
  16295. public virtual Literal GetValue(Literal/*!*/ targetObject)
  16296. {
  16297. return new Literal(this.GetValue(targetObject.Value));
  16298. }
  16299. public virtual void SetValue(object targetObject, object value)
  16300. {
  16301. System.Reflection.FieldInfo fieldInfo = this.GetFieldInfo();
  16302. if(fieldInfo == null)
  16303. return;
  16304. fieldInfo.SetValue(targetObject, value);
  16305. }
  16306. public virtual void SetValue(Literal/*!*/ targetObject, Literal/*!*/ value)
  16307. {
  16308. this.SetValue(targetObject.Value, value.Value);
  16309. }
  16310. public override string ToString()
  16311. {
  16312. return this.DeclaringType.GetFullUnmangledNameWithTypeParameters() + "." + this.Name;
  16313. }
  16314. }
  16315. public class Property : Member
  16316. {
  16317. /// <summary>
  16318. /// The list of types (just one in C#) that contain abstract or virtual properties that are explicitly implemented or overridden by this property.
  16319. /// </summary>
  16320. public TypeNodeList ImplementedTypes;
  16321. public TypeNodeList ImplementedTypeExpressions;
  16322. public bool IsModelfield = false; //set to true if this property serves as the representation of a modelfield in an interface
  16323. public Property() : base(NodeType.Property)
  16324. {
  16325. }
  16326. public Property(TypeNode declaringType, AttributeList attributes, PropertyFlags flags, Identifier name,
  16327. Method getter, Method setter)
  16328. : base(declaringType, attributes, name, NodeType.Property)
  16329. {
  16330. this.flags = flags;
  16331. this.getter = getter;
  16332. this.setter = setter;
  16333. if(getter != null)
  16334. getter.DeclaringMember = this;
  16335. if(setter != null)
  16336. setter.DeclaringMember = this;
  16337. }
  16338. private PropertyFlags flags;
  16339. public PropertyFlags Flags
  16340. {
  16341. get { return this.flags; }
  16342. set { this.flags = value; }
  16343. }
  16344. private Method getter;
  16345. /// <summary>The method that is called to get the value of this property. Corresponds to the get clause in C#.</summary>
  16346. public Method Getter
  16347. {
  16348. get { return this.getter; }
  16349. set { this.getter = value; }
  16350. }
  16351. private Method setter;
  16352. /// <summary>The method that is called to set the value of this property. Corresponds to the set clause in C#.</summary>
  16353. public Method Setter
  16354. {
  16355. get { return this.setter; }
  16356. set { this.setter = value; }
  16357. }
  16358. private MethodList otherMethods;
  16359. /// <summary>Other methods associated with the property. No equivalent in C#.</summary>
  16360. public MethodList OtherMethods
  16361. {
  16362. get { return this.otherMethods; }
  16363. set { this.otherMethods = value; }
  16364. }
  16365. protected string fullName;
  16366. public override string/*!*/ FullName
  16367. {
  16368. get
  16369. {
  16370. if(this.fullName != null)
  16371. return this.fullName;
  16372. StringBuilder sb = new StringBuilder();
  16373. sb.Append(this.DeclaringType.FullName);
  16374. sb.Append('.');
  16375. if(this.Name != null)
  16376. sb.Append(this.Name.ToString());
  16377. ParameterList parameters = this.Parameters;
  16378. for(int i = 0, n = parameters == null ? 0 : parameters.Count; i < n; i++)
  16379. {
  16380. Parameter par = parameters[i];
  16381. if(par == null || par.Type == null)
  16382. continue;
  16383. if(i == 0)
  16384. sb.Append('(');
  16385. else
  16386. sb.Append(',');
  16387. sb.Append(par.Type.FullName);
  16388. if(i == n - 1)
  16389. sb.Append(')');
  16390. }
  16391. return this.fullName = sb.ToString();
  16392. }
  16393. }
  16394. public virtual Method GetBaseGetter()
  16395. {
  16396. TypeNode t = this.DeclaringType;
  16397. if(t == null)
  16398. return null;
  16399. while(t.BaseType != null)
  16400. {
  16401. t = t.BaseType;
  16402. MemberList mems = t.GetMembersNamed(this.Name);
  16403. for(int i = 0, n = mems == null ? 0 : mems.Count; i < n; i++)
  16404. {
  16405. Property bprop = mems[i] as Property;
  16406. if(bprop == null)
  16407. continue;
  16408. if(!bprop.ParametersMatch(this.Parameters))
  16409. continue;
  16410. if(bprop.Getter != null)
  16411. return bprop.Getter;
  16412. }
  16413. }
  16414. return null;
  16415. }
  16416. public virtual Method GetBaseSetter()
  16417. {
  16418. TypeNode t = this.DeclaringType;
  16419. if(t == null)
  16420. return null;
  16421. while(t.BaseType != null)
  16422. {
  16423. t = t.BaseType;
  16424. MemberList mems = t.GetMembersNamed(this.Name);
  16425. for(int i = 0, n = mems == null ? 0 : mems.Count; i < n; i++)
  16426. {
  16427. Property bprop = mems[i] as Property;
  16428. if(bprop == null)
  16429. continue;
  16430. if(!bprop.ParametersMatch(this.Parameters))
  16431. continue;
  16432. if(bprop.Setter != null)
  16433. return bprop.Setter;
  16434. }
  16435. }
  16436. return null;
  16437. }
  16438. protected override Identifier GetDocumentationId()
  16439. {
  16440. StringBuilder sb = new StringBuilder(this.DeclaringType.DocumentationId.ToString());
  16441. sb[0] = 'P';
  16442. sb.Append('.');
  16443. if(this.Name != null)
  16444. sb.Append(this.Name.ToString());
  16445. ParameterList parameters = this.Parameters;
  16446. for(int i = 0, n = parameters == null ? 0 : parameters.Count; i < n; i++)
  16447. {
  16448. Parameter par = parameters[i];
  16449. if(par == null || par.Type == null)
  16450. continue;
  16451. if(i == 0)
  16452. sb.Append('(');
  16453. else
  16454. sb.Append(',');
  16455. par.Type.AppendDocumentIdMangledName(sb, null, this.DeclaringType.TemplateParameters);
  16456. if(i == n - 1)
  16457. sb.Append(')');
  16458. }
  16459. return Identifier.For(sb.ToString());
  16460. }
  16461. public static Property GetProperty(System.Reflection.PropertyInfo propertyInfo)
  16462. {
  16463. if(propertyInfo == null)
  16464. return null;
  16465. TypeNode tn = TypeNode.GetTypeNode(propertyInfo.DeclaringType);
  16466. if(tn == null)
  16467. return null;
  16468. System.Reflection.ParameterInfo[] paramInfos = propertyInfo.GetIndexParameters();
  16469. int n = paramInfos == null ? 0 : paramInfos.Length;
  16470. TypeNode[] parameterTypes = new TypeNode[n];
  16471. if(paramInfos != null)
  16472. for(int i = 0; i < n; i++)
  16473. {
  16474. System.Reflection.ParameterInfo param = paramInfos[i];
  16475. if(param == null)
  16476. return null;
  16477. parameterTypes[i] = TypeNode.GetTypeNode(param.ParameterType);
  16478. }
  16479. return tn.GetProperty(Identifier.For(propertyInfo.Name), parameterTypes);
  16480. }
  16481. protected System.Reflection.PropertyInfo propertyInfo;
  16482. public virtual System.Reflection.PropertyInfo GetPropertyInfo()
  16483. {
  16484. if(this.propertyInfo == null)
  16485. {
  16486. if(this.DeclaringType == null)
  16487. return null;
  16488. Type t = this.DeclaringType.GetRuntimeType();
  16489. if(t == null)
  16490. return null;
  16491. if(this.Type == null)
  16492. return null;
  16493. Type retType = this.Type.GetRuntimeType();
  16494. if(retType == null)
  16495. return null;
  16496. ParameterList pars = this.Parameters;
  16497. int n = pars == null ? 0 : pars.Count;
  16498. Type[] types = new Type[n];
  16499. for(int i = 0; i < n; i++)
  16500. {
  16501. Parameter p = pars[i];
  16502. if(p == null || p.Type == null)
  16503. return null;
  16504. Type pt = types[i] = p.Type.GetRuntimeType();
  16505. if(pt == null)
  16506. return null;
  16507. }
  16508. System.Reflection.MemberInfo[] members =
  16509. t.GetMember(this.Name.ToString(), System.Reflection.MemberTypes.Property,
  16510. BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
  16511. foreach(System.Reflection.PropertyInfo prop in members)
  16512. {
  16513. if(prop == null || prop.PropertyType != retType)
  16514. continue;
  16515. System.Reflection.ParameterInfo[] parameters = prop.GetIndexParameters();
  16516. if(parameters == null || parameters.Length != n)
  16517. continue;
  16518. for(int i = 0; i < n; i++)
  16519. {
  16520. System.Reflection.ParameterInfo parInfo = parameters[i];
  16521. if(parInfo == null || parInfo.ParameterType != types[i])
  16522. goto tryNext;
  16523. }
  16524. return this.propertyInfo = prop;
  16525. tryNext:
  16526. ;
  16527. }
  16528. }
  16529. return this.propertyInfo;
  16530. }
  16531. public virtual object GetValue(object targetObject, params object[] indices)
  16532. {
  16533. System.Reflection.PropertyInfo propInfo = this.GetPropertyInfo();
  16534. if(propInfo == null)
  16535. throw new InvalidOperationException();
  16536. return propInfo.GetValue(targetObject, indices);
  16537. }
  16538. public virtual Literal GetValue(Literal/*!*/ targetObject, params Literal[] indices)
  16539. {
  16540. int n = indices == null ? 0 : indices.Length;
  16541. object[] inds = n == 0 ? null : new object[n];
  16542. if(inds != null && indices != null)
  16543. for(int i = 0; i < n; i++)
  16544. {
  16545. Literal lit = indices[i];
  16546. inds[i] = lit == null ? null : lit.Value;
  16547. }
  16548. return new Literal(this.GetValue(targetObject.Value, inds));
  16549. }
  16550. public virtual void SetValue(object targetObject, object value, params object[] indices)
  16551. {
  16552. System.Reflection.PropertyInfo propInfo = this.GetPropertyInfo();
  16553. if(propInfo == null)
  16554. throw new InvalidOperationException();
  16555. propInfo.SetValue(targetObject, value, indices);
  16556. }
  16557. public virtual void SetValue(Literal/*!*/ targetObject, Literal/*!*/ value, params Literal[] indices)
  16558. {
  16559. int n = indices == null ? 0 : indices.Length;
  16560. object[] inds = n == 0 ? null : new object[n];
  16561. if(inds != null && indices != null)
  16562. for(int i = 0; i < n; i++)
  16563. {
  16564. Literal lit = indices[i];
  16565. inds[i] = lit == null ? null : lit.Value;
  16566. }
  16567. System.Reflection.PropertyInfo propInfo = this.GetPropertyInfo();
  16568. if(propInfo == null)
  16569. throw new InvalidOperationException();
  16570. propInfo.SetValue(targetObject.Value, value.Value, inds);
  16571. }
  16572. public override string HelpText
  16573. {
  16574. get
  16575. {
  16576. if(this.helpText != null)
  16577. return this.helpText;
  16578. StringBuilder sb = new StringBuilder(base.HelpText);
  16579. // if there is already some help text, start the contract on a new line
  16580. bool startWithNewLine = (sb.Length != 0);
  16581. if(this.Getter != null && this.Getter.HelpText != null && this.Getter.HelpText.Length > 0)
  16582. {
  16583. if(startWithNewLine)
  16584. {
  16585. sb.Append("\n");
  16586. startWithNewLine = false;
  16587. }
  16588. sb.Append("get\n");
  16589. int i = sb.Length;
  16590. sb.Append(this.Getter.HelpText);
  16591. if(sb.Length > i)
  16592. startWithNewLine = true;
  16593. }
  16594. if(this.Setter != null && this.Setter.HelpText != null && this.Setter.HelpText.Length > 0)
  16595. {
  16596. if(startWithNewLine)
  16597. {
  16598. sb.Append("\n");
  16599. startWithNewLine = false;
  16600. }
  16601. sb.Append("set\n");
  16602. sb.Append(this.Setter.HelpText);
  16603. }
  16604. return this.helpText = sb.ToString();
  16605. }
  16606. set
  16607. {
  16608. base.HelpText = value;
  16609. }
  16610. }
  16611. public override bool IsAssembly
  16612. {
  16613. get { return Method.GetVisibilityUnion(this.Getter, this.Setter) == MethodFlags.Assembly; }
  16614. }
  16615. public override bool IsCompilerControlled
  16616. {
  16617. get { return Method.GetVisibilityUnion(this.Getter, this.Setter) == MethodFlags.CompilerControlled; }
  16618. }
  16619. public override bool IsFamily
  16620. {
  16621. get { return Method.GetVisibilityUnion(this.Getter, this.Setter) == MethodFlags.Family; }
  16622. }
  16623. public override bool IsFamilyAndAssembly
  16624. {
  16625. get { return Method.GetVisibilityUnion(this.Getter, this.Setter) == MethodFlags.FamANDAssem; }
  16626. }
  16627. public override bool IsFamilyOrAssembly
  16628. {
  16629. get { return Method.GetVisibilityUnion(this.Getter, this.Setter) == MethodFlags.FamORAssem; }
  16630. }
  16631. public bool IsFinal
  16632. {
  16633. get { return (this.Getter == null || this.Getter.IsFinal) && (this.Setter == null || this.Setter.IsFinal); }
  16634. }
  16635. public override bool IsPrivate
  16636. {
  16637. get { return Method.GetVisibilityUnion(this.Getter, this.Setter) == MethodFlags.Private; }
  16638. }
  16639. public override bool IsPublic
  16640. {
  16641. get { return Method.GetVisibilityUnion(this.Getter, this.Setter) == MethodFlags.Public; }
  16642. }
  16643. public override bool IsSpecialName
  16644. {
  16645. get { return (this.Flags & PropertyFlags.SpecialName) != 0; }
  16646. }
  16647. public override bool IsStatic
  16648. {
  16649. get { return (this.Getter == null || this.Getter.IsStatic) && (this.Setter == null || this.Setter.IsStatic); }
  16650. }
  16651. /// <summary>
  16652. /// True if this property can in principle be overridden by a property in a derived class.
  16653. /// </summary>
  16654. public bool IsVirtual
  16655. {
  16656. get { return (this.Getter == null || this.Getter.IsVirtual) && (this.Setter == null || this.Setter.IsVirtual); }
  16657. }
  16658. public override bool IsVisibleOutsideAssembly
  16659. {
  16660. get { return (this.Getter != null && this.Getter.IsVisibleOutsideAssembly) || (this.Setter != null && this.Setter.IsVisibleOutsideAssembly); }
  16661. }
  16662. public static readonly Property NotSpecified = new Property();
  16663. public override Member HiddenMember
  16664. {
  16665. get
  16666. {
  16667. return this.HiddenProperty;
  16668. }
  16669. set
  16670. {
  16671. this.HiddenProperty = (Property)value;
  16672. }
  16673. }
  16674. protected Property hiddenProperty;
  16675. public virtual Property HiddenProperty
  16676. {
  16677. get
  16678. {
  16679. if(this.hiddenMember == Property.NotSpecified)
  16680. return null;
  16681. Property hiddenProperty = this.hiddenMember as Property;
  16682. if(hiddenProperty != null)
  16683. return hiddenProperty;
  16684. Method hiddenGetter = this.Getter == null ? null : this.Getter.HiddenMethod;
  16685. Method hiddenSetter = this.Setter == null ? null : this.Setter.HiddenMethod;
  16686. Property hiddenGetterProperty = hiddenGetter == null ? null : hiddenGetter.DeclaringMember as Property;
  16687. Property hiddenSetterProperty = hiddenSetter == null ? null : hiddenSetter.DeclaringMember as Property;
  16688. hiddenProperty = hiddenGetterProperty;
  16689. if(hiddenSetterProperty != null)
  16690. {
  16691. if(hiddenProperty == null ||
  16692. (hiddenSetterProperty.DeclaringType != null && hiddenSetterProperty.DeclaringType.IsDerivedFrom(hiddenProperty.DeclaringType)))
  16693. hiddenProperty = hiddenSetterProperty;
  16694. }
  16695. this.hiddenMember = hiddenProperty;
  16696. return hiddenProperty;
  16697. }
  16698. set
  16699. {
  16700. this.hiddenMember = value;
  16701. }
  16702. }
  16703. public override Member OverriddenMember
  16704. {
  16705. get
  16706. {
  16707. return this.OverriddenProperty;
  16708. }
  16709. set
  16710. {
  16711. this.OverriddenProperty = (Property)value;
  16712. }
  16713. }
  16714. protected Property overriddenProperty;
  16715. public virtual Property OverriddenProperty
  16716. {
  16717. get
  16718. {
  16719. if(this.overriddenMember == Property.NotSpecified)
  16720. return null;
  16721. Property overriddenProperty = this.overriddenMember as Property;
  16722. if(overriddenProperty != null)
  16723. return overriddenProperty;
  16724. Method overriddenGetter = this.Getter == null ? null : this.Getter.OverriddenMethod;
  16725. Method overriddenSetter = this.Setter == null ? null : this.Setter.OverriddenMethod;
  16726. Property overriddenGetterProperty = overriddenGetter == null ? null : overriddenGetter.DeclaringMember as Property;
  16727. Property overriddenSetterProperty = overriddenSetter == null ? null : overriddenSetter.DeclaringMember as Property;
  16728. overriddenProperty = overriddenGetterProperty;
  16729. if(overriddenSetterProperty != null)
  16730. {
  16731. if(overriddenProperty == null ||
  16732. (overriddenSetterProperty.DeclaringType != null && overriddenSetterProperty.DeclaringType.IsDerivedFrom(overriddenProperty.DeclaringType)))
  16733. overriddenProperty = overriddenSetterProperty;
  16734. }
  16735. this.overriddenMember = overriddenProperty;
  16736. return overriddenProperty;
  16737. }
  16738. set
  16739. {
  16740. this.overriddenMember = value;
  16741. }
  16742. }
  16743. private ParameterList parameters;
  16744. /// <summary>
  16745. /// The parameters of this property if it is an indexer.
  16746. /// </summary>
  16747. public ParameterList Parameters
  16748. {
  16749. get
  16750. {
  16751. if(this.parameters != null)
  16752. return this.parameters;
  16753. if(this.Getter != null)
  16754. return this.parameters = this.Getter.Parameters;
  16755. ParameterList setterPars = this.Setter == null ? null : this.Setter.Parameters;
  16756. int n = setterPars == null ? 0 : setterPars.Count - 1;
  16757. ParameterList propPars = this.parameters = new ParameterList();
  16758. if(setterPars != null)
  16759. for(int i = 0; i < n; i++)
  16760. propPars.Add(setterPars[i]);
  16761. return propPars;
  16762. }
  16763. set
  16764. {
  16765. this.parameters = value;
  16766. }
  16767. }
  16768. public virtual bool ParametersMatch(ParameterList parameters)
  16769. {
  16770. ParameterList pars = this.Parameters;
  16771. int n = pars == null ? 0 : pars.Count;
  16772. int m = parameters == null ? 0 : parameters.Count;
  16773. if(n != m)
  16774. return false;
  16775. if(parameters == null)
  16776. return true;
  16777. for(int i = 0; i < n; i++)
  16778. {
  16779. Parameter par1 = pars[i];
  16780. Parameter par2 = parameters[i];
  16781. if(par1.Type != par2.Type)
  16782. return false;
  16783. }
  16784. return true;
  16785. }
  16786. public virtual bool ParametersMatchStructurally(ParameterList parameters)
  16787. {
  16788. ParameterList pars = this.Parameters;
  16789. int n = pars == null ? 0 : pars.Count;
  16790. int m = parameters == null ? 0 : parameters.Count;
  16791. if(n != m)
  16792. return false;
  16793. if(parameters == null)
  16794. return true;
  16795. for(int i = 0; i < n; i++)
  16796. {
  16797. Parameter par1 = pars[i];
  16798. Parameter par2 = parameters[i];
  16799. if(par1 == null || par2 == null)
  16800. return false;
  16801. if(par1.Type == null || par2.Type == null)
  16802. return false;
  16803. if(par1.Type != par2.Type && !par1.Type.IsStructurallyEquivalentTo(par2.Type))
  16804. return false;
  16805. }
  16806. return true;
  16807. }
  16808. public virtual bool ParameterTypesMatch(TypeNodeList argumentTypes)
  16809. {
  16810. ParameterList pars = this.Parameters;
  16811. int n = pars == null ? 0 : pars.Count;
  16812. int m = argumentTypes == null ? 0 : argumentTypes.Count;
  16813. if(n != m)
  16814. return false;
  16815. if(argumentTypes == null)
  16816. return true;
  16817. for(int i = 0; i < n; i++)
  16818. {
  16819. Parameter par = this.Parameters[i];
  16820. if(par == null)
  16821. return false;
  16822. TypeNode argType = argumentTypes[i];
  16823. if(par.Type != argType)
  16824. return false;
  16825. }
  16826. return true;
  16827. }
  16828. protected TypeNode type;
  16829. /// <summary>
  16830. /// The type of value that this property holds.
  16831. /// </summary>
  16832. public virtual TypeNode Type
  16833. {
  16834. get
  16835. {
  16836. if(this.type != null)
  16837. return this.type;
  16838. if(this.Getter != null)
  16839. return this.type = this.Getter.ReturnType;
  16840. if(this.Setter != null && this.Setter.Parameters != null)
  16841. return this.type = this.Setter.Parameters[this.Setter.Parameters.Count - 1].Type;
  16842. return CoreSystemTypes.Object;
  16843. }
  16844. set
  16845. {
  16846. this.type = value;
  16847. }
  16848. }
  16849. public TypeNode TypeExpression;
  16850. public override string ToString()
  16851. {
  16852. return this.DeclaringType.GetFullUnmangledNameWithTypeParameters() + "." + this.Name;
  16853. }
  16854. }
  16855. public class Variable : Expression
  16856. {
  16857. private Identifier name;
  16858. public TypeNode TypeExpression;
  16859. public Variable(NodeType type)
  16860. : base(type)
  16861. {
  16862. }
  16863. /// <summary>The name of a stack location. For example the name of a local variable or the name of a method parameter.</summary>
  16864. public Identifier Name
  16865. {
  16866. get { return this.name; }
  16867. set { this.name = value; }
  16868. }
  16869. }
  16870. public class Parameter : Variable
  16871. {
  16872. private AttributeList attributes;
  16873. /// <summary>The (C# custom) attributes of this parameter.</summary>
  16874. public AttributeList Attributes
  16875. {
  16876. get
  16877. {
  16878. if(this.attributes != null)
  16879. return this.attributes;
  16880. return this.attributes = new AttributeList();
  16881. }
  16882. set { this.attributes = value; }
  16883. }
  16884. private Expression defaultValue;
  16885. /// <summary>The value that should be supplied as the argument value of this optional parameter if the source code omits an explicit argument value.</summary>
  16886. public Expression DefaultValue
  16887. {
  16888. get { return this.defaultValue; }
  16889. set { this.defaultValue = value; }
  16890. }
  16891. private ParameterFlags flags;
  16892. public ParameterFlags Flags
  16893. {
  16894. get { return this.flags; }
  16895. set { this.flags = value; }
  16896. }
  16897. private MarshallingInformation marshallingInformation;
  16898. public MarshallingInformation MarshallingInformation
  16899. {
  16900. get { return this.marshallingInformation; }
  16901. set { this.marshallingInformation = value; }
  16902. }
  16903. private Method declaringMethod;
  16904. public Method DeclaringMethod
  16905. {
  16906. get { return this.declaringMethod; }
  16907. set { this.declaringMethod = value; }
  16908. }
  16909. private int parameterListIndex;
  16910. /// <summary>
  16911. /// Zero based index into a parameter list containing this parameter.
  16912. /// </summary>
  16913. public int ParameterListIndex
  16914. {
  16915. get { return this.parameterListIndex; }
  16916. set { this.parameterListIndex = value; }
  16917. }
  16918. private int argumentListIndex;
  16919. /// <summary>
  16920. /// Zero based index into the list of arguments on the evaluation stack.
  16921. /// Instance methods have the this object as parameter zero, which means that the first parameter will have value 1, not 0.
  16922. /// </summary>
  16923. public int ArgumentListIndex
  16924. {
  16925. get { return this.argumentListIndex; }
  16926. set { this.argumentListIndex = value; }
  16927. }
  16928. public Parameter()
  16929. : base(NodeType.Parameter)
  16930. {
  16931. }
  16932. public Parameter(Identifier name, TypeNode type)
  16933. : base(NodeType.Parameter)
  16934. {
  16935. this.Name = name;
  16936. this.Type = type;
  16937. }
  16938. public Parameter(AttributeList attributes, ParameterFlags flags, Identifier name, TypeNode type,
  16939. Literal defaultValue, MarshallingInformation marshallingInformation)
  16940. : base(NodeType.Parameter)
  16941. {
  16942. this.attributes = attributes;
  16943. this.defaultValue = defaultValue;
  16944. this.flags = flags;
  16945. this.marshallingInformation = marshallingInformation;
  16946. this.Name = name;
  16947. this.Type = type;
  16948. }
  16949. /// <summary>
  16950. /// True if the corresponding argument value is used by the callee. (This need not be the case for a parameter marked as IsOut.)
  16951. /// </summary>
  16952. public virtual bool IsIn
  16953. {
  16954. get
  16955. {
  16956. return (this.Flags & ParameterFlags.In) != 0;
  16957. }
  16958. set
  16959. {
  16960. if(value)
  16961. this.Flags |= ParameterFlags.In;
  16962. else
  16963. this.Flags &= ~ParameterFlags.In;
  16964. }
  16965. }
  16966. /// <summary>
  16967. /// True if the caller can omit providing an argument for this parameter.
  16968. /// </summary>
  16969. public virtual bool IsOptional
  16970. {
  16971. get
  16972. {
  16973. return (this.Flags & ParameterFlags.Optional) != 0;
  16974. }
  16975. set
  16976. {
  16977. if(value)
  16978. this.Flags |= ParameterFlags.Optional;
  16979. else
  16980. this.Flags &= ~ParameterFlags.Optional;
  16981. }
  16982. }
  16983. /// <summary>
  16984. /// True if the corresponding argument must be a left hand expression and will be updated when the call returns.
  16985. /// </summary>
  16986. public virtual bool IsOut
  16987. {
  16988. get
  16989. {
  16990. return (this.Flags & ParameterFlags.Out) != 0;
  16991. }
  16992. set
  16993. {
  16994. if(value)
  16995. this.Flags |= ParameterFlags.Out;
  16996. else
  16997. this.Flags &= ~ParameterFlags.Out;
  16998. }
  16999. }
  17000. protected TypeNode paramArrayElementType = null;
  17001. /// <summary>
  17002. /// If the parameter is a param array, this returns the element type of the array. If not, it returns null.
  17003. /// </summary>
  17004. public virtual TypeNode GetParamArrayElementType()
  17005. {
  17006. TypeNode result = this.paramArrayElementType;
  17007. if(result == null)
  17008. {
  17009. AttributeNode attr = this.GetParamArrayAttribute();
  17010. if(attr != null)
  17011. {
  17012. TypeNode t = TypeNode.StripModifiers(this.Type);
  17013. Reference r = t as Reference;
  17014. if(r != null)
  17015. t = r.ElementType;
  17016. ArrayType arr = t as ArrayType;
  17017. if(arr != null && arr.Rank == 1)
  17018. return this.paramArrayElementType = arr.ElementType;
  17019. }
  17020. this.paramArrayElementType = result = Class.DoesNotExist;
  17021. }
  17022. if(result == Class.DoesNotExist)
  17023. return null;
  17024. return result;
  17025. }
  17026. protected AttributeNode paramArrayAttribute = null;
  17027. public virtual AttributeNode GetParamArrayAttribute()
  17028. {
  17029. AttributeNode result = this.paramArrayAttribute;
  17030. if(result == null)
  17031. {
  17032. AttributeList attributes = this.Attributes;
  17033. for(int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
  17034. {
  17035. AttributeNode attr = attributes[i];
  17036. if(attr == null)
  17037. continue;
  17038. TypeNode attrType = null;
  17039. MemberBinding mb = attr.Constructor as MemberBinding;
  17040. if(mb != null)
  17041. attrType = mb.BoundMember.DeclaringType;
  17042. else
  17043. {
  17044. Literal lit = attr.Constructor as Literal;
  17045. if(lit == null)
  17046. continue;
  17047. attrType = lit.Value as TypeNode;
  17048. }
  17049. if(attrType == SystemTypes.ParamArrayAttribute)
  17050. return this.paramArrayAttribute = attr;
  17051. }
  17052. result = this.paramArrayAttribute = AttributeNode.DoesNotExist;
  17053. }
  17054. if(result == AttributeNode.DoesNotExist)
  17055. return null;
  17056. return result;
  17057. }
  17058. public override bool Equals(object obj)
  17059. {
  17060. ParameterBinding binding = obj as ParameterBinding;
  17061. return obj == this || binding != null && binding.BoundParameter == this;
  17062. }
  17063. public override int GetHashCode()
  17064. {
  17065. return base.GetHashCode();
  17066. }
  17067. /// <summary>
  17068. /// Gets the first attribute of the given type in the attribute list of this parameter. Returns null if none found.
  17069. /// This should not be called until the AST containing this member has been processed to replace symbolic references
  17070. /// to members with references to the actual members.
  17071. /// </summary>
  17072. public virtual AttributeNode GetAttribute(TypeNode attributeType)
  17073. {
  17074. if(attributeType == null)
  17075. return null;
  17076. AttributeList attributes = this.Attributes;
  17077. for(int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
  17078. {
  17079. AttributeNode attr = attributes[i];
  17080. if(attr == null)
  17081. continue;
  17082. MemberBinding mb = attr.Constructor as MemberBinding;
  17083. if(mb != null)
  17084. {
  17085. if(mb.BoundMember == null)
  17086. continue;
  17087. if(mb.BoundMember.DeclaringType != attributeType)
  17088. continue;
  17089. return attr;
  17090. }
  17091. Literal lit = attr.Constructor as Literal;
  17092. if(lit == null)
  17093. continue;
  17094. if((lit.Value as TypeNode) != attributeType)
  17095. continue;
  17096. return attr;
  17097. }
  17098. return null;
  17099. }
  17100. public override string ToString()
  17101. {
  17102. if(this.Name == null)
  17103. return "";
  17104. if(this.Type == null)
  17105. return this.Name.ToString();
  17106. return this.Type.ToString() + " " + this.Name.ToString();
  17107. }
  17108. }
  17109. public class ParameterBinding : Parameter, IUniqueKey
  17110. {
  17111. public Parameter/*!*/ BoundParameter;
  17112. public ParameterBinding(Parameter/*!*/ boundParameter, SourceContext sctx)
  17113. {
  17114. if(boundParameter == null)
  17115. throw new ArgumentNullException("boundParameter");
  17116. this.BoundParameter = boundParameter;
  17117. this.SourceContext = sctx;
  17118. this.Type = boundParameter.Type;
  17119. this.Name = boundParameter.Name;
  17120. this.TypeExpression = boundParameter.TypeExpression;
  17121. this.Attributes = boundParameter.Attributes;
  17122. this.DefaultValue = boundParameter.DefaultValue;
  17123. this.Flags = boundParameter.Flags;
  17124. this.MarshallingInformation = boundParameter.MarshallingInformation;
  17125. this.DeclaringMethod = boundParameter.DeclaringMethod;
  17126. this.ParameterListIndex = boundParameter.ParameterListIndex;
  17127. this.ArgumentListIndex = boundParameter.ArgumentListIndex;
  17128. //^ base();
  17129. }
  17130. public override int GetHashCode()
  17131. {
  17132. return this.BoundParameter.GetHashCode();
  17133. }
  17134. public override bool Equals(object obj)
  17135. {
  17136. ParameterBinding pb = obj as ParameterBinding;
  17137. if(pb != null)
  17138. return this.BoundParameter.Equals(pb.BoundParameter);
  17139. else
  17140. return this.BoundParameter.Equals(obj);
  17141. }
  17142. int IUniqueKey.UniqueId
  17143. {
  17144. get { return this.BoundParameter.UniqueKey; }
  17145. }
  17146. }
  17147. public class Local : Variable
  17148. {
  17149. public Block DeclaringBlock;
  17150. public bool InitOnly;
  17151. public int Index;
  17152. public Local()
  17153. : base(NodeType.Local)
  17154. {
  17155. }
  17156. public Local(TypeNode type)
  17157. : base(NodeType.Local)
  17158. {
  17159. this.Name = Identifier.Empty;
  17160. if(type == null)
  17161. type = CoreSystemTypes.Object;
  17162. this.Type = type;
  17163. }
  17164. public Local(Identifier name, TypeNode type)
  17165. : this(type)
  17166. {
  17167. this.Name = name;
  17168. }
  17169. public Local(TypeNode type, SourceContext context)
  17170. : this(Identifier.Empty, type, null)
  17171. {
  17172. this.SourceContext = context;
  17173. }
  17174. public Local(Identifier name, TypeNode type, SourceContext context)
  17175. : this(name, type, null)
  17176. {
  17177. this.SourceContext = context;
  17178. }
  17179. public Local(Identifier name, TypeNode type, Block declaringBlock)
  17180. : base(NodeType.Local)
  17181. {
  17182. this.DeclaringBlock = declaringBlock;
  17183. this.Name = name;
  17184. if(type == null)
  17185. type = CoreSystemTypes.Object;
  17186. this.Type = type;
  17187. }
  17188. private bool pinned;
  17189. public bool Pinned
  17190. {
  17191. get { return this.pinned; }
  17192. set { this.pinned = value; }
  17193. }
  17194. public override bool Equals(object obj)
  17195. {
  17196. LocalBinding binding = obj as LocalBinding;
  17197. return obj == this || binding != null && binding.BoundLocal == this;
  17198. }
  17199. public override int GetHashCode()
  17200. {
  17201. return base.GetHashCode();
  17202. }
  17203. public override string ToString()
  17204. {
  17205. if(this.Name == null)
  17206. return "No name";
  17207. return this.Name.ToString();
  17208. }
  17209. }
  17210. public class LocalBinding : Local, IUniqueKey
  17211. {
  17212. public Local/*!*/ BoundLocal;
  17213. public LocalBinding(Local/*!*/ boundLocal, SourceContext sctx)
  17214. {
  17215. if(boundLocal == null)
  17216. throw new ArgumentNullException("boundLocal");
  17217. this.BoundLocal = boundLocal;
  17218. //^ base();
  17219. this.SourceContext = sctx;
  17220. this.Type = boundLocal.Type;
  17221. this.Name = boundLocal.Name;
  17222. this.TypeExpression = boundLocal.TypeExpression;
  17223. this.DeclaringBlock = boundLocal.DeclaringBlock;
  17224. this.Pinned = boundLocal.Pinned;
  17225. this.InitOnly = boundLocal.InitOnly;
  17226. this.Index = boundLocal.Index;
  17227. }
  17228. public override int GetHashCode()
  17229. {
  17230. return this.BoundLocal.GetHashCode();
  17231. }
  17232. public override bool Equals(object obj)
  17233. {
  17234. LocalBinding lb = obj as LocalBinding;
  17235. if(lb != null)
  17236. return this.BoundLocal.Equals(lb.BoundLocal);
  17237. else
  17238. return this.BoundLocal.Equals(obj);
  17239. }
  17240. int IUniqueKey.UniqueId
  17241. {
  17242. get { return this.BoundLocal.UniqueKey; }
  17243. }
  17244. }
  17245. /// <summary>
  17246. /// A named container of types and nested namespaces.
  17247. /// The name of the container implicitly qualifies the names of the contained types and namespaces.
  17248. /// </summary>
  17249. public class Namespace : Member
  17250. {
  17251. /// <summary>The FullName of the namespace in the form of an Identifier rather than in the form of a string.</summary>
  17252. public Identifier FullNameId;
  17253. /// <summary>
  17254. /// Provides alternative names for types and nested namespaces. Useful for introducing shorter names or for resolving name clashes.
  17255. /// The names should be added to the scope associated with this namespace.
  17256. /// </summary>
  17257. public AliasDefinitionList AliasDefinitions;
  17258. /// <summary>
  17259. /// The list of namespaces that are fully contained inside this namespace.
  17260. /// </summary>
  17261. public NamespaceList NestedNamespaces;
  17262. /// <summary>
  17263. /// The Universal Resource Identifier that should be associated with all declarations inside this namespace.
  17264. /// Typically used when the types inside the namespace are serialized as an XML Schema Definition. (XSD)
  17265. /// </summary>
  17266. public Identifier URI;
  17267. /// <summary>
  17268. /// The list of the namespaces of types that should be imported into the scope associated with this namespace.
  17269. /// </summary>
  17270. public UsedNamespaceList UsedNamespaces;
  17271. /// <summary>
  17272. /// A delegate that is called the first time Types is accessed. Provides for incremental construction of the namespace node.
  17273. /// </summary>
  17274. public TypeProvider ProvideTypes;
  17275. /// <summary>
  17276. /// Opaque information passed as a parameter to the delegate in ProvideTypes. Typically used to associate this namespace
  17277. /// instance with a helper object.
  17278. /// </summary>
  17279. public object ProviderHandle;
  17280. /// <summary>
  17281. /// A method that fills in the Types property of the given namespace. Must not leave Types null.
  17282. /// </summary>
  17283. public delegate void TypeProvider(Namespace @namespace, object handle);
  17284. protected string fullName;
  17285. protected TypeNodeList types;
  17286. public Namespace()
  17287. : base(NodeType.Namespace)
  17288. {
  17289. }
  17290. public Namespace(Identifier name)
  17291. : base(NodeType.Namespace)
  17292. {
  17293. this.Name = name;
  17294. this.FullNameId = name;
  17295. if(name != null)
  17296. this.fullName = name.ToString();
  17297. }
  17298. public Namespace(Identifier name, TypeProvider provideTypes, object providerHandle)
  17299. : base(NodeType.Namespace)
  17300. {
  17301. this.Name = name;
  17302. this.FullNameId = name;
  17303. if(name != null)
  17304. this.fullName = name.ToString();
  17305. this.ProvideTypes = provideTypes;
  17306. this.ProviderHandle = providerHandle;
  17307. }
  17308. public Namespace(Identifier name, Identifier fullName, AliasDefinitionList aliasDefinitions, UsedNamespaceList usedNamespaces,
  17309. NamespaceList nestedNamespaces, TypeNodeList types)
  17310. : base(NodeType.Namespace)
  17311. {
  17312. this.Name = name;
  17313. this.FullNameId = fullName;
  17314. if(fullName != null)
  17315. this.fullName = fullName.ToString();
  17316. this.AliasDefinitions = aliasDefinitions;
  17317. this.NestedNamespaces = nestedNamespaces;
  17318. this.Types = types;
  17319. this.UsedNamespaces = usedNamespaces;
  17320. }
  17321. public override string/*!*/ FullName
  17322. {
  17323. get { return this.fullName == null ? "" : this.fullName; }
  17324. }
  17325. public override bool IsAssembly { get { return false; } }
  17326. public override bool IsCompilerControlled { get { return false; } }
  17327. public override bool IsFamily { get { return false; } }
  17328. public override bool IsFamilyAndAssembly { get { return false; } }
  17329. public override bool IsFamilyOrAssembly { get { return false; } }
  17330. public override bool IsPrivate { get { return !this.IsPublic; } }
  17331. public override bool IsPublic { get { return this.isPublic; } }
  17332. protected internal bool isPublic;
  17333. public override bool IsSpecialName { get { return false; } }
  17334. public override bool IsStatic { get { return false; } }
  17335. public override bool IsVisibleOutsideAssembly { get { return false; } }
  17336. /// <summary>
  17337. /// The list of types contained inside this namespace. If the value of Types is null and the value of ProvideTypes is not null, the
  17338. /// TypeProvider delegate is called to fill in the value of this property.
  17339. /// </summary>
  17340. public TypeNodeList Types
  17341. {
  17342. get
  17343. {
  17344. if(this.types == null)
  17345. if(this.ProvideTypes != null)
  17346. lock(this)
  17347. {
  17348. if(this.types == null)
  17349. {
  17350. this.ProvideTypes(this, this.ProviderHandle);
  17351. }
  17352. }
  17353. else
  17354. this.types = new TypeNodeList();
  17355. return this.types;
  17356. }
  17357. set
  17358. {
  17359. this.types = value;
  17360. }
  17361. }
  17362. }
  17363. /// <summary>
  17364. /// The root node of an Abstract Syntax Tree. Typically corresponds to multiple source files compiled to form a single target.
  17365. /// </summary>
  17366. public class Compilation : Node
  17367. {
  17368. /// <summary>
  17369. /// The compilation parameters that are used for this compilation.
  17370. /// </summary>
  17371. public System.CodeDom.Compiler.CompilerParameters CompilerParameters;
  17372. /// <summary>
  17373. /// The target code object that is produced as a result of this compilation.
  17374. /// </summary>
  17375. public Module TargetModule;
  17376. /// <summary>
  17377. /// A list of all the compilation units (typically source files) that make up this compilation.
  17378. /// </summary>
  17379. public CompilationUnitList CompilationUnits;
  17380. /// <summary>
  17381. /// A scope for symbols that belong to the compilation as a whole. No C# equivalent. Null if not applicable.
  17382. /// </summary>
  17383. public Scope GlobalScope;
  17384. public DateTime LastModified = DateTime.Now;
  17385. public DateTime LastCompiled = DateTime.MinValue;
  17386. public Compilation()
  17387. : base(NodeType.Compilation)
  17388. {
  17389. }
  17390. public Compilation(Module targetModule, CompilationUnitList compilationUnits, System.CodeDom.Compiler.CompilerParameters compilerParameters, Scope globalScope)
  17391. : base(NodeType.Compilation)
  17392. {
  17393. this.CompilationUnits = compilationUnits;
  17394. this.TargetModule = targetModule;
  17395. this.CompilerParameters = compilerParameters;
  17396. this.GlobalScope = globalScope;
  17397. }
  17398. public virtual Compilation CloneCompilationUnits()
  17399. {
  17400. Compilation clone = (Compilation)base.Clone();
  17401. CompilationUnitList cus = this.CompilationUnits;
  17402. if(cus != null)
  17403. {
  17404. clone.CompilationUnits = cus = new CompilationUnitList(cus);
  17405. for(int i = 0, n = cus.Count; i < n; i++)
  17406. {
  17407. CompilationUnit cu = cus[i];
  17408. if(cu == null)
  17409. continue;
  17410. cus[i] = cu = (CompilationUnit)cu.Clone();
  17411. cu.Compilation = clone;
  17412. cu.Nodes = null;
  17413. }
  17414. }
  17415. return clone;
  17416. }
  17417. }
  17418. /// <summary>
  17419. /// The root node of an Abstract Syntax Tree. Corresponds to the starting production of the syntax. Equivalent to C# compilation-unit.
  17420. /// Typically a compilation unit corresponds to a single source file.
  17421. /// </summary>
  17422. public class CompilationUnit : Node
  17423. {
  17424. /// <summary>
  17425. /// An identifier that can be used to retrieve the source text of the compilation unit.
  17426. /// </summary>
  17427. public Identifier Name;
  17428. /// <summary>
  17429. /// An anonymous (name is Identifier.Empty) namespace holding types and nested namespaces.
  17430. /// </summary>
  17431. public NodeList Nodes;
  17432. /// <summary>
  17433. /// The preprocessor symbols that are to treated as defined when compiling this CompilationUnit into the TargetModule.
  17434. /// </summary>
  17435. public Hashtable PreprocessorDefinedSymbols;
  17436. /// <summary>
  17437. /// Pragma warning information.
  17438. /// </summary>
  17439. public TrivialHashtable PragmaWarnInformation;
  17440. /// <summary>
  17441. /// The compilation of which this unit forms a part.
  17442. /// </summary>
  17443. public Compilation Compilation;
  17444. public CompilationUnit()
  17445. : base(NodeType.CompilationUnit)
  17446. {
  17447. }
  17448. public CompilationUnit(Identifier name)
  17449. : base(NodeType.CompilationUnit)
  17450. {
  17451. this.Name = name;
  17452. }
  17453. }
  17454. public class CompilationUnitSnippet : CompilationUnit
  17455. {
  17456. public DateTime LastModified = DateTime.Now;
  17457. public IParserFactory ParserFactory;
  17458. public Method ChangedMethod;
  17459. public int OriginalEndPosOfChangedMethod;
  17460. public CompilationUnitSnippet()
  17461. {
  17462. this.NodeType = NodeType.CompilationUnitSnippet;
  17463. }
  17464. public CompilationUnitSnippet(Identifier name, IParserFactory parserFactory, SourceContext sctx)
  17465. {
  17466. this.NodeType = NodeType.CompilationUnitSnippet;
  17467. this.Name = name;
  17468. this.ParserFactory = parserFactory;
  17469. this.SourceContext = sctx;
  17470. }
  17471. }
  17472. public abstract class Composer
  17473. {
  17474. public abstract Node Compose(Node node, Composer context, bool hasContextReference, Class scope);
  17475. private class NullComposer : Composer
  17476. {
  17477. public override Node Compose(Node node, Composer context, bool hasContextReference, Class scope)
  17478. {
  17479. return node;
  17480. }
  17481. }
  17482. public static readonly Composer Null = new NullComposer();
  17483. }
  17484. public class Composition : Expression
  17485. {
  17486. public Expression Expression;
  17487. public Composer Composer;
  17488. public Class Scope;
  17489. public Composition(Expression exp, Composer composer, Class scope)
  17490. : base(NodeType.Composition)
  17491. {
  17492. this.Expression = exp;
  17493. this.Composer = composer;
  17494. this.Scope = scope;
  17495. if(exp != null)
  17496. this.Type = exp.Type;
  17497. }
  17498. }
  17499. /// <summary>
  17500. /// An object that knows how to produce a particular scope's view of a type.
  17501. /// </summary>
  17502. public class TypeViewer
  17503. {
  17504. /// <summary>
  17505. /// Return a scope's view of the argument type, where the scope's view is represented
  17506. /// by a type viewer.
  17507. /// [The identity function, except for dialects (e.g. Extensible Sing#) that allow
  17508. /// extensions and differing views of types].
  17509. /// Defined as a static method to allow the type viewer to be null,
  17510. /// meaning an identity-function view.
  17511. /// </summary>
  17512. public static TypeNode/*!*/ GetTypeView(TypeViewer typeViewer, TypeNode/*!*/ type)
  17513. {
  17514. return typeViewer == null ? type.EffectiveTypeNode : typeViewer.GetTypeView(type);
  17515. }
  17516. /// <summary>
  17517. /// Return the typeViewer's view of the argument type. Overridden by subclasses
  17518. /// that support non-identity-function type viewers, e.g. Extensible Sing#.
  17519. /// </summary>
  17520. protected virtual TypeNode/*!*/ GetTypeView(TypeNode/*!*/ type)
  17521. {
  17522. return type.EffectiveTypeNode;
  17523. }
  17524. }
  17525. static class PlatformHelpers
  17526. {
  17527. internal static bool TryParseInt32(String s, out Int32 result)
  17528. {
  17529. return Int32.TryParse(s, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out result);
  17530. }
  17531. internal static int StringCompareOrdinalIgnoreCase(string strA, int indexA, string strB, int indexB, int length)
  17532. {
  17533. return string.Compare(strA, indexA, strB, indexB, length, StringComparison.OrdinalIgnoreCase);
  17534. }
  17535. internal static int StringCompareOrdinalIgnoreCase(string strA, string strB)
  17536. {
  17537. return string.Compare(strA, strB, StringComparison.OrdinalIgnoreCase);
  17538. }
  17539. }
  17540. }