PageRenderTime 66ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/SpecSharp/System.Compiler.Framework/LanguageService/LanguageService.cs

#
C# | 2090 lines | 1924 code | 32 blank | 134 comment | 1262 complexity | e0e7c0d668acdcbb32d8d9094d74657b MD5 | raw file
  1. //-----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) Microsoft Corporation. All Rights Reserved.
  4. //
  5. //-----------------------------------------------------------------------------
  6. using System;
  7. using System.CodeDom.Compiler;
  8. using System.Collections;
  9. using System.ComponentModel;
  10. using System.Diagnostics;
  11. using System.Globalization;
  12. using System.IO;
  13. using System.Runtime.InteropServices;
  14. using System.Text;
  15. using System.Threading;
  16. using System.Xml;
  17. #if CCINamespace
  18. namespace Microsoft.Cci{
  19. #else
  20. namespace System.Compiler{
  21. #endif
  22. public class CommentInfo{
  23. public bool supported;
  24. public string lineStart;
  25. public string blockStart;
  26. public string blockEnd;
  27. public bool useLineComments;
  28. }
  29. public enum ParseReason{
  30. Colorize,
  31. Check,
  32. MemberSelect, // Also means Implicit invocation
  33. CompleteWord,
  34. QuickInfo,
  35. MethodTip,
  36. MatchBraces, // Also means parameter help.
  37. HighlightBraces,
  38. Autos,
  39. CodeSpan,
  40. CollapsibleRegions,
  41. MemberSelectExplicit,
  42. //Compile,
  43. }
  44. public abstract class LanguageService{
  45. /// <summary>Tracks the symbol table (Module) associated with the current editor window</summary>
  46. public Module currentSymbolTable;
  47. public Node currentAst;
  48. public CultureInfo culture;
  49. public ErrorHandler errorHandler;
  50. public Int32List identifierPositions;
  51. public Int32List identifierLengths;
  52. public NodeList identifierInfos;
  53. public Int32List identifierContexts;
  54. public ScopeList identifierScopes;
  55. public ScopeList allScopes;
  56. /// <summary>Set this to True if you want drop downs showing types and members</summary>
  57. public bool EnableDropDownCombos;
  58. public LanguageService(ErrorHandler errorHandler){
  59. this.errorHandler = errorHandler;
  60. this.GetCompilationFor = new LanguageService.GetCompilation(this.GetDummyCompilationFor);
  61. }
  62. public abstract Scanner GetScanner();
  63. public abstract Compilation GetDummyCompilationFor(string fileName);
  64. public abstract void ParseAndAnalyzeCompilationUnit(string fname, string source, int line, int col, ErrorNodeList errors, Compilation compilation, AuthoringSink sink);
  65. public abstract CompilationUnit ParseCompilationUnit(string fname, string source, ErrorNodeList errors, Compilation compilation, AuthoringSink sink);
  66. public abstract void Resolve(Member unresolvedMember, Member resolvedMember);
  67. public abstract void Resolve(CompilationUnit partialCompilationUnit);
  68. public virtual MemberList GetTypesNamespacesAndPrefixes(Scope scope, bool constructorMustBeVisible, bool listAllUnderRootNamespace) {
  69. return null;
  70. }
  71. public virtual MemberList GetVisibleNames(Scope scope){
  72. return null;
  73. }
  74. public virtual MemberList GetNestedNamespacesAndTypes(Identifier name, Scope scope){
  75. return this.GetNestedNamespacesAndTypes(name, scope, null);
  76. }
  77. public virtual MemberList GetNestedNamespacesAndTypes(Identifier name, Scope scope, AssemblyReferenceList assembliesToSearch){
  78. return null;
  79. }
  80. public virtual MemberList GetNestedNamespaces(Identifier name, Scope scope) {
  81. MemberList fullList = this.GetNestedNamespacesAndTypes(name, scope);
  82. MemberList result = new MemberList();
  83. for (int i = 0, n = fullList == null ? 0 : fullList.Count; i < n; i++){
  84. Namespace ns = fullList[i] as Namespace;
  85. if (ns == null) continue;
  86. result.Add(ns);
  87. }
  88. return result;
  89. }
  90. public virtual MemberList GetNamespacesAndAttributeTypes(Scope scope){
  91. return this.GetTypesNamespacesAndPrefixes(scope, true, false);
  92. }
  93. public virtual AuthoringHelper GetAuthoringHelper(){
  94. return new AuthoringHelper(this.errorHandler, this.culture);
  95. }
  96. public virtual AuthoringScope GetAuthoringScope(){
  97. return new AuthoringScope(this, this.GetAuthoringHelper());
  98. }
  99. public virtual void GetCommentFormat(CommentInfo info){
  100. info.supported = true;
  101. info.lineStart = "//";
  102. info.blockStart = "/*";
  103. info.blockEnd = "*/";
  104. info.useLineComments = true;
  105. }
  106. public virtual void GetMethodFormat(out string typeStart, out string typeEnd, out bool typePrefixed){
  107. typeStart = "";
  108. typeEnd = " ";
  109. typePrefixed = true;
  110. }
  111. public AuthoringScope ParseSource(string text, int line, int col, string fname, AuthoringSink asink, ParseReason reason){
  112. this.currentAst = null;
  113. Compilation compilation = this.GetCompilationFor(fname);
  114. Debug.Assert(compilation != null, "no compilation for: "+fname);
  115. this.currentSymbolTable = compilation.TargetModule;
  116. switch (reason){
  117. case ParseReason.CollapsibleRegions:
  118. case ParseReason.CompleteWord:
  119. case ParseReason.MatchBraces:
  120. case ParseReason.HighlightBraces:
  121. case ParseReason.MemberSelect:
  122. case ParseReason.MemberSelectExplicit:
  123. case ParseReason.MethodTip:
  124. case ParseReason.QuickInfo:
  125. case ParseReason.Autos:{
  126. return this.ParsePartialCompilationUnit(fname, text, line, col, asink, reason);
  127. }
  128. case ParseReason.Check:{
  129. ErrorNodeList errors = new ErrorNodeList();
  130. this.ParseAndAnalyzeCompilationUnit(fname, text, line, col, errors, compilation, asink);
  131. this.ReportErrors(fname, errors, asink);
  132. return this.GetAuthoringScope();
  133. }
  134. }
  135. return null;
  136. }
  137. public virtual AuthoringScope GetAuthoringScopeForMethodBody(string text, Compilation/*!*/ compilation, Method/*!*/ method, AuthoringSink asink) {
  138. return null;
  139. }
  140. public virtual AuthoringScope ParsePartialCompilationUnit(string fname, string text, int line, int col, AuthoringSink asink, ParseReason reason){
  141. Compilation compilation = this.GetCompilationFor(fname);
  142. if (line >= 0 && (reason == ParseReason.MemberSelect || reason == ParseReason.MemberSelectExplicit || reason == ParseReason.CompleteWord))
  143. text = this.Truncate(text, line, col);
  144. Module savedSymbolTable = this.currentSymbolTable;
  145. compilation.TargetModule = this.currentSymbolTable = new Module();
  146. this.currentSymbolTable.AssemblyReferences = savedSymbolTable.AssemblyReferences;
  147. CompilationUnit partialCompilationUnit = this.ParseCompilationUnit(fname, text, new ErrorNodeList(), compilation, asink);
  148. compilation.TargetModule = this.currentSymbolTable = savedSymbolTable;
  149. if (reason != ParseReason.HighlightBraces && reason != ParseReason.MatchBraces){
  150. MemberFinder memberFinder = this.GetMemberFinder(line+1, col+1);
  151. memberFinder.Visit(partialCompilationUnit);
  152. Member unresolvedMember = memberFinder.Member;
  153. memberFinder.Member = null;
  154. CompilationUnit cu = this.GetCompilationUnitSnippet(compilation, fname);
  155. if (cu != null){
  156. if (unresolvedMember == null){
  157. //Dealing with a construct that is not part of a type definition, such as a using statement
  158. this.Resolve(partialCompilationUnit);
  159. }else{
  160. memberFinder.Visit(cu);
  161. if (memberFinder.Member != null)
  162. this.Resolve(unresolvedMember, memberFinder.Member);
  163. else
  164. this.Resolve(partialCompilationUnit); //Symbol table is out of date
  165. }
  166. }
  167. }
  168. return this.GetAuthoringScope();
  169. }
  170. public virtual CompilationUnitSnippet GetCompilationUnitSnippet(Compilation compilation, string fname){
  171. if (compilation == null || compilation.CompilationUnits == null) return null;
  172. for (int i = 0, n = compilation.CompilationUnits.Count; i < n; i++){
  173. CompilationUnitSnippet cu = compilation.CompilationUnits[i] as CompilationUnitSnippet;
  174. if (cu == null) continue;
  175. if (string.Compare(cu.Name.ToString(), fname, true, System.Globalization.CultureInfo.InvariantCulture) != 0) continue;
  176. return cu;
  177. }
  178. return null;
  179. }
  180. public virtual MemberFinder GetMemberFinder(int line, int col){
  181. return new MemberFinder(line, col);
  182. }
  183. public virtual string Truncate(string text, int line, int col){
  184. // If we are just parsing for intellisense then there's no point parsing beyond
  185. // the caret position, except that we do need to complete the token so that we
  186. // provide the right intellisense on that token.
  187. int pos = 0;
  188. int length = text.Length;
  189. while ( pos < length && line >= 0 && col >= 0 ){
  190. char ch = text[pos++];
  191. if (line == 0 && col == 0){
  192. // cursor position - finish here
  193. if (!Char.IsLetter(ch)){
  194. pos--;
  195. break;
  196. }
  197. }else{
  198. // handle the standard ret/lf
  199. if (ch == '\r' && pos < length && text[pos] == '\n'){
  200. // reached a new line
  201. pos++;
  202. line --;
  203. continue;
  204. }
  205. // in case of dangling ret and lf we assume each one symbolises a new line
  206. // have not encountered this case, but it is safe to do ...
  207. if (ch == '\n' || ch == '\r'){line --; continue;}
  208. if (line == 0){
  209. // now we are in the correct line, so start counting column position
  210. col--;
  211. continue;
  212. }
  213. }
  214. }
  215. return text.Substring(0,pos);
  216. }
  217. public virtual int GetColorCount(){
  218. return (int)TokenColor.LastColor;
  219. }
  220. protected int lastLine = -1;
  221. protected int lastCol = -1;
  222. protected string lastFileName;
  223. public delegate Compilation GetCompilation(string fileName);
  224. public GetCompilation GetCompilationFor;
  225. public virtual CompilerParameters GetDummyCompilerParameters(){
  226. return new CompilerOptions();
  227. }
  228. public virtual void ReportErrors(string fileName, ErrorNodeList errors, AuthoringSink sink){
  229. if (sink == null) return;
  230. for (int n = errors.Count, i = n-1; i >= 0; i--){ //Scan backwards so that early errors trump later errors
  231. ErrorNode enode = errors[i];
  232. if (enode == null || enode.Severity < 0) continue;
  233. //TODO: suppress warnings of level > set in options
  234. SourceContext context = enode.SourceContext;
  235. if (context.Document == null) continue;
  236. if (context.Document.Name != fileName) continue;
  237. sink.AddError(enode);
  238. }
  239. }
  240. public virtual void SearchAstForNodeAtPosition(int line, int col, out Node node, out Scope scope, out int identContext){
  241. node = null;
  242. scope = null;
  243. identContext = IdentifierContexts.NullContext;
  244. }
  245. public virtual Scope SearchForLeastEnclosingScope(int line, int col) {
  246. if (allScopes == null) return null;
  247. Scope retScope = null;
  248. for (int i = 0; i < allScopes.Count; i++){
  249. SourceContext sc = allScopes[i].LexicalSourceExtent;
  250. if (sc.Encloses(line, col)) {
  251. if (retScope == null) {
  252. retScope = allScopes[i];
  253. }
  254. else {
  255. SourceContext scForRetScope = retScope.LexicalSourceExtent;
  256. if (scForRetScope.Encloses(sc))
  257. retScope = allScopes[i];
  258. }
  259. }
  260. }
  261. return retScope;
  262. }
  263. public virtual void AddReleventKeywords(MemberList memberList, Node node, Scope scope, int identifierContext) {
  264. return;
  265. }
  266. public virtual void SearchForNodeAtPosition(int line, int col, out Node node, out Scope scope, out int identifierContext) {
  267. if (this.currentAst != null) {
  268. this.SearchAstForNodeAtPosition(line, col, out node, out scope, out identifierContext);
  269. identifierContext = IdentifierContexts.NullContext;
  270. return;
  271. }
  272. node = null;
  273. scope = null;
  274. identifierContext = IdentifierContexts.AllContext;
  275. int pos = line*1000+col;
  276. Int32List posList = this.identifierPositions;
  277. Int32List lenList = this.identifierLengths;
  278. NodeList infos = this.identifierInfos;
  279. ScopeList scopes = this.identifierScopes;
  280. Int32List identContexts = this.identifierContexts;
  281. if (posList == null || infos == null) return;
  282. int i = 0, n = posList.Count, j = n-1;
  283. while (i < j){
  284. int k = (i+j) / 2;
  285. int m = posList[k] - pos;
  286. if (m < 0)
  287. i = k+1;
  288. else if (m > 0)
  289. j = k;
  290. else{
  291. // Move ahead to the last index with the same pos.
  292. while (k < n-1 && posList[k+1] == pos)
  293. k++;
  294. int bestMatch = -1;
  295. while (k >= 0 && posList[k] / 1000 == line) {
  296. // Within the tange and smaller in length than best match
  297. if (((posList[k] % 1000) <= col) && ((posList[k] % 1000) + lenList[k] >= col) && (bestMatch == -1 || lenList[k] < lenList[bestMatch]))
  298. bestMatch = k;
  299. k--;
  300. }
  301. node = infos[bestMatch];
  302. identifierContext = identContexts[bestMatch];
  303. scope = scopes[bestMatch];
  304. return;
  305. }
  306. }
  307. if (j >= 0){
  308. if (posList[j] > pos && j > 0) j--;
  309. if (j >= n - 1 && posList[j] / 1000 < line) {
  310. node = infos[j];
  311. identifierContext = identContexts[j];
  312. if (node != null) {
  313. if (node.SourceContext.EndLine == line && node.SourceContext.EndColumn == col) {
  314. scope = scopes[j];
  315. return;
  316. }
  317. node = null;
  318. identifierContext = IdentifierContexts.AllContext;
  319. }
  320. return; //At the last node, but not on the same line. No match.
  321. }
  322. int bestMatch = -1;
  323. while (j >= 0 && posList[j] / 1000 == line){
  324. // Within the tange and smaller in length than best match
  325. if (((posList[j] % 1000) <= col) && ((posList[j] % 1000) + lenList[j] >= col) && (bestMatch == -1 || lenList[j] < lenList[bestMatch]))
  326. bestMatch = j;
  327. j--;
  328. }
  329. if (bestMatch < 0 || posList[bestMatch] / 1000 != line) return;
  330. node = infos[bestMatch];
  331. identifierContext = identContexts[bestMatch];
  332. scope = scopes[bestMatch];
  333. }
  334. return;
  335. }
  336. public virtual MemberList GetConstructibleNestedTypes(TypeNode typeNode, TypeNode referringType){
  337. if (typeNode == null) return null;
  338. MemberList result = new MemberList();
  339. TypeNodeList nestedTypes = typeNode.NestedTypes;
  340. for (int i = 0, n = nestedTypes == null ? 0 : nestedTypes.Count; i < n; i++){
  341. TypeNode nt = nestedTypes[i];
  342. if (this.TypeHasNoVisibleConstructorsOrIsAbstract(nt, referringType)) continue;
  343. result.Add(nt);
  344. }
  345. return result;
  346. }
  347. public virtual bool TypeHasNoVisibleConstructorsOrIsAbstract(TypeNode type, TypeNode referringType){
  348. if (type == null || referringType == null || type.IsAbstract) return true;
  349. if (type is Struct || type is EnumNode) return false;
  350. TypeNode dummy = referringType;
  351. MemberList constructors = type.GetConstructors();
  352. for (int i = 0, n = constructors == null ? 0 : constructors.Count; i < n; i++){
  353. Member constr = constructors[i];
  354. if (constr == null) continue;
  355. if (!Checker.NotAccessible(constr, ref dummy, referringType.DeclaringModule, referringType, null)) return false;
  356. }
  357. return true;
  358. }
  359. }
  360. public class AuthoringScope{
  361. protected LanguageService languageService;
  362. protected AuthoringHelper helper;
  363. protected bool suppressAttributeSuffix;
  364. public AuthoringScope(LanguageService languageService, AuthoringHelper helper){
  365. this.languageService = languageService;
  366. this.helper = helper;
  367. }
  368. public virtual Member GetMember(int line, int col){
  369. Node n;
  370. Scope scope;
  371. int identContext;
  372. this.languageService.SearchForNodeAtPosition(line + 1, col + 1, out n, out scope, out identContext);
  373. if (n == null) return null;
  374. MemberBinding mb = this.GetMemberBinding(n);
  375. if (mb != null) return mb.BoundMember;
  376. TypeNode t = n as TypeNode;
  377. if (t == null && n is Expression)
  378. t = ((Expression)n).Type;
  379. if (t != null) return t;
  380. t = this.GetQueryResultType(n);
  381. if (t != null) return t;
  382. return null;
  383. }
  384. public virtual string GetDataTipText(int line, int col, out SourceContext sourceContext){
  385. Node n;
  386. Scope scope;
  387. int identContext;
  388. this.languageService.SearchForNodeAtPosition(line + 1, col + 1, out n, out scope, out identContext);
  389. if (n == null){
  390. sourceContext = new SourceContext(); return null;
  391. }
  392. sourceContext = n.SourceContext;
  393. string helpText = null;
  394. MemberBinding mb = this.GetMemberBinding(n);
  395. string memberSignature = "";
  396. if (mb != null){
  397. sourceContext = mb.SourceContext;
  398. Member mem = mb.BoundMember;
  399. Method m = mem as Method;
  400. if (m != null && m.IsSpecialName && m.Name.ToString().StartsWith("get_")){
  401. TypeNode[] types = m.GetParameterTypes();
  402. Identifier propId = Identifier.For(m.Name.ToString().Substring(4));
  403. TypeNode ty = m.DeclaringType;
  404. while (ty != null){
  405. Property prop = ty.GetProperty(propId, types);
  406. if (prop != null){
  407. mem = prop;
  408. break;
  409. }
  410. ty = ty.BaseType;
  411. }
  412. }
  413. helpText = mem.HelpText;
  414. if (mb.TargetObject is ImplicitThis){
  415. if (mem.DeclaringType is BlockScope)
  416. memberSignature = this.languageService.errorHandler.GetLocalSignature(mem as Field);
  417. else if (mem is ParameterField)
  418. memberSignature = this.languageService.errorHandler.GetParameterSignature((ParameterField)mem);
  419. else if (mem is Field || mem is Property)
  420. memberSignature = this.languageService.errorHandler.GetInstanceMemberSignature(mb.BoundMember);
  421. else
  422. memberSignature = this.languageService.errorHandler.GetMemberSignature(mb.BoundMember, true);
  423. }else
  424. memberSignature = this.languageService.errorHandler.GetMemberSignature(mb.BoundMember, true);
  425. if (helpText == "" && mb.BoundMember is InstanceInitializer)
  426. helpText = mem.DeclaringType.HelpText;
  427. }else{
  428. TypeNode t = n as TypeNode;
  429. if (t == null && n is Expression)
  430. t = ((Expression)n).Type;
  431. if (t != null){
  432. memberSignature = this.languageService.errorHandler.GetMemberSignature(t, true);
  433. helpText = t.HelpText;
  434. }else{
  435. t = this.GetQueryResultType(n);
  436. if (t != null)
  437. memberSignature = this.languageService.errorHandler.GetMemberSignature(t, false);
  438. }
  439. }
  440. if (helpText != null && helpText != "")
  441. return memberSignature + "\n" + helpText;
  442. else
  443. return memberSignature;
  444. }
  445. public virtual SourceContext GetPositionOfDeclaration(int line, int col){
  446. return this.GetPositionOfDefinition(line, col);
  447. }
  448. public virtual Node GetDefinition(int line, int col) {
  449. Node n;
  450. Scope scope;
  451. int identContext;
  452. this.languageService.SearchForNodeAtPosition(line + 1, col + 1, out n, out scope, out identContext);
  453. if (n is TypeNode)
  454. return n;
  455. MemberBinding mb = this.GetMemberBinding(n);
  456. if (mb != null) {
  457. Member mem = mb.BoundMember;
  458. if (mem != null) {
  459. n = mem;
  460. }
  461. }
  462. return n;
  463. }
  464. public virtual SourceContext GetPositionOfDefinition(Node definition) {
  465. TypeNode type = definition as TypeNode;
  466. Member member = definition as Member;
  467. Identifier name = null;
  468. if (type != null)
  469. name = type.Name;
  470. else if (member != null)
  471. name = member.Name;
  472. SourceContext result = new SourceContext();
  473. if (name != null) result = name.SourceContext;
  474. return result;
  475. }
  476. public virtual SourceContext GetPositionOfDefinition(int line, int col) {
  477. return this.GetPositionOfDefinition(this.GetDefinition(line, col));
  478. }
  479. public virtual SourceContext GetPositionOfReference(int line, int col){
  480. return new SourceContext();
  481. }
  482. protected virtual MemberBinding GetMemberBinding(Node n){
  483. NameBinding nb = n as NameBinding;
  484. QualifiedIdentifier qualId = n as QualifiedIdentifier;
  485. Construct cons = n as Construct;
  486. AttributeNode attr = n as AttributeNode;
  487. MemberBinding mb = null;
  488. if (nb != null)
  489. mb = nb.BoundMember as MemberBinding;
  490. else if (qualId != null)
  491. mb = qualId.BoundMember as MemberBinding;
  492. else if (cons != null)
  493. mb = cons.Constructor as MemberBinding;
  494. else if (attr != null){
  495. Literal lit = attr.Constructor as Literal;
  496. if (lit == null || !(lit.Value is TypeNode)) return null;
  497. mb = new MemberBinding(null, (TypeNode)lit.Value);
  498. }else
  499. mb = n as MemberBinding;
  500. return mb;
  501. }
  502. protected virtual TypeNode GetQueryResultType(Node n){
  503. QualifiedIdentifier qualId = n as QualifiedIdentifier;
  504. if (qualId == null) return null;
  505. QueryAxis qAxis = qualId.Qualifier as QueryAxis;
  506. if (qAxis == null) return null;
  507. return qAxis.Type;
  508. }
  509. /// <summary>
  510. /// Called for completions.
  511. /// </summary>
  512. public virtual Declarations GetDeclarations(int line, int col, ParseReason reason){
  513. Scope scope;
  514. Node node;
  515. MemberList members = this.GetMembers(line, col, reason, out node, out scope);
  516. if (members == null) members = new MemberList(); // return empty list then.
  517. return new Declarations(members, this.helper, node, scope);
  518. }
  519. public virtual MemberList FilterByContext(MemberList originalList, int identContext) {
  520. if (originalList == null || identContext == IdentifierContexts.AllContext) return originalList;
  521. MemberList retMemberList = new MemberList();
  522. for (int i = 0; i < originalList.Count; ++i) {
  523. Member memb = originalList[i];
  524. if (!this.MemberSatisfies(memb, identContext)) continue;
  525. retMemberList.Add(memb);
  526. }
  527. return retMemberList;
  528. }
  529. public virtual bool MemberSatisfies(Member memb, int identContext) {
  530. return true;
  531. }
  532. // MemberSelectExplicit =>
  533. // if node != null then show rele vent stuff only
  534. // else show default list
  535. // MemberSelect =>
  536. // if node != null then show relevent stuff only
  537. // dont show anything
  538. public virtual MemberList GetMembers(int line, int col, ParseReason reason, out Node node, out Scope scope){
  539. int identContext;
  540. this.languageService.SearchForNodeAtPosition(line + 1, col + 1, out node, out scope, out identContext);
  541. if (identContext == IdentifierContexts.NullContext) return null;
  542. bool doingCompletion = reason == ParseReason.MemberSelect || reason == ParseReason.MemberSelectExplicit || reason == ParseReason.CompleteWord;
  543. MemberList retList = null;
  544. QualifiedIdentifier qi = node as QualifiedIdentifier;
  545. if (qi != null && qi.Identifier.UniqueIdKey == StandardIds.Ctor.UniqueIdKey && (qi.Qualifier is This || qi.Qualifier is Base) && reason == ParseReason.CompleteWord) {
  546. node = null;
  547. retList = this.GetMembers(line, col, node, scope);
  548. } else if ((node as Scope) == scope && scope != null) {
  549. retList = this.languageService.GetTypesNamespacesAndPrefixes(scope, false, false);
  550. } else if (node is AttributeNode) {
  551. retList = this.GetMembers(line, col, (AttributeNode)node, scope);
  552. } else if (node is ClassExpression) {
  553. retList = this.GetMembers(line, col, (ClassExpression)node, scope);
  554. } else if (node is InterfaceExpression) {
  555. InterfaceExpression ie = (InterfaceExpression)node;
  556. if (ie.Expression != null && ie.Expression is QualifiedIdentifier)
  557. retList = this.GetMembers(line, col, ie.Expression as QualifiedIdentifier, scope);
  558. else
  559. retList = this.GetMembers(line, col, (InterfaceExpression)node, scope);
  560. } else if (node is Construct) {
  561. retList = this.GetMembers(line, col, (Construct)node, scope, doingCompletion);
  562. } else if (node is UsedNamespace && (node.SourceContext.StartLine == line + 1)) {
  563. retList = this.languageService.GetNestedNamespaces(((UsedNamespace)node).Namespace, scope);
  564. } else if (node is AliasDefinition) {
  565. retList = this.GetMembers(line, col, (AliasDefinition)node, scope);
  566. } else if (node is Namespace) {
  567. Namespace ns = (Namespace)node;
  568. string name = ns.FullName;
  569. if (name != null && (name.Equals("global:") || name.Length == 0)) {
  570. Scope iterScope = scope;
  571. while (iterScope != null && iterScope.OuterScope != null)
  572. iterScope = iterScope.OuterScope;
  573. retList = this.languageService.GetNestedNamespacesAndTypes(Identifier.Empty, iterScope);
  574. goto returnList;
  575. }
  576. if (doingCompletion)
  577. retList = this.FillWithDefaultList(line, col, node, scope);
  578. else
  579. retList = this.GetMembers(line, col, ns, scope);
  580. } else if (node is QualifiedIdentifier) {
  581. retList = this.GetMembers(line, col, qi, scope);
  582. } else if (node is TemplateInstance) {
  583. retList = this.GetMembers(line, col, (TemplateInstance)node, scope);
  584. } else if (node is TypeExpression) {
  585. retList = this.GetMembers(line, col, (TypeExpression)node, scope);
  586. } else if (node is NameBinding) {
  587. retList = this.GetMembers(line, col, (NameBinding)node, scope, doingCompletion);
  588. } else if (node is Event || node is Method || node is Property) {
  589. retList = this.GetMembers(line, col, (Member)node, scope, doingCompletion);
  590. } else if (node is This) {
  591. retList = this.GetMembers(line, col, (This)node, scope, doingCompletion);
  592. } else if (node is Base) {
  593. retList = this.GetMembers(line, col, (Base)node, scope, doingCompletion);
  594. } else if (node is Identifier || node is Class || node is Interface) {
  595. retList = this.FillWithDefaultList(line, col, node, scope);
  596. }
  597. if (node == null && (reason == ParseReason.CompleteWord || reason == ParseReason.MemberSelectExplicit)) {
  598. retList = this.FillWithDefaultList(line, col, node, scope);
  599. } else if (reason == ParseReason.MethodTip) {
  600. Class cl = node as Class;
  601. if (cl != null && cl.IsAssignableTo(SystemTypes.Attribute)) {
  602. this.suppressAttributeSuffix = true;
  603. retList = new MemberList();
  604. MemberList memList = cl.GetConstructors();
  605. bool showInternal = this.MayAccessInternals(this.languageService.currentSymbolTable, cl);
  606. if (memList != null) {
  607. int n = memList.Count;
  608. for (int i = 0; i < n; ++i) {
  609. Member mem = memList[i];
  610. if (mem == null) continue;
  611. if (mem.IsCompilerControlled) continue;
  612. if (mem.IsPrivate) continue;
  613. if (mem.IsFamily || mem.IsFamilyAndAssembly) continue;
  614. if ((mem.IsAssembly || mem.IsFamilyOrAssembly) && !showInternal) continue;
  615. retList.Add(mem);
  616. }
  617. }
  618. }
  619. }
  620. if (retList != null && reason != ParseReason.MethodTip) {
  621. retList = this.FilterByContext(retList, identContext);
  622. this.languageService.AddReleventKeywords(retList, node, scope, identContext);
  623. }
  624. returnList:
  625. return retList;
  626. }
  627. private MemberList FillWithDefaultList(int line, int col, Node node, Scope scope) {
  628. Scope contScope = scope;
  629. if (contScope == null) contScope = this.languageService.SearchForLeastEnclosingScope(line + 1, col + 1);
  630. MemberList retList = this.GetMembers(line, col, node, contScope);
  631. if (retList != null) {
  632. Identifier id = node as Identifier;
  633. if (id != null)
  634. retList.Add(id.Type);
  635. }
  636. return retList;
  637. }
  638. protected virtual MemberList GetMembers(int line, int col, This thisNode, Scope scope, bool doingCompletion) {
  639. if (thisNode == null || scope == null || !(thisNode.Type is Class)) return null;
  640. if (thisNode.IsCtorCall)
  641. return ((Class)thisNode.Type).GetConstructors();
  642. else
  643. return ((Class)thisNode.Type).DefaultMembers;
  644. }
  645. protected virtual MemberList GetMembers(int line, int col, Base baseNode, Scope scope, bool doingCompletion) {
  646. if (baseNode == null || scope == null || !(baseNode.Type is Class)) return null;
  647. if (baseNode.IsCtorCall)
  648. return ((Class)baseNode.Type).GetConstructors();
  649. else
  650. return ((Class)baseNode.Type).DefaultMembers;
  651. }
  652. protected virtual MemberList GetMembers(int line, int col, AttributeNode attrNode, Scope scope) {
  653. if (attrNode == null || scope == null) return null;
  654. Literal lit = attrNode.Constructor as Literal;
  655. if (lit != null && lit.Value is TypeNode) return new MemberList((TypeNode)lit.Value);
  656. return this.languageService.GetNamespacesAndAttributeTypes(scope);
  657. }
  658. protected virtual MemberList GetMembers(int line, int col, AliasDefinition aliasDef, Scope scope){
  659. if (aliasDef == null || scope == null) return null;
  660. //deal with case where the alias is being defined, e.g. "using sys = System."
  661. if (aliasDef.SourceContext.StartLine == line+1)
  662. return this.languageService.GetNestedNamespacesAndTypes(aliasDef.AliasedExpression as Identifier, scope);
  663. //deal with the case where the alias is being used, e.g. "sys::"
  664. MemberList members;
  665. if (aliasDef.AliasedNamespace != null && aliasDef.AliasedNamespace.Name != null)
  666. members = this.GetMembers(line, col, new QualifiedIdentifier(aliasDef.AliasedNamespace, Identifier.Empty, aliasDef.SourceContext), scope);
  667. else
  668. members = this.languageService.GetNestedNamespacesAndTypes(Identifier.Empty, scope, aliasDef.AliasedAssemblies);
  669. if (scope is AttributeScope) return members;
  670. if (aliasDef.RestrictToClassesAndInterfaces)
  671. members = this.GetClassesAndInterfacesAndNamespacesThatContainThem(members, null);
  672. else if (aliasDef.RestrictToInterfaces)
  673. members = this.GetInterfacesAndNamespacesThatContainThem(scope, members);
  674. return members;
  675. }
  676. protected virtual MemberList GetMembers(int line, int col, ClassExpression cExpr, Scope scope){
  677. if (cExpr == null) return null;
  678. MemberList members;
  679. QualifiedIdentifier qual = cExpr.Expression as QualifiedIdentifier;
  680. if (qual != null)
  681. members = this.GetMembers(line, col, qual, scope);
  682. else
  683. members = this.languageService.GetTypesNamespacesAndPrefixes(scope, false, false);
  684. if (members == null) return null;
  685. return this.GetClassesAndInterfacesAndNamespacesThatContainThem(members, cExpr.DeclaringType);
  686. }
  687. protected virtual MemberList GetClassesAndInterfacesAndNamespacesThatContainThem(MemberList members, TypeNode classToExclude){
  688. MemberList result = new MemberList(members.Count);
  689. for (int i = 0, n = members.Count; i < n; i++) {
  690. Member mem = members[i];
  691. if (mem is Class && classToExclude != null && mem.FullName == classToExclude.FullName) continue;
  692. if (mem is Interface || mem is Namespace)
  693. result.Add(mem); //TODO: show namespaces only if they have classes or interfaces or types with nested classes/interfaces.
  694. else{
  695. Class cl = mem as Class;
  696. if (cl == null || cl.IsSealed || cl == SystemTypes.Array || cl == SystemTypes.Delegate || cl == SystemTypes.Enum ||
  697. cl == SystemTypes.MulticastDelegate || cl == SystemTypes.ValueType) continue;
  698. result.Add(mem);
  699. }
  700. }
  701. if (result.Count == 0) return null;
  702. return result;
  703. }
  704. protected virtual MemberList GetConstructibleTypesAndAndNamespacesThatContainThem(MemberList members, TypeNode referringType){
  705. MemberList result = new MemberList(members.Count);
  706. for (int i = 0, n = members.Count; i < n; i++) {
  707. Member mem = members[i];
  708. if (mem is Namespace)
  709. result.Add(mem); //TODO: show namespaces only if they have classes or interfaces or types with nested classes/interfaces.
  710. else{
  711. TypeNode t = mem as TypeNode;
  712. if (t == null || this.languageService.TypeHasNoVisibleConstructorsOrIsAbstract(t, referringType)) continue;
  713. result.Add(mem);
  714. }
  715. }
  716. if (result.Count == 0) return null;
  717. return result;
  718. }
  719. protected virtual MemberList GetMembers(int line, int col, InterfaceExpression iExpr, Scope scope) {
  720. MemberList members = this.languageService.GetTypesNamespacesAndPrefixes(scope, false, false);
  721. if (members == null) return null;
  722. return this.GetInterfacesAndNamespacesThatContainThem(scope, members);
  723. }
  724. protected virtual MemberList GetInterfacesAndNamespacesThatContainThem(Scope scope, MemberList members){
  725. MemberList result = new MemberList(members.Count);
  726. for (int i = 0, n = members.Count; i < n; i++) {
  727. Member mem = members[i];
  728. if (mem is Interface || mem is Namespace || (mem is TypeNode && this.HasNestedInterface((TypeNode)mem, scope)))
  729. result.Add(mem); //TODO: show namespaces only if they have interfaces or types with nested interfaces
  730. }
  731. if (result.Count == 0) return null;
  732. return result;
  733. }
  734. private bool HasNestedInterface(TypeNode typeNode, Scope scope){
  735. if (typeNode == null) return false;
  736. MemberList members = typeNode.Members;
  737. for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++){
  738. TypeNode nt = members[i] as TypeNode;
  739. if (nt == null) continue;
  740. if (nt.IsPrivate) continue; //TODO: check that other visibilities are visible from given scope
  741. if (nt is Interface) return true;
  742. if (this.HasNestedInterface(nt, scope)) return true;
  743. }
  744. return false;
  745. }
  746. protected virtual MemberList GetMembers(int line, int col, Namespace nspace, Scope scope){
  747. if (nspace == null || nspace.Name == null || scope == null) return null;
  748. string nsname = nspace.Name.ToString();
  749. if (nsname == null || nsname.Length == 0) return null;
  750. if (nsname[nsname.Length-1] == ':') nsname = nsname.Substring(0, nsname.Length-1) + ".";
  751. return this.languageService.GetNestedNamespacesAndTypes(Identifier.For(nsname), scope);
  752. }
  753. protected virtual MemberList GetMembers(int line, int col, Construct cons, Scope scope, bool doingCompletion){
  754. if (cons == null) return null;
  755. MemberBinding mb = cons.Constructor as MemberBinding;
  756. if (mb != null && !doingCompletion) {
  757. if (mb.BoundMember is InstanceInitializer && mb.BoundMember.DeclaringType != null)
  758. return new MemberList(mb.BoundMember.DeclaringType);
  759. else if (mb.BoundMember is TypeNode) {
  760. return new MemberList(mb.BoundMember);
  761. }
  762. }
  763. MemberList result = null;
  764. QualifiedIdentifier qual = cons.Constructor as QualifiedIdentifier;
  765. if (qual != null){
  766. if (qual.Qualifier is Literal && ((Literal)qual.Qualifier).Value is TypeNode)
  767. return this.languageService.GetConstructibleNestedTypes((TypeNode)((Literal)qual.Qualifier).Value, this.GetReferringType(scope));
  768. result = this.GetMembers(line, col, qual, scope);
  769. if (result != null)
  770. return this.GetConstructibleTypesAndAndNamespacesThatContainThem(result, this.GetReferringType(scope));
  771. }
  772. if (scope != null) result = this.languageService.GetTypesNamespacesAndPrefixes(scope, true, false);
  773. if (result != null){
  774. if (cons.Type != null && !(cons.Type is Reference)) {
  775. TypeNode type = cons.Type;
  776. while (type != null) {
  777. if (type is ArrayType)
  778. type = ((ArrayType)type).ElementType;
  779. else if (type is Pointer)
  780. type = ((Pointer)type).ElementType;
  781. else
  782. break;
  783. }
  784. if (type != null && (type != cons.Type || !this.languageService.TypeHasNoVisibleConstructorsOrIsAbstract(type, this.GetReferringType(scope))))
  785. result.Add(type);
  786. else
  787. result.Add(null); // Always add something to the end of the list in the case of constructor. We will remove this later when creating declaration.
  788. }
  789. if (result.Count > 0) return result;
  790. }
  791. return null;
  792. }
  793. protected virtual MemberList FilterOutIncassessibleMembers(MemberList members, Scope scope){
  794. if (members == null) return null;
  795. TypeNode referringType = GetReferringType(scope);
  796. MemberList result = new MemberList(members.Count);
  797. for (int i = 0, n = members.Count; i < n; i++){
  798. Member member = members[i];
  799. if (member == null) continue;
  800. if (member.IsPrivate && referringType != member.DeclaringType) continue;
  801. if ((member.IsFamily || member.IsFamilyAndAssembly) && referringType.IsAssignableTo(member.DeclaringType)) continue;
  802. if (member.IsAssembly && !this.MayAccessInternals(referringType, member.DeclaringType)) continue;
  803. if (member.IsFamilyOrAssembly && !referringType.IsAssignableTo(member.DeclaringType) && !this.MayAccessInternals(referringType, member.DeclaringType)) continue;
  804. result.Add(member);
  805. }
  806. return result;
  807. }
  808. protected virtual TypeNode GetReferringType(Scope scope){
  809. TypeNode referringType = null;
  810. while (scope != null) {
  811. TypeScope tScope = scope as TypeScope;
  812. if (tScope != null) {
  813. referringType = tScope.Type;
  814. break;
  815. }
  816. scope = scope.OuterScope;
  817. }
  818. return referringType;
  819. }
  820. protected virtual MemberList GetMembers(int line, int col, Node node, Scope scope){
  821. if (node is MemberBinding) return null;
  822. if (scope != null) return this.languageService.GetVisibleNames(scope);
  823. return null;
  824. }
  825. protected virtual MemberList GetMembers(int line, int col, NameBinding nameBinding, Scope scope, bool doingCompletion) {
  826. if (nameBinding == null) return null;
  827. if (nameBinding.BoundMembers != null && !doingCompletion)
  828. return this.FilterOutIncassessibleMembers(nameBinding.BoundMembers, scope);
  829. if (scope != null) return this.languageService.GetVisibleNames(scope);
  830. return null;
  831. }
  832. protected virtual MemberList GetMembers(int line, int col, Member memberNode, Scope scope, bool doingCompletion) {
  833. if (memberNode == null) return null;
  834. Interface i = null;
  835. TypeNode type = memberNode.DeclaringType;
  836. NodeType toShow = NodeType.Method;
  837. Event e = memberNode as Event;
  838. if (e != null){
  839. if (e.ImplementedTypes == null || e.ImplementedTypes.Count == 0) return null;
  840. i = e.ImplementedTypes[0] as Interface;
  841. toShow = NodeType.Event;
  842. }
  843. Property p = memberNode as Property;
  844. if(p != null){
  845. if (p.ImplementedTypes == null || p.ImplementedTypes.Count == 0) return null;
  846. i = p.ImplementedTypes[0] as Interface;
  847. toShow = NodeType.Method;
  848. }
  849. Method m = memberNode as Method;
  850. if(m != null){
  851. if (m.ImplementedTypes == null || m.ImplementedTypes.Count == 0) return null;
  852. i = m.ImplementedTypes[0] as Interface;
  853. toShow = NodeType.Method;
  854. }
  855. if (i == null) return null;
  856. TypeNode referringType = null;
  857. while (scope != null) {
  858. TypeScope tScope = scope as TypeScope;
  859. if (tScope != null) {
  860. referringType = tScope.Type;
  861. break;
  862. }
  863. scope = scope.OuterScope;
  864. }
  865. bool showInternal = this.MayAccessInternals(referringType, type);
  866. MemberList result = new MemberList();
  867. this.GetMembers(i, result, showInternal, toShow);
  868. return result;
  869. }
  870. protected virtual MemberList GetMembers(int line, int col, QualifiedIdentifier qualId, Scope scope) {
  871. if (qualId == null) return null;
  872. bool staticMembersWanted = true;
  873. bool allMembersWanted = false;
  874. Node n = qualId.Qualifier;
  875. if (n == null || n.IsErroneous) return null;
  876. if (n is ConstructArray) return null;
  877. TypeNode type = null;
  878. MemberBinding mb = this.GetMemberBinding(n);
  879. if (mb != null){
  880. staticMembersWanted = false;
  881. Member mem = mb.BoundMember;
  882. if (mem is Field)
  883. type = ((Field)mem).Type;
  884. else if (mem is Property)
  885. type = ((Property)mem).Type;
  886. else if (mem is InstanceInitializer)
  887. type = mem.DeclaringType;
  888. //TODO: other stuff? Events?
  889. allMembersWanted = (mem != null && type != null && mem.Name != null && type.Name != null && mem.Name.UniqueIdKey == type.Name.UniqueIdKey);
  890. }else{
  891. if (n is Identifier || n is NameBinding || n is QualifiedIdentifier){
  892. NameBinding nb = n as NameBinding;
  893. if (nb != null) n = nb.Identifier;
  894. return this.languageService.GetNestedNamespacesAndTypes(this.ConvertToNamespaceId((Expression)n), scope);
  895. }
  896. type = n as TypeNode;
  897. if (type == null){
  898. if (n is Literal){
  899. if (Literal.IsNullLiteral((Literal)n)) return null;
  900. type = ((Literal)n).Value as TypeNode;
  901. }
  902. Expression expr = n as Expression;
  903. if (type == null && expr != null){
  904. if (n is Base && n.SourceContext.Document == null) return null;
  905. staticMembersWanted = false;
  906. type = expr.Type;
  907. MethodCall mc = expr as MethodCall;
  908. bool useEnum = false;
  909. if (mc != null && mc.Callee is MemberBinding) {
  910. Member mem = ((MemberBinding)mc.Callee).BoundMember;
  911. Method meth = mem as Method;
  912. if (meth != null) {
  913. Property p = meth.DeclaringMember as Property;
  914. useEnum = p == null;
  915. allMembersWanted = p != null && type != null && p.Name != null && type.Name != null && p.Name.UniqueIdKey == type.Name.UniqueIdKey;
  916. }
  917. }
  918. if (type is EnumNode && useEnum) type = SystemTypes.Enum;
  919. }
  920. }
  921. }
  922. TypeAlias ta = type as TypeAlias;
  923. while (ta != null) {
  924. type = ta.AliasedType;
  925. ta = type as TypeAlias;
  926. }
  927. type = TypeNode.StripModifiers(type);
  928. if (type is Reference) type = ((Reference)type).ElementType;
  929. if (type == null || type == SystemTypes.Void) return null;
  930. TypeNode referringType = null;
  931. while (scope != null){
  932. TypeScope tScope = scope as TypeScope;
  933. if (tScope != null){
  934. referringType = tScope.Type;
  935. break;
  936. }
  937. scope = scope.OuterScope;
  938. }
  939. Debug.Assert(referringType != SystemTypes.Object);
  940. MemberList result = new MemberList();
  941. bool showPrivate = referringType == type;
  942. bool showFamily = referringType == null || type.IsAssignableTo(referringType) || n is Base;
  943. bool showInternal = this.MayAccessInternals(referringType, type);
  944. this.GetMembers(type, result, staticMembersWanted, allMembersWanted, showPrivate, showFamily, showInternal);
  945. return result;
  946. }
  947. protected virtual Identifier ConvertToNamespaceId(Expression expression){
  948. Identifier id = expression as Identifier;
  949. if (id != null) return Identifier.For(id.Name+".");
  950. NameBinding nb = expression as NameBinding;
  951. if (nb != null) return Identifier.For(nb.Identifier.Name + ".");
  952. QualifiedIdentifier qualId = expression as QualifiedIdentifier;
  953. if (qualId != null) return Identifier.For(this.ConvertToNamespaceId(qualId.Qualifier)+qualId.Identifier.Name+".");
  954. return Identifier.Empty;
  955. }
  956. protected virtual MemberList GetMembers(int line, int col, TemplateInstance templateInstance, Scope scope){
  957. if (templateInstance == null) return null;
  958. return this.FilterOutIncassessibleMembers(templateInstance.BoundMembers, scope);
  959. }
  960. protected virtual MemberList GetMembers(int line, int col, TypeExpression tExpr, Scope scope) {
  961. if (tExpr == null) return null;
  962. MemberList members;
  963. QualifiedIdentifier qual = tExpr.Expression as QualifiedIdentifier;
  964. if (qual != null)
  965. members = this.GetMembers(line, col, qual, scope);
  966. else
  967. members = this.languageService.GetTypesNamespacesAndPrefixes(scope, true, false);
  968. if (members == null) return null;
  969. return this.GetTypesAndNamespacesThatContainThem(members);
  970. }
  971. protected virtual MemberList GetTypesAndNamespacesThatContainThem(MemberList members) {
  972. MemberList result = new MemberList(members.Count);
  973. for (int i = 0, n = members.Count; i < n; i++) {
  974. Member mem = members[i];
  975. if (mem is TypeNode || mem is Namespace)
  976. result.Add(mem);
  977. }
  978. if (result.Count == 0) return null;
  979. return result;
  980. }
  981. protected virtual bool MayAccessInternals(TypeNode referringType, TypeNode referredToType) {
  982. if (referringType == null || referredToType == null) return false;
  983. Module referringModule = referringType.DeclaringModule;
  984. return this.MayAccessInternals(referringModule, referredToType);
  985. }
  986. protected virtual bool MayAccessInternals(Module referringModule, TypeNode referredToType) {
  987. if (referringModule == null || referredToType == null) return false;
  988. Module referredToModule = referredToType.DeclaringModule;
  989. if (referredToModule == null) return false;
  990. if (referringModule == referredToModule) return true;
  991. AssemblyNode referringAssembly = referringModule.ContainingAssembly;
  992. AssemblyNode referredToAssembly = referredToModule.ContainingAssembly;
  993. if (referringAssembly == null) referringAssembly = referringModule as AssemblyNode;
  994. if (referredToAssembly == null) referredToAssembly = referredToModule as AssemblyNode;
  995. if (referringAssembly == null) return referringModule.ContainsModule(referredToModule);
  996. if (referringAssembly == referredToAssembly) return true;
  997. if (referringAssembly.ContainsModule(referringModule)) return true;
  998. return referringAssembly.MayAccessInternalTypesOf(referredToAssembly);
  999. }
  1000. protected virtual void GetMembers(Interface type, MemberList memberList, bool showInternal, NodeType memberKind) {
  1001. if (type == null) return;
  1002. MemberList typeMembers = type.Members;
  1003. for (int i = 0, k = typeMembers == null ? 0 : typeMembers.Count; i < k; i++) {
  1004. Member mem = typeMembers[i];
  1005. if (mem == null) continue;
  1006. if (mem.IsCompilerControlled) continue;
  1007. if (mem.IsPrivate) continue;
  1008. if ((mem.IsAssembly || mem.IsFamilyOrAssembly) && !showInternal) continue;
  1009. if (mem.IsSpecialName && !(mem is InstanceInitializer)) continue;
  1010. if (this.SuppressBecauseItIsADefaultMember(mem, type.DefaultMembers)) continue;
  1011. if (mem.IsAnonymous || this.MemberIsOverriddenOrHidden(mem, memberList)) continue;
  1012. if ((memberKind == NodeType.Event && mem is Event) || (memberKind == NodeType.Method && (mem is Property || mem is Method)))
  1013. memberList.Add(mem);
  1014. }
  1015. for (int i = 0, k = type.Interfaces == null ? 0 : type.Interfaces.Count; i < k; i++) {
  1016. this.GetMembers(type.Interfaces[i], memberList, showInternal, memberKind);
  1017. }
  1018. }
  1019. protected virtual void GetMembers(TypeNode type, MemberList members, bool onlyStaticMembersWanted, bool allMembersWanted, bool showPrivate, bool showFamily, bool showInternal) {
  1020. if (type == null || members == null) return;
  1021. if (type is ArrayType){
  1022. this.GetMembers(SystemTypes.Array, members, onlyStaticMembersWanted, allMembersWanted, showPrivate, showFamily, showInternal);
  1023. return;
  1024. }
  1025. TypeUnion tu = type as TypeUnion;
  1026. if (tu != null){
  1027. TypeNodeList tlist = tu.Types;
  1028. for (int i = 0, n = (tlist == null ? 0 : tlist.Count); i < n; i++){
  1029. TypeNode t = tlist[i] as TypeNode;
  1030. if (t == null) continue;
  1031. this.GetMembers(t, members, onlyStaticMembersWanted, allMembersWanted, showPrivate, showFamily, showInternal);
  1032. }
  1033. return;
  1034. }
  1035. TypeAlias ta = type as TypeAlias;
  1036. if (ta != null){
  1037. this.GetMembers(ta.AliasedType, members, onlyStaticMembersWanted, allMembersWanted, showPrivate, showFamily, showInternal);
  1038. return;
  1039. }
  1040. MemberList typeMembers = type.Members;
  1041. for (int i = 0, k = typeMembers == null ? 0 : typeMembers.Count; i < k; i++){
  1042. Member mem = typeMembers[i];
  1043. if (mem == null) continue;
  1044. if (onlyStaticMembersWanted != mem.IsStatic && !allMembersWanted) continue;
  1045. if (mem.IsCompilerControlled) continue;
  1046. if (mem.IsPrivate && !showPrivate) continue;
  1047. if ((mem.IsFamily || mem.IsFamilyAndAssembly) && !showFamily) continue;
  1048. if ((mem.IsAssembly || mem.IsFamilyOrAssembly) && !showInternal) continue;
  1049. if (mem.IsSpecialName && !(mem is InstanceInitializer)) continue;
  1050. if (this.SuppressBecauseItIsADefaultMember(mem, type.DefaultMembers)) continue;
  1051. if (this.IsTransparent(mem)){
  1052. TypeNode mt = this.GetMemberType(mem);
  1053. TypeNode rt = this.GetRootType(mt);
  1054. this.GetMembers(rt, members, onlyStaticMembersWanted, allMembersWanted, false, false, false);
  1055. }else if (!mem.IsAnonymous && !this.MemberIsOverriddenOrHidden(mem, members)){
  1056. members.Add(mem);
  1057. }
  1058. }
  1059. if (type.BaseType != null && !(type is EnumNode && onlyStaticMembersWanted)){
  1060. this.GetMembers(type.BaseType, members, onlyStaticMembersWanted, allMembersWanted, false, showFamily, showInternal && this.MayAccessInternals(type, type.BaseType));
  1061. }
  1062. if (type is Interface){
  1063. for (int i = 0, k = type.Interfaces == null ? 0 : type.Interfaces.Count; i < k; i++){
  1064. this.GetMembers(type.Interfaces[i], members, allMembersWanted, false, false, false, false);
  1065. }
  1066. this.GetMembers(SystemTypes.Object, members, onlyStaticMembersWanted, allMembersWanted, false, showFamily, showInternal);
  1067. }
  1068. }
  1069. protected virtual bool SuppressBecauseItIsADefaultMember(Member m, MemberList defaultMemberList) {
  1070. for (int i = 0, n = defaultMemberList == null ? 0 : defaultMemberList.Count; i < n; i++) {
  1071. if (m == defaultMemberList[i]) return true;
  1072. }
  1073. return false;
  1074. }
  1075. protected virtual bool MemberIsOverriddenOrHidden(Member mem, MemberList members) {
  1076. if (mem == null || mem.Name == null || members == null){Debug.Assert(false); return true;}
  1077. for (int i = 0, n = members.Count; i < n; i++){
  1078. Member m = members[i];
  1079. if (m == null || m.Name == null || m.Name.UniqueIdKey != mem.Name.UniqueIdKey) continue;
  1080. Method meth1 = m as Method;
  1081. Method meth2 = mem as Method;
  1082. if (meth1 == null || meth2 == null) return true;
  1083. if (meth1.ParametersMatchStructurallyIncludingOutFlag(meth2.Parameters) && meth1.TypeParameterCountsMatch(meth2)) return true;
  1084. }
  1085. if (mem is Method && mem.DeclaringType == SystemTypes.Object && mem.Name != null && mem.Name.UniqueIdKey == StandardIds.Finalize.UniqueIdKey)
  1086. return true;
  1087. return false;
  1088. }
  1089. public virtual TypeNode GetMemberType(Member member){
  1090. Field f = member as Field;
  1091. if (f != null) return f.Type;
  1092. Property p = member as Property;
  1093. if (p != null) return p.Type;
  1094. Method mth = member as Method;
  1095. if (mth != null) return mth.ReturnType;
  1096. return null;
  1097. }
  1098. protected virtual TypeNode GetRootType(TypeNode type){
  1099. return type;
  1100. }
  1101. protected virtual bool IsTransparent(Member member) {
  1102. return false;
  1103. }
  1104. protected virtual Overloads GetConstructors(int line, int col, TypeNode type){
  1105. Node node;
  1106. Scope scope;
  1107. int identContext;
  1108. this.languageService.SearchForNodeAtPosition(line+1, col+1, out node, out scope, out identContext);
  1109. TypeNode referringType = null;
  1110. Module referringModule = null;
  1111. while (scope != null){
  1112. TypeScope tScope = scope as TypeScope;
  1113. if (tScope != null){
  1114. referringType = tScope.Type;
  1115. if (referringType != null){
  1116. referringModule = referringType.DeclaringModule;
  1117. break;
  1118. }
  1119. }
  1120. NamespaceScope nScope = scope as NamespaceScope;
  1121. if (nScope != null){
  1122. referringModule = nScope.AssociatedModule;
  1123. break;
  1124. }
  1125. scope = scope.OuterScope;
  1126. }
  1127. bool showPrivate = referringType == type;
  1128. bool showFamily = referringType != null && referringType.IsAssignableTo(type);
  1129. bool showInternal = this.MayAccessInternals(referringType, type) || this.MayAccessInternals(referringModule, type);
  1130. Member selectedMember = this.GetMember(line, col);
  1131. MemberList members = type == null ? null : type.GetConstructors();
  1132. int positionOfSelectedMember = 0;
  1133. MemberList filteredMembers = new MemberList();
  1134. if (type != null && type.IsValueType){
  1135. //Add dummy default constructor
  1136. InstanceInitializer cons = new InstanceInitializer(type, null, null, null);
  1137. cons.Flags |= MethodFlags.Public;
  1138. filteredMembers.Add(cons);
  1139. }
  1140. for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++){
  1141. Method meth = members[i] as Method;
  1142. if (meth == null) continue;
  1143. if (meth.IsCompilerControlled) continue;
  1144. if (meth.IsPrivate && !showPrivate) continue;
  1145. if ((meth.IsFamily || meth.IsFamilyAndAssembly) && !showFamily) continue;
  1146. if ((meth.IsAssembly || meth.IsFamilyOrAssembly) && !showInternal) continue;
  1147. if (meth == selectedMember) positionOfSelectedMember = filteredMembers.Count;
  1148. filteredMembers.Add(meth);
  1149. }
  1150. if (filteredMembers.Count == 0) return null;
  1151. return new Overloads(filteredMembers, scope, positionOfSelectedMember, this.helper, OverloadKind.Constructors);
  1152. }
  1153. protected virtual Overloads GetDefaultIndexedProperties(int line, int col, Method selectedPropertyGetter, TypeNode declaringType){
  1154. if (declaringType == null) return null;
  1155. Node node;
  1156. Scope scope;
  1157. int identContext;
  1158. this.languageService.SearchForNodeAtPosition(line+1, col+1, out node, out scope, out identContext);
  1159. int positionOfSelectedProperty = 0;
  1160. MemberList properties = new MemberList();
  1161. while (declaringType != null){
  1162. MemberList defMems = declaringType.DefaultMembers;
  1163. defMems = this.FilterOutIncassessibleMembers(defMems, scope);
  1164. for (int i = 0, n = defMems == null ? 0 : defMems.Count; i < n; i++){
  1165. Property prop = defMems[i] as Property;
  1166. if (prop == null) continue;
  1167. if (prop.Getter == selectedPropertyGetter) positionOfSelectedProperty = properties.Count;
  1168. for (int j = 0, m = properties.Count; j < m; j++){
  1169. Property p = (Property)properties[j];
  1170. if (p.ParametersMatch(prop.Parameters)){
  1171. prop = null; break;
  1172. }
  1173. }
  1174. if (prop == null) continue;
  1175. properties.Add(prop);
  1176. }
  1177. declaringType = declaringType.BaseType;
  1178. }
  1179. return new Overloads(properties, scope, positionOfSelectedProperty, this.helper, OverloadKind.Indexer);
  1180. }
  1181. /// <summary>
  1182. /// Called for parameter help.
  1183. /// </summary>
  1184. public virtual Overloads GetGenericMethods(int line, int col, Expression name){
  1185. if (name == null) return null;
  1186. int key = name is Identifier? ((Identifier)name).UniqueIdKey : -1;
  1187. Scope scope;
  1188. Node node;
  1189. Member selectedMember = this.GetMember(line, col);
  1190. MemberList members = this.GetMembers(line, col, ParseReason.MethodTip, out node, out scope);
  1191. int positionOfSelectedMember = 0;
  1192. MemberList filteredMembers = new MemberList();
  1193. for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++){
  1194. Method meth = members[i] as Method;
  1195. if (meth == null) continue;
  1196. if (meth.Template != null) meth = meth.Template;
  1197. if (meth.Name == null) continue;
  1198. if (meth.Name == null || meth.Name.UniqueIdKey != key) continue;
  1199. if (meth.TemplateParameters == null || meth.TemplateParameters.Count == 0) continue;
  1200. if (meth == selectedMember) positionOfSelectedMember = filteredMembers.Count;
  1201. filteredMembers.Add(meth);
  1202. }
  1203. if (filteredMembers.Count == 0) return null;
  1204. return new GenericMethodOverloads(filteredMembers, scope, positionOfSelectedMember, this.helper);
  1205. }
  1206. /// <summary>
  1207. /// Called for parameter help.
  1208. /// </summary>
  1209. public virtual Overloads GetMethods(int line, int col, Expression name) {
  1210. if (name == null) return null;
  1211. string nameStr = null;
  1212. Identifier id = name as Identifier;
  1213. int key = -1;
  1214. if (id != null){
  1215. key = id.UniqueIdKey;
  1216. nameStr = id.Name;
  1217. }
  1218. Scope scope;
  1219. Node node;
  1220. Member selectedMember = this.GetMember(line, col);
  1221. Method selectedMethod = selectedMember as Method;
  1222. MemberList members = this.GetMembers(line, col, ParseReason.MethodTip, out node, out scope);
  1223. int positionOfSelectedMember = 0;
  1224. MemberList filteredMembers = new MemberList();
  1225. OverloadKind olk = (key == StandardIds.Ctor.UniqueIdKey) ? OverloadKind.Constructors : OverloadKind.Methods;
  1226. for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++){
  1227. Method meth = members[i] as Method;
  1228. if (meth == null){
  1229. TypeNode t = members[i] as TypeNode;
  1230. if (t != null){
  1231. Identifier tname = Identifier.For(t.GetUnmangledNameWithoutTypeParameters());
  1232. if (tname == null) continue;
  1233. if (tname.UniqueIdKey != key && selectedMember != (object)t) continue;
  1234. return this.GetConstructors(line, col, t);
  1235. }
  1236. Event ev = members[i] as Event;
  1237. if (ev != null){
  1238. t = ev.HandlerType;
  1239. if (t == null || t.Name == null || t.Name.UniqueIdKey != key) continue;
  1240. MemberList invokers = t.GetMembersNamed(StandardIds.Invoke);
  1241. if (invokers != null && invokers.Count > 0)
  1242. meth = invokers[0] as Method;
  1243. }
  1244. Field f = members[i] as Field;
  1245. if (f != null){
  1246. if (f.Name == null || f.Name.UniqueIdKey != key) continue;
  1247. t = f.Type;
  1248. if (t is DelegateNode){
  1249. MemberList invokers = t.GetMembersNamed(StandardIds.Invoke);
  1250. if (invokers != null && invokers.Count > 0)
  1251. meth = invokers[0] as Method;
  1252. }else if (t is ArrayType)
  1253. return new Overloads(new MemberList(t), scope, 0, this.helper, OverloadKind.Indexer);
  1254. else
  1255. return this.GetDefaultIndexedProperties(line, col, selectedMember as Method, t);
  1256. }
  1257. Property p = members[i] as Property;
  1258. if (p != null && p.DeclaringType.DefaultMembers.Contains(p)) {
  1259. return new Overloads(new MemberList(p), scope, 0, this.helper, OverloadKind.Property);
  1260. }
  1261. if (meth == null) continue;
  1262. key = StandardIds.Invoke.UniqueIdKey;
  1263. }
  1264. Identifier methName = meth.Name;
  1265. if (meth.Template != null) methName = meth.Template.Name;
  1266. if (methName == null || methName.UniqueIdKey != key) {
  1267. if (meth is InstanceInitializer && meth.DeclaringType != null && meth.DeclaringType.IsAssignableTo(SystemTypes.Attribute)){
  1268. olk = OverloadKind.AttributeConstructors;
  1269. if (!(this.suppressAttributeSuffix && meth.DeclaringType.Name != null && meth.DeclaringType.Name.Name != null &&
  1270. meth.DeclaringType.Name.Name.EndsWith("Attribute")
  1271. && meth.DeclaringType.Name.Name.Substring(0, meth.DeclaringType.Name.Name.Length - 9).Equals(nameStr)))
  1272. continue;
  1273. } else
  1274. continue;
  1275. }
  1276. if (meth == selectedMethod){
  1277. positionOfSelectedMember = filteredMembers.Count;
  1278. }else if (selectedMethod != null && selectedMethod.Template == meth){
  1279. meth = selectedMethod; positionOfSelectedMember = filteredMembers.Count;
  1280. }
  1281. filteredMembers.Add(meth);
  1282. }
  1283. if (filteredMembers.Count == 0) return null;
  1284. if (key == StandardIds.Ctor.UniqueIdKey) filteredMembers = this.RemoveBaseClassConstructors(filteredMembers);
  1285. return new Overloads(filteredMembers, scope, positionOfSelectedMember, this.helper, olk);
  1286. }
  1287. protected virtual MemberList RemoveBaseClassConstructors(MemberList constructors){
  1288. MemberList resultList = new MemberList();
  1289. TypeNode mostDerivedType = SystemTypes.Object;
  1290. for (int i = 0, n = constructors == null ? 0 : constructors.Count; i < n; i++){
  1291. InstanceInitializer cons = constructors[i] as InstanceInitializer;
  1292. if (cons == null || cons.DeclaringType == null) continue;
  1293. if (cons.DeclaringType.IsAssignableTo(mostDerivedType)){
  1294. if (mostDerivedType != cons.DeclaringType){
  1295. mostDerivedType = cons.DeclaringType;
  1296. resultList = new MemberList();
  1297. }
  1298. resultList.Add(cons);
  1299. }
  1300. }
  1301. return resultList;
  1302. }
  1303. /// <summary>
  1304. /// Called for parameter help.
  1305. /// </summary>
  1306. public virtual Overloads GetTypes(int line, int col, Expression name) {
  1307. if (name == null) return null;
  1308. int key = name is Identifier? ((Identifier)name).UniqueIdKey : -1;
  1309. string strName = name is Identifier ? ((Identifier)name).Name : null;
  1310. Node node;
  1311. Scope scope;
  1312. int identContext;
  1313. this.languageService.SearchForNodeAtPosition(line + 1, col + 1, out node, out scope, out identContext);
  1314. TypeNode selectedType = null;
  1315. Construct cons = node as Construct;
  1316. if (cons != null)
  1317. selectedType = cons.Type;
  1318. else{
  1319. selectedType = node as TypeNode;
  1320. if (selectedType == null) return this.GetGenericMethods(line, col, name);
  1321. }
  1322. if (selectedType == null || scope == null) return null;
  1323. MemberList members = this.languageService.GetTypesNamespacesAndPrefixes(scope, false, true);
  1324. int positionOfSelectedMember = 0;
  1325. MemberList filteredMembers = new MemberList();
  1326. for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++){
  1327. TypeNode t = members[i] as TypeNode;
  1328. if (t == null) continue;
  1329. if (t.GetUnmangledNameWithoutTypeParameters() != strName) continue;
  1330. if (t.TemplateParameters == null || t.TemplateParameters.Count == 0) continue;
  1331. if (t == selectedType) positionOfSelectedMember = filteredMembers.Count;
  1332. filteredMembers.Add(t);
  1333. }
  1334. if (filteredMembers.Count == 0) return null;
  1335. return new Overloads(filteredMembers, scope, positionOfSelectedMember, this.helper, OverloadKind.GenericTypes);
  1336. }
  1337. }
  1338. public class Declarations{
  1339. public Member[] members;
  1340. public int[] overloads;
  1341. public AuthoringHelper helper;
  1342. public string displayTextForLastGetBestMatch;
  1343. public bool diplayTextMayDifferFromInsertionText;
  1344. public int initialMatch = -1;
  1345. public Node node;
  1346. public Scope scope;
  1347. public Declarations(MemberList memberList, AuthoringHelper helper, Node node, Scope scope){
  1348. this.node = node;
  1349. this.scope = scope;
  1350. this.displayTextForLastGetBestMatch = "";
  1351. this.helper = helper;
  1352. if (memberList == null || memberList.Count == 0) {
  1353. this.members = new Member[0];
  1354. this.helper = helper;
  1355. return;
  1356. }
  1357. Identifier tName = null;
  1358. TypeNode t = memberList[memberList.Count - 1] as TypeNode;
  1359. if (t != null)
  1360. tName = (t.Template == null) ? t.Name : t.Template.Name;
  1361. Member lastMemb = memberList[memberList.Count - 1];
  1362. if (lastMemb == null)
  1363. memberList.RemoveAt(memberList.Count - 1);
  1364. Member[] members = memberList.ToArray();
  1365. Array.Sort(members, this.GetMemberComparer(helper.culture)); //REVIEW: perhaps get it from helper?
  1366. MemberList memberList1 = new MemberList();
  1367. this.overloads = new int[members.Length];
  1368. String memberName = null;
  1369. bool doneAddingPreselection = !((node is Construct) || (node is Identifier)) || lastMemb == null;
  1370. int j = 0;
  1371. for (int i = 0; i < members.Length;){
  1372. Member mem = members[i];
  1373. if (mem == null){ i++; continue;}
  1374. if (mem.IsSpecialName || mem.FilterPriority == System.ComponentModel.EditorBrowsableState.Never){i++; continue;}
  1375. memberName = helper.GetMemberName(mem);
  1376. if (memberName == null || memberName.Length == 0){i++; continue;}
  1377. if (!doneAddingPreselection && mem.Name != null && tName != null && mem.Name.UniqueIdKey == tName.UniqueIdKey) {
  1378. this.initialMatch = memberList1.Count;
  1379. if (t != null && t.Template != null) { // t is implicitly not null since tName is not null but it's safer to check anyway.
  1380. memberList1.Add(t);
  1381. doneAddingPreselection = true;
  1382. if (t == (mem as TypeNode)) { i++; j++; continue; }
  1383. }
  1384. } else if (t != null && t == (mem as TypeNode) && t.Template != null) { // TODO: Perhaps check doneAddingPreselection here as well?
  1385. if (this.initialMatch >= 0) { i++; continue; }
  1386. this.initialMatch = memberList1.Count;
  1387. doneAddingPreselection = true;
  1388. } else if (!doneAddingPreselection && lastMemb == mem) {
  1389. if (this.initialMatch >= 0) { i++; continue; }
  1390. this.initialMatch = memberList1.Count;
  1391. doneAddingPreselection = true;
  1392. }
  1393. memberList1.Add(mem);
  1394. i++;
  1395. while (i < members.Length && helper.GetMemberName(members[i]) == memberName){
  1396. if (t != (members[i] as TypeNode) || (t == null && members[i] != null)) this.overloads[j]++;
  1397. i++;
  1398. }
  1399. j++;
  1400. }
  1401. members = memberList1.ToArray();
  1402. this.members = members;
  1403. }
  1404. public IComparer GetMemberComparer(CultureInfo culture){
  1405. return new MemberComparer();
  1406. }
  1407. private class MemberComparer : IComparer{
  1408. public int Compare(Object a, Object b){
  1409. TypeNode ta = a as TypeNode;
  1410. TypeNode tb = b as TypeNode;
  1411. string sa = ta == null ? ((Member)a).Name.Name : ta.GetUnmangledNameWithoutTypeParameters();
  1412. string sb = tb == null ? ((Member)b).Name.Name : tb.GetUnmangledNameWithoutTypeParameters();
  1413. int result = string.Compare(sa, sb, false, CultureInfo.InvariantCulture);
  1414. if (result == 0 && ta != null && tb != null) {
  1415. if ((ta.TemplateParameters == null || ta.TemplateParameters.Count == 0) && tb.TemplateParameters != null && tb.TemplateParameters.Count > 0)
  1416. return -1;
  1417. if ((tb.TemplateParameters == null || tb.TemplateParameters.Count == 0) && ta.TemplateParameters != null && ta.TemplateParameters.Count > 0)
  1418. return 1;
  1419. }
  1420. if (result == 0 && a is Method && b is Method) {
  1421. Method ma = (Method)a;
  1422. Method mb = (Method)b;
  1423. if ((ma.TemplateParameters == null || ma.TemplateParameters.Count == 0) && mb.TemplateParameters != null && mb.TemplateParameters.Count > 0)
  1424. return -1;
  1425. if ((mb.TemplateParameters == null || mb.TemplateParameters.Count == 0) && ma.TemplateParameters != null && ma.TemplateParameters.Count > 0)
  1426. return 1;
  1427. }
  1428. return result;
  1429. }
  1430. }
  1431. public virtual int GetCount(){
  1432. return this.members.Length;
  1433. }
  1434. public virtual void GetBestMatch(string text, out int index, out bool uniqueMatch){
  1435. if (this.initialMatch >= 0){
  1436. index = this.initialMatch;
  1437. uniqueMatch = false;
  1438. this.initialMatch = -1;
  1439. return;
  1440. }
  1441. index = 0;
  1442. uniqueMatch = false;
  1443. this.displayTextForLastGetBestMatch = "";
  1444. if (text != null){
  1445. int len = text.Length;
  1446. index = -1;
  1447. for (int i = 0; i < this.members.Length; i++){
  1448. if (string.Compare(this.GetDisplayText(this.members[i]), 0, text, 0, len, true) == 0){
  1449. if (index == -1){
  1450. index = i;
  1451. uniqueMatch = true;
  1452. }else
  1453. uniqueMatch = false;
  1454. }
  1455. }
  1456. if (!uniqueMatch){
  1457. int index2 = -1;
  1458. for (int i = 0; i < this.members.Length; i++){
  1459. if (string.Compare(this.GetDisplayText(this.members[i]), 0, text, 0, len, false) == 0){
  1460. if (index2 == -1){
  1461. index2 = i;
  1462. uniqueMatch = true;
  1463. }else
  1464. uniqueMatch = false;
  1465. }
  1466. }
  1467. if (index2 != -1) index = index2;
  1468. }
  1469. if (index != -1) return;
  1470. }
  1471. if (text == null || text.Length == 0){
  1472. //TODO: provide an extensibility point that can be used to select the most recently used member
  1473. //TODO: find out what algorithm C# uses.
  1474. uniqueMatch = false;
  1475. index = 0;
  1476. // no match found - return S_FALSE
  1477. COMException ce = new COMException("", unchecked((int)0x00000001));
  1478. throw ce;
  1479. }
  1480. //Get here if text is not a prefix to any of the members' display texts
  1481. this.displayTextForLastGetBestMatch = text;
  1482. index = this.members.Length;
  1483. uniqueMatch = true;
  1484. return;
  1485. }
  1486. protected virtual string GetDisplayText(Member m){
  1487. TypeNode t = m as TypeNode;
  1488. if (t != null) {
  1489. if (this.diplayTextMayDifferFromInsertionText || this.helper.SuppressAttributeSuffix)
  1490. return this.helper.GetMemberName(t);
  1491. else if (t.TemplateParameters != null && t.TemplateParameters.Count > 0)
  1492. return t.GetUnmangledNameWithoutTypeParameters() + "<>";
  1493. else if (t.Template != null && (t.TemplateArguments == null || t.TemplateArguments.Count == 0))
  1494. return this.GetDisplayText(t.Template);
  1495. else
  1496. return this.helper.GetMemberName(t);
  1497. }
  1498. Method meth = m as Method;
  1499. if (meth != null) {
  1500. if ((meth.TemplateParameters != null && meth.TemplateParameters.Count > 0) || (meth.TemplateArguments != null && meth.TemplateArguments.Count > 0))
  1501. return meth.GetUnmangledNameWithoutTypeParameters(true) + "<>";
  1502. return meth.GetUnmangledNameWithoutTypeParameters(true);
  1503. }
  1504. if (m.Name == null) return " ";
  1505. return m.Name.ToString();
  1506. }
  1507. public virtual string GetDisplayText(int index){
  1508. if (index == this.members.Length) return this.displayTextForLastGetBestMatch;
  1509. string name = this.GetDisplayText(this.members[index]);
  1510. if (name == null) name = " ";
  1511. return name;
  1512. }
  1513. public virtual string GetDescription(int index){
  1514. if (index == this.members.Length) return " ";
  1515. return this.helper.GetDescription(this.members[index], this.overloads[index]);
  1516. }
  1517. protected virtual string GetInsertionText(Member m) {
  1518. TypeNode t = m as TypeNode;
  1519. if (t != null && t.TemplateParameters != null && t.TemplateParameters.Count > 0)
  1520. return t.GetUnmangledNameWithoutTypeParameters();
  1521. Method meth = m as Method;
  1522. if (meth != null)
  1523. return meth.GetUnmangledNameWithoutTypeParameters(true);
  1524. return this.GetDisplayText(m);
  1525. }
  1526. public virtual string GetInsertionText(int index){
  1527. if (index == this.members.Length) return this.displayTextForLastGetBestMatch;
  1528. string name = this.GetInsertionText(this.members[index]);
  1529. if (name == null) name = " ";
  1530. return name;
  1531. }
  1532. public virtual Member GetMember(int index){
  1533. if (index == this.members.Length) index = 0;
  1534. return this.members[index];
  1535. }
  1536. public virtual bool IsCommitChar(string textSoFar, char commitChar){
  1537. // if the char is in the list of given member names then obviously it
  1538. // is not a commit char.
  1539. int i = (textSoFar == null) ? 0 : textSoFar.Length;
  1540. for (int j = 0, n = this.members.Length; j < n; j++){
  1541. Member m = this.members[j];
  1542. string name = m.Name.ToString();
  1543. if (name.Length > i+1 && name[i] == commitChar){
  1544. if (i == 0 || String.Compare(name.Substring(0,i), textSoFar, true, this.helper.culture) == 0){
  1545. return false; // cannot be a commit char if it is an expected char in a matching name
  1546. }
  1547. }
  1548. }
  1549. return !(Char.IsLetterOrDigit(commitChar) || commitChar == '_');
  1550. }
  1551. }
  1552. public enum OverloadKind {
  1553. Methods = 0x0001,
  1554. Constructors = 0x0002,
  1555. AttributeConstructors = 0x0004,
  1556. Indexer = 0x0008,
  1557. Property = 0x0010,
  1558. GenericTypes = 0x0020,
  1559. GenericMethods = 0x0040,
  1560. Any = OverloadKind.Methods | OverloadKind.Constructors | OverloadKind.AttributeConstructors | OverloadKind.Indexer
  1561. | OverloadKind.Property | OverloadKind.GenericTypes | OverloadKind.GenericMethods,
  1562. }
  1563. public class Overloads{
  1564. public MemberList members;
  1565. public Scope scope;
  1566. protected AuthoringHelper helper;
  1567. public int positionOfSelectedMember;
  1568. public OverloadKind OverloadKind;
  1569. public Overloads(MemberList members, Scope scope, int positionOfSelectedMember, AuthoringHelper helper, OverloadKind kind){
  1570. this.members = members;
  1571. this.scope = scope;
  1572. this.helper = helper;
  1573. this.positionOfSelectedMember = positionOfSelectedMember;
  1574. this.OverloadKind = kind;
  1575. }
  1576. public Overloads(Overloads overloads)
  1577. : this(overloads.members, overloads.scope, overloads.positionOfSelectedMember, overloads.helper, overloads.OverloadKind) {
  1578. }
  1579. public virtual string GetName(int index){
  1580. TypeNode t = this.members[index] as TypeNode;
  1581. if (t is ArrayType) return "";
  1582. if (t != null) return t.GetFullUnmangledNameWithoutTypeParameters();
  1583. Property p = this.members[index] as Property;
  1584. if (p != null && p.DeclaringType != null) return p.DeclaringType.GetFullUnmangledNameWithTypeParameters();
  1585. string st = this.helper.ErrorHandler.GetMemberName(this.members[index]);
  1586. return st;
  1587. }
  1588. public virtual int GetCount(){
  1589. int ret = this.members == null ? 0 : this.members.Count;
  1590. return ret;
  1591. }
  1592. public virtual int GetPositionOfSelectedMember(){
  1593. return this.positionOfSelectedMember;
  1594. }
  1595. public virtual string GetDescription(int index){
  1596. string st;
  1597. Member m = this.members[index];
  1598. st = this.helper.GetDescription(m, 0);
  1599. return st;
  1600. }
  1601. public virtual string GetHelpText(int index){
  1602. string st = this.members[index].HelpText;
  1603. return st;
  1604. }
  1605. public virtual string GetSignature(int index) {
  1606. string st = this.helper.GetSignature(this.members[index], this.scope);
  1607. return st;
  1608. }
  1609. public virtual string GetType(int index){
  1610. string st;
  1611. Member m = this.members[index];
  1612. if (m is InstanceInitializer || m is StaticInitializer)
  1613. st = "";
  1614. else if (m is Method)
  1615. st = this.helper.ErrorHandler.GetTypeName(((Method)m).ReturnType);
  1616. else if (m is Property)
  1617. st = this.helper.ErrorHandler.GetTypeName(((Property)m).Type);
  1618. else if (m is ArrayType)
  1619. st = this.helper.ErrorHandler.GetTypeName(((ArrayType)m).ElementType);
  1620. else
  1621. st = "";
  1622. int l = st.Length;
  1623. if (l > 53){
  1624. st = st.Substring(0,30) + "..." + st.Substring(l-20,20);
  1625. }
  1626. return st;
  1627. }
  1628. public virtual int GetParameterCount(int index){
  1629. Member m = this.members[index];
  1630. TypeNode t = m as TypeNode;
  1631. if (t != null && t.TemplateParameters != null)
  1632. return t.TemplateParameters.Count;
  1633. ParameterList parameters = null;
  1634. if (m is Method)
  1635. parameters = ((Method)m).Parameters;
  1636. else if (m is Property)
  1637. parameters = ((Property)m).Parameters;
  1638. else if (m is ArrayType)
  1639. return ((ArrayType)m).Rank;
  1640. if (parameters == null) return 0;
  1641. return parameters.Count;
  1642. }
  1643. public virtual void GetParameterInfo(int index, int parameter, out string name, out string display, out string description){
  1644. name = "";
  1645. description = "";
  1646. display = "";
  1647. Member m = this.members[index];
  1648. TypeNode t = m as TypeNode;
  1649. if (t != null){
  1650. if (t is ArrayType) return;
  1651. if (t.TemplateParameters != null && parameter >= 0 && parameter < t.TemplateParameters.Count){
  1652. TypeNode p = t.TemplateParameters[parameter];
  1653. if (p != null){
  1654. name = p.Name == null ? "" : p.Name.Name;
  1655. display = name;
  1656. description = p.HelpText;
  1657. }
  1658. return;
  1659. }
  1660. }
  1661. ParameterList parameters = null;
  1662. if (m is Method)
  1663. parameters = ((Method)m).Parameters;
  1664. else if (m is Property)
  1665. parameters = ((Property)m).Parameters;
  1666. if (parameters != null && parameter >= 0 && parameter < parameters.Count){
  1667. Parameter p = parameters[parameter];
  1668. name = p.Name == null ? "" : p.Name.Name;
  1669. display = this.helper.GetParameterDescription(p, this.scope);
  1670. description = m.GetParameterHelpText(name);
  1671. if (description != null) description = name + ": " + description;
  1672. }
  1673. }
  1674. public virtual string GetParameterClose(int index){
  1675. Member mem = this.members[index];
  1676. if (mem is Property || mem is ArrayType)
  1677. return "]";
  1678. else if (mem is TypeNode)
  1679. return ">";
  1680. else
  1681. return ")";
  1682. }
  1683. public virtual string GetParameterOpen(int index){
  1684. Member mem = this.members[index];
  1685. if (mem is Property || mem is ArrayType)
  1686. return "[";
  1687. else if (mem is TypeNode)
  1688. return "<";
  1689. else
  1690. return "(";
  1691. }
  1692. public string GetParameterSeparator(int index){
  1693. if (this.members[index] is ArrayType) return ",";
  1694. return ", ";
  1695. }
  1696. }
  1697. public class GenericMethodOverloads : Overloads {
  1698. public GenericMethodOverloads(MemberList members, Scope scope, int positionOfSelectedMember, AuthoringHelper helper)
  1699. : base(members, scope, positionOfSelectedMember, helper, OverloadKind.GenericMethods)
  1700. {
  1701. }
  1702. public override string GetName(int index){
  1703. Method m = this.members[index] as Method;
  1704. if (m != null)
  1705. return this.helper.GetFullMethodName(m);
  1706. return null;
  1707. }
  1708. public override string GetParameterClose(int index) {
  1709. Method m = this.members[index] as Method;
  1710. if (m != null)
  1711. return ">"+this.helper.GetParameterString(m);
  1712. return null;
  1713. }
  1714. public override int GetParameterCount(int index){
  1715. Member m = this.members[index];
  1716. TypeNodeList tparams = null;
  1717. if (m is Method)
  1718. tparams = ((Method)m).TemplateParameters;
  1719. if (tparams == null) return 0;
  1720. return tparams.Count;
  1721. }
  1722. public override void GetParameterInfo(int index, int parameter, out string name, out string display, out string description){
  1723. name = "";
  1724. description = "";
  1725. display = "";
  1726. TypeNodeList tparams = null;
  1727. Member m = this.members[index];
  1728. if (m is Method)
  1729. tparams = ((Method)m).TemplateParameters;
  1730. if (tparams != null && parameter >= 0 && parameter < tparams.Count){
  1731. TypeNode tp = tparams[parameter];
  1732. if (tp != null){
  1733. name = tp.Name == null ? "" : tp.Name.Name;
  1734. display = name;
  1735. description = tp.HelpText;
  1736. }
  1737. }
  1738. }
  1739. public override string GetParameterOpen(int method){
  1740. return "<";
  1741. }
  1742. }
  1743. public abstract class AuthoringSink{
  1744. public abstract void AddCollapsibleRegion(SourceContext context, bool collapsed);
  1745. /// <summary>
  1746. /// Whenever a matching pair is parsed, e.g. '{' and '}', this method is called
  1747. /// with the text span of both the left and right item. The
  1748. /// information is used when a user types "ctrl-]" in VS
  1749. /// to find a matching brace and when auto-highlight matching
  1750. /// braces is enabled.
  1751. /// </summary>
  1752. public abstract void MatchPair(SourceContext startContext, SourceContext endContext);
  1753. /// <summary>
  1754. /// Matching tripples are used to highlight in bold a completed statement. For example
  1755. /// when you type the closing brace on a foreach statement VS highlights in bold the statement
  1756. /// that was closed. The first two source contexts are the beginning and ending of the statement that
  1757. /// opens the block (for example, the span of the "foreach(...){" and the third source context
  1758. /// is the closing brace for the block (e.g., the "}").
  1759. /// </summary>
  1760. public abstract void MatchTriple(SourceContext startContext, SourceContext middleContext, SourceContext endContext);
  1761. /// <summary>
  1762. /// In support of Member Selection, CompleteWord, QuickInfo,
  1763. /// MethodTip, and Autos, the StartName and QualifyName methods
  1764. /// are called.
  1765. /// StartName is called for each identifier that is parsed (e.g. "Console")
  1766. /// Its type is Expression since it can be this/base etc
  1767. /// </summary>
  1768. public abstract void StartName(Expression name);
  1769. /// <summary>
  1770. /// QualifyName is called for each qualification with both
  1771. /// the text span of the selector (e.g. ".") and the text span
  1772. /// of the name ("WriteLine").
  1773. /// </summary>
  1774. public abstract void QualifyName(SourceContext selectorContext, Expression name);
  1775. /// <summary>
  1776. /// AutoExpression is in support of IVsLanguageDebugInfo.GetProximityExpressions.
  1777. /// It is called for each expression that might be interesting for
  1778. /// a user in the "Auto Debugging" window. All names that are
  1779. /// set using StartName and QualifyName are already automatically
  1780. /// added to the "Auto" window! This means that AutoExpression
  1781. /// is rarely used.
  1782. /// </summary>
  1783. public abstract void AutoExpression(SourceContext exprContext);
  1784. /// <summary>
  1785. /// CodeSpan is in support of IVsLanguageDebugInfo.ValidateBreakpointLocation.
  1786. /// It is called for each region that contains "executable" code.
  1787. /// This is used to validate breakpoints. Comments are
  1788. /// automatically taken care of based on TokenInfo returned from scanner.
  1789. /// Normally this method is called when a procedure is started/ended.
  1790. /// </summary>
  1791. public abstract void CodeSpan(SourceContext spanContext);
  1792. /// <summary>
  1793. /// The StartParameters, Parameter and EndParameter methods are
  1794. /// called in support of method tip intellisense (ECMD_PARAMINFO).
  1795. /// [StartParameters] is called when the parameters of a method
  1796. /// are started, ie. "(".
  1797. /// [NextParameter] is called on the start of a new parameter, ie. ",".
  1798. /// [EndParameter] is called on the end of the paramters, ie. ")".
  1799. /// REVIEW: perhaps this entire scheme should go away
  1800. /// </summary>
  1801. public abstract void StartParameters(SourceContext context);
  1802. /// <summary>
  1803. /// NextParameter is called after StartParameters on the start of each new parameter, ie. ",".
  1804. /// </summary>
  1805. public abstract void NextParameter(SourceContext context);
  1806. /// <summary>
  1807. /// EndParameter is called on the end of the paramters, ie. ")".
  1808. /// </summary>
  1809. public abstract void EndParameters(SourceContext context);
  1810. public abstract void StartTemplateParameters(SourceContext context);
  1811. public abstract void NextTemplateParameter(SourceContext context);
  1812. public abstract void EndTemplateParameters(SourceContext context);
  1813. /// <summary>
  1814. /// Send a message to the development enviroment. The kind of message
  1815. /// is specified through the given severity.
  1816. /// </summary>
  1817. public abstract void AddError(ErrorNode node);
  1818. // public abstract SourceContext RegionToClear{get; set;}
  1819. }
  1820. public class AuthoringHelper{
  1821. public ErrorHandler ErrorHandler;
  1822. public CultureInfo culture;
  1823. public bool SuppressAttributeSuffix;
  1824. public AuthoringHelper(ErrorHandler errorHandler, CultureInfo culture){
  1825. this.ErrorHandler = errorHandler;
  1826. this.culture = culture;
  1827. }
  1828. public virtual String GetDescription(Member member){
  1829. return this.GetDescription(member, 0);
  1830. }
  1831. public virtual String GetDescription(Member member, int overloads){
  1832. StringBuilder descr = new StringBuilder(this.ErrorHandler.GetMemberSignature(member, true));
  1833. if (overloads > 0){
  1834. descr.Append(" (+ ");
  1835. descr.Append(overloads.ToString());
  1836. if (member is TypeNode) descr.Append(" generic");
  1837. descr.Append(overloads == 1 ? " overload" : " overloads"); //TODO: globalize this
  1838. descr.Append(")");
  1839. }
  1840. string helpText = member.HelpText;
  1841. if (helpText != null && helpText.Length > 0){
  1842. descr.Append("\n");
  1843. descr.Append(helpText);
  1844. }
  1845. return descr.ToString();
  1846. }
  1847. public virtual string GetSignature(Member member, Scope scope){
  1848. return this.ErrorHandler.GetMemberSignature(member, true);
  1849. }
  1850. public virtual string GetFullMethodName(Method method){
  1851. if (method == null || method.DeclaringType == null) return null;
  1852. return method.DeclaringType.GetFullUnmangledNameWithTypeParameters()+"."+method.Name;
  1853. }
  1854. public virtual string GetFullTypeName(TypeNode type){
  1855. return this.ErrorHandler.GetTypeName(type);
  1856. }
  1857. public virtual string GetMemberName(Member member){
  1858. TypeNode t = member as TypeNode;
  1859. if (t != null){
  1860. string name = t.GetUnmangledNameWithoutTypeParameters();
  1861. if (this.SuppressAttributeSuffix && name.EndsWith("Attribute"))
  1862. return name.Substring(0, name.Length-9);
  1863. else if (t.TemplateParameters != null && t.TemplateParameters.Count > 0)
  1864. return name+"<>";
  1865. else if (t.TemplateArguments != null && t.TemplateArguments.Count > 0)
  1866. return this.ErrorHandler.GetUnqualifiedTypeName(t);
  1867. return name;
  1868. }
  1869. Method meth = member as Method;
  1870. if (meth != null && meth.TemplateParameters != null && meth.TemplateParameters.Count > 0)
  1871. return meth.Name.Name+"<>";
  1872. if (member == null || member.Name == null) return " ";
  1873. return member.Name.Name;
  1874. }
  1875. public virtual string GetParameterDescription(Parameter parameter, Scope scope){
  1876. StringBuilder descr = new StringBuilder(this.ErrorHandler.GetParameterTypeName(parameter));
  1877. descr.Append(' ');
  1878. descr.Append(parameter.Name);
  1879. return descr.ToString();
  1880. }
  1881. public virtual string GetParameterString(Method method){
  1882. return this.ErrorHandler.GetSignatureString("", method.Parameters, "(", ")", ", ", true);
  1883. }
  1884. }
  1885. /// <summary>
  1886. /// Represents the two drop down bars on the top of a text editor window that allow types and type members to be selected by name.
  1887. /// </summary>
  1888. public class TypeAndMemberDropdownBars{
  1889. /// <summary>The language service object that created this object and calls its SynchronizeDropdowns method</summary>
  1890. public LanguageService languageService;
  1891. /// <summary>The list of types that appear in the type drop down list. Sorted by full type name.</summary>
  1892. public TypeNodeList sortedDropDownTypes;
  1893. /// <summary>The list of types that appear in the type drop down list. Textual order.</summary>
  1894. private TypeNodeList dropDownTypes;
  1895. /// <summary>The list of members that appear in the member drop down list. Sorted by name.</summary>
  1896. private MemberList dropDownMembers;
  1897. /// <summary>The list of members that appear in the member drop down list. Textual order.</summary>
  1898. public MemberList sortedDropDownMembers;
  1899. public string[] dropDownMemberSignatures;
  1900. // public int[] dropDownTypeGlyphs;
  1901. // public int[] dropDownMemberGlyphs;
  1902. public int selectedType = -1;
  1903. public int selectedMember = -1;
  1904. private const int DropClasses = 0;
  1905. private const int DropMethods = 1;
  1906. public TypeAndMemberDropdownBars(LanguageService languageService){
  1907. this.languageService = languageService;
  1908. }
  1909. /// <summary>
  1910. /// Updates the state of the drop down bars to match the current contents of the text editor window. Call this initially and every time
  1911. /// the cursor position changes.
  1912. /// </summary>
  1913. /// <param name="textView">The editor window</param>
  1914. /// <param name="line">The line on which the cursor is now positioned</param>
  1915. /// <param name="col">The column on which the cursor is now position</param>
  1916. public void SynchronizeDropdowns(string fname, int line, int col){
  1917. Compilation compilation = this.languageService.GetCompilationFor(fname);
  1918. if (compilation == null){Debug.Assert(false); return;}
  1919. CompilationUnit cu = this.languageService.GetCompilationUnitSnippet(compilation, fname);
  1920. if (cu == null || cu.Nodes == null || cu.Nodes.Count == 0 || !(cu.Nodes[0] is Namespace)) return;
  1921. AuthoringHelper helper = this.languageService.GetAuthoringHelper();
  1922. TypeNodeList types = this.dropDownTypes;
  1923. TypeNodeList sortedTypes = this.sortedDropDownTypes;
  1924. //Need to reconstruct the type lists. First get the types in text order.
  1925. types = this.dropDownTypes = new TypeNodeList();
  1926. this.PopulateTypeList(types, (Namespace)cu.Nodes[0]);
  1927. //Now sort by full text name.
  1928. int n = types.Count;
  1929. if (n == 0) return;
  1930. sortedTypes = this.sortedDropDownTypes = new TypeNodeList(n);
  1931. for (int i = 0; i < n; i++){
  1932. TypeNode t = types[i];
  1933. if (t == null){Debug.Assert(false); continue;}
  1934. string tName = helper.GetMemberName(t);
  1935. sortedTypes.Add(t);
  1936. for (int j = sortedTypes.Count-2; j >= 0; j--){
  1937. if (string.Compare(tName, helper.GetMemberName(sortedTypes[j]), true, System.Globalization.CultureInfo.InvariantCulture) >= 0) break;
  1938. sortedTypes[j+1] = sortedTypes[j];
  1939. sortedTypes[j] = t;
  1940. }
  1941. }
  1942. this.selectedType = -1;
  1943. //Find the type matching the given source position
  1944. int newType = 0;
  1945. int candidateType = -1;
  1946. for (int i = 0; i < n; i++){
  1947. TypeNode t = types[i];
  1948. if (t == null) continue;
  1949. if (t.SourceContext.Document == null) continue;
  1950. if (t.SourceContext.Encloses(line+1, col+1)) candidateType = i;
  1951. if (t.SourceContext.StartLine > line+1 || (t.SourceContext.StartLine == line+1 && t.SourceContext.StartColumn > col+1)){
  1952. if (candidateType == -1) candidateType = 0;
  1953. t = types[candidateType];
  1954. }else if (i < n-1)
  1955. continue;
  1956. else{
  1957. if (candidateType == -1) candidateType = 0;
  1958. t = types[candidateType];
  1959. }
  1960. for (int j = 0; j < n; j++){
  1961. if (sortedTypes[j] != t) continue;
  1962. newType = j;
  1963. break;
  1964. }
  1965. break;
  1966. }
  1967. MemberList members = this.dropDownMembers;
  1968. MemberList sortedMembers = this.sortedDropDownMembers;
  1969. if (newType != this.selectedType){
  1970. if (newType < 0 || newType > sortedTypes.Count) return;
  1971. TypeNode t = sortedTypes[newType];
  1972. if (t == null || t.Members == null) return;
  1973. //Need to reconstruct the member list. First get the members in text order.
  1974. members = t.Members;
  1975. n = members == null ? 0 : members.Count;
  1976. MemberList newMembers = this.dropDownMembers = new MemberList(n);
  1977. //Now sort them
  1978. sortedMembers = this.sortedDropDownMembers = new MemberList(n);
  1979. string[] memSignatures = this.dropDownMemberSignatures = new string[n];
  1980. for (int i = 0; i < n; i++){
  1981. Member mem = members[i];
  1982. if (mem == null) continue;
  1983. if (mem.SourceContext.Document == null) continue;
  1984. string memSignature = this.languageService.errorHandler.GetUnqualifiedMemberSignature(mem);
  1985. if (memSignature == null) continue;
  1986. memSignatures[sortedMembers.Count] = memSignature;
  1987. newMembers.Add(mem);
  1988. sortedMembers.Add(mem);
  1989. for (int j = sortedMembers.Count - 2; j >= 0; j--){
  1990. if (string.Compare(memSignature, memSignatures[j], true, System.Globalization.CultureInfo.InvariantCulture) >= 0) break;
  1991. memSignatures[j+1] = memSignatures[j];
  1992. memSignatures[j] = memSignature;
  1993. sortedMembers[j+1] = sortedMembers[j];
  1994. sortedMembers[j] = mem;
  1995. }
  1996. }
  1997. this.selectedMember = -1;
  1998. }
  1999. //Find the member matching the given source position
  2000. members = this.dropDownMembers;
  2001. int newMember = 0;
  2002. n = sortedMembers.Count;
  2003. for (int i = 0; i < n; i++){
  2004. Member mem = members[i];
  2005. if (mem == null) continue;
  2006. if (mem.SourceContext.StartLine > line+1 || (mem.SourceContext.StartLine == line+1 && mem.SourceContext.StartColumn > col+1)){
  2007. if (i > 0) mem = members[i-1];
  2008. }else if (i < n-1)
  2009. continue;
  2010. for (int j = 0; j < n; j++){
  2011. if (sortedMembers[j] != mem) continue;
  2012. newMember = j;
  2013. break;
  2014. }
  2015. break;
  2016. }
  2017. this.selectedType = newType;
  2018. this.selectedMember = newMember;
  2019. }
  2020. public void PopulateTypeList(TypeNodeList types, Namespace ns){
  2021. if (types == null || ns == null){Debug.Assert(false); return;}
  2022. if (ns.NestedNamespaces != null)
  2023. this.PopulateTypeList(types, ns.NestedNamespaces);
  2024. TypeNodeList nTypes = ns.Types;
  2025. for (int j = 0, m = nTypes == null ? 0 : nTypes.Count; j < m; j++){
  2026. TypeNode t = nTypes[j];
  2027. if (t == null) continue;
  2028. if ((t.Flags & TypeFlags.SpecialName) != 0) continue;
  2029. this.PopulateTypeList(types, t);
  2030. }
  2031. }
  2032. public void PopulateTypeList(TypeNodeList types, NamespaceList namespaces){
  2033. if (types == null){Debug.Assert(false); return;}
  2034. for (int i = 0, n = namespaces == null ? 0 : namespaces.Count; i < n; i++){
  2035. Namespace ns = namespaces[i];
  2036. if (ns == null) continue;
  2037. if (ns.NestedNamespaces != null)
  2038. this.PopulateTypeList(types, ns.NestedNamespaces);
  2039. TypeNodeList nTypes = ns.Types;
  2040. for (int j = 0, m = nTypes == null ? 0 : nTypes.Count; j < m; j++){
  2041. TypeNode t = nTypes[j];
  2042. if (t == null) continue;
  2043. this.PopulateTypeList(types, t);
  2044. }
  2045. }
  2046. }
  2047. public void PopulateTypeList(TypeNodeList types, TypeNode t){
  2048. if (types == null || t == null){Debug.Assert(false); return;}
  2049. types.Add(t);
  2050. MemberList members = t.Members;
  2051. for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++){
  2052. t = members[i] as TypeNode;
  2053. if (t == null) continue;
  2054. this.PopulateTypeList(types, t);
  2055. }
  2056. }
  2057. }
  2058. }