/O2_SharpDevelop/NRefactory/Project/Src/Visitors/LookupTableVisitor.cs

http://github.com/o2platform/O2.Platform.Projects · C# · 319 lines · 274 code · 36 blank · 9 comment · 45 complexity · 507267b6c7f4f399688bbcc1b56ef7fd MD5 · raw file

  1. // <file>
  2. // <copyright see="prj:///doc/copyright.txt"/>
  3. // <license see="prj:///doc/license.txt"/>
  4. // <owner name="none" email=""/>
  5. // <version>$Revision: 4527 $</version>
  6. // </file>
  7. using System;
  8. using System.Collections.Generic;
  9. using ICSharpCode.NRefactory.Ast;
  10. namespace ICSharpCode.NRefactory.Visitors
  11. {
  12. public sealed class LocalLookupVariable
  13. {
  14. public readonly string Name;
  15. public readonly TypeReference TypeRef;
  16. public readonly Location StartPos;
  17. public readonly Location EndPos;
  18. public readonly bool IsConst;
  19. public readonly bool IsLoopVariable;
  20. public readonly Expression Initializer;
  21. public readonly LambdaExpression ParentLambdaExpression;
  22. public readonly bool IsQueryContinuation;
  23. public LocalLookupVariable(string name, TypeReference typeRef, Location startPos, Location endPos, bool isConst, bool isLoopVariable, Expression initializer, LambdaExpression parentLambdaExpression, bool isQueryContinuation)
  24. {
  25. this.Name = name;
  26. this.TypeRef = typeRef;
  27. this.StartPos = startPos;
  28. this.EndPos = endPos;
  29. this.IsConst = isConst;
  30. this.IsLoopVariable = isLoopVariable;
  31. this.Initializer = initializer;
  32. this.ParentLambdaExpression = parentLambdaExpression;
  33. this.IsQueryContinuation = isQueryContinuation;
  34. }
  35. }
  36. public sealed class LookupTableVisitor : AbstractAstVisitor
  37. {
  38. Dictionary<string, List<LocalLookupVariable>> variables;
  39. SupportedLanguage language;
  40. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
  41. public Dictionary<string, List<LocalLookupVariable>> Variables {
  42. get {
  43. return variables;
  44. }
  45. }
  46. List<WithStatement> withStatements = new List<WithStatement>();
  47. public List<WithStatement> WithStatements {
  48. get {
  49. return withStatements;
  50. }
  51. }
  52. public LookupTableVisitor(SupportedLanguage language)
  53. {
  54. this.language = language;
  55. if (language == SupportedLanguage.VBNet) {
  56. variables = new Dictionary<string, List<LocalLookupVariable>>(StringComparer.InvariantCultureIgnoreCase);
  57. } else {
  58. variables = new Dictionary<string, List<LocalLookupVariable>>(StringComparer.InvariantCulture);
  59. }
  60. }
  61. public void AddVariable(TypeReference typeRef, string name,
  62. Location startPos, Location endPos, bool isConst,
  63. bool isLoopVariable, Expression initializer,
  64. LambdaExpression parentLambdaExpression,
  65. bool isQueryContinuation)
  66. {
  67. if (name == null || name.Length == 0) {
  68. return;
  69. }
  70. List<LocalLookupVariable> list;
  71. if (!variables.ContainsKey(name)) {
  72. variables[name] = list = new List<LocalLookupVariable>();
  73. } else {
  74. list = (List<LocalLookupVariable>)variables[name];
  75. }
  76. list.Add(new LocalLookupVariable(name, typeRef, startPos, endPos, isConst, isLoopVariable, initializer, parentLambdaExpression, isQueryContinuation));
  77. }
  78. public override object VisitWithStatement(WithStatement withStatement, object data)
  79. {
  80. withStatements.Add(withStatement);
  81. return base.VisitWithStatement(withStatement, data);
  82. }
  83. Stack<Location> endLocationStack = new Stack<Location>();
  84. Location CurrentEndLocation {
  85. get {
  86. return (endLocationStack.Count == 0) ? Location.Empty : endLocationStack.Peek();
  87. }
  88. }
  89. public override object VisitCompilationUnit (ICSharpCode.NRefactory.Ast.CompilationUnit compilationUnit, object data)
  90. {
  91. variables.Clear ();
  92. return base.VisitCompilationUnit (compilationUnit, data);
  93. }
  94. public override object VisitBlockStatement(BlockStatement blockStatement, object data)
  95. {
  96. endLocationStack.Push(blockStatement.EndLocation);
  97. base.VisitBlockStatement(blockStatement, data);
  98. endLocationStack.Pop();
  99. return null;
  100. }
  101. public override object VisitLocalVariableDeclaration(LocalVariableDeclaration localVariableDeclaration, object data)
  102. {
  103. for (int i = 0; i < localVariableDeclaration.Variables.Count; ++i) {
  104. VariableDeclaration varDecl = (VariableDeclaration)localVariableDeclaration.Variables[i];
  105. AddVariable(localVariableDeclaration.GetTypeForVariable(i),
  106. varDecl.Name,
  107. localVariableDeclaration.StartLocation,
  108. CurrentEndLocation,
  109. (localVariableDeclaration.Modifier & Modifiers.Const) == Modifiers.Const,
  110. false, varDecl.Initializer, null, false);
  111. }
  112. return base.VisitLocalVariableDeclaration(localVariableDeclaration, data);
  113. }
  114. public override object VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression, object data)
  115. {
  116. foreach (ParameterDeclarationExpression p in anonymousMethodExpression.Parameters) {
  117. AddVariable(p.TypeReference, p.ParameterName,
  118. anonymousMethodExpression.StartLocation, anonymousMethodExpression.EndLocation,
  119. false, false, null, null, false);
  120. }
  121. return base.VisitAnonymousMethodExpression(anonymousMethodExpression, data);
  122. }
  123. public override object VisitLambdaExpression(LambdaExpression lambdaExpression, object data)
  124. {
  125. foreach (ParameterDeclarationExpression p in lambdaExpression.Parameters) {
  126. AddVariable(p.TypeReference, p.ParameterName,
  127. lambdaExpression.StartLocation, lambdaExpression.ExtendedEndLocation,
  128. false, false, null, lambdaExpression, false);
  129. }
  130. return base.VisitLambdaExpression(lambdaExpression, data);
  131. }
  132. public override object VisitQueryExpression(QueryExpression queryExpression, object data)
  133. {
  134. endLocationStack.Push(GetQueryVariableEndScope(queryExpression));
  135. base.VisitQueryExpression(queryExpression, data);
  136. endLocationStack.Pop();
  137. return null;
  138. }
  139. Location GetQueryVariableEndScope(QueryExpression queryExpression)
  140. {
  141. return queryExpression.EndLocation;
  142. }
  143. public override object VisitQueryExpressionFromClause(QueryExpressionFromClause fromClause, object data)
  144. {
  145. QueryExpression parent = fromClause.Parent as QueryExpression;
  146. AddVariable(fromClause.Type, fromClause.Identifier,
  147. fromClause.StartLocation, CurrentEndLocation,
  148. false, true, fromClause.InExpression, null, parent != null && parent.IsQueryContinuation);
  149. return base.VisitQueryExpressionFromClause(fromClause, data);
  150. }
  151. public override object VisitQueryExpressionJoinClause(QueryExpressionJoinClause joinClause, object data)
  152. {
  153. if (string.IsNullOrEmpty(joinClause.IntoIdentifier)) {
  154. AddVariable(joinClause.Type, joinClause.Identifier,
  155. joinClause.StartLocation, CurrentEndLocation,
  156. false, true, joinClause.InExpression, null, false);
  157. } else {
  158. AddVariable(joinClause.Type, joinClause.Identifier,
  159. joinClause.StartLocation, joinClause.EndLocation,
  160. false, true, joinClause.InExpression, null, false);
  161. AddVariable(joinClause.Type, joinClause.IntoIdentifier,
  162. joinClause.StartLocation, CurrentEndLocation,
  163. false, false, joinClause.InExpression, null, false);
  164. }
  165. return base.VisitQueryExpressionJoinClause(joinClause, data);
  166. }
  167. public override object VisitQueryExpressionLetClause(QueryExpressionLetClause letClause, object data)
  168. {
  169. AddVariable(null, letClause.Identifier,
  170. letClause.StartLocation, CurrentEndLocation,
  171. false, false, letClause.Expression, null, false);
  172. return base.VisitQueryExpressionLetClause(letClause, data);
  173. }
  174. public override object VisitForNextStatement(ForNextStatement forNextStatement, object data)
  175. {
  176. if (forNextStatement.EmbeddedStatement.EndLocation.IsEmpty) {
  177. return base.VisitForNextStatement(forNextStatement, data);
  178. } else {
  179. endLocationStack.Push(forNextStatement.EmbeddedStatement.EndLocation);
  180. AddVariable(forNextStatement.TypeReference,
  181. forNextStatement.VariableName,
  182. forNextStatement.StartLocation,
  183. forNextStatement.EndLocation,
  184. false, false,
  185. forNextStatement.Start,
  186. null,
  187. false);
  188. base.VisitForNextStatement(forNextStatement, data);
  189. endLocationStack.Pop();
  190. return null;
  191. }
  192. }
  193. public override object VisitFixedStatement(FixedStatement fixedStatement, object data)
  194. {
  195. // uses LocalVariableDeclaration, we just have to put the end location on the stack
  196. if (fixedStatement.EmbeddedStatement.EndLocation.IsEmpty) {
  197. return base.VisitFixedStatement(fixedStatement, data);
  198. } else {
  199. endLocationStack.Push(fixedStatement.EmbeddedStatement.EndLocation);
  200. base.VisitFixedStatement(fixedStatement, data);
  201. endLocationStack.Pop();
  202. return null;
  203. }
  204. }
  205. public override object VisitForStatement(ForStatement forStatement, object data)
  206. {
  207. // uses LocalVariableDeclaration, we just have to put the end location on the stack
  208. if (forStatement.EmbeddedStatement.EndLocation.IsEmpty) {
  209. return base.VisitForStatement(forStatement, data);
  210. } else {
  211. endLocationStack.Push(forStatement.EmbeddedStatement.EndLocation);
  212. base.VisitForStatement(forStatement, data);
  213. endLocationStack.Pop();
  214. return null;
  215. }
  216. }
  217. public override object VisitUsingStatement(UsingStatement usingStatement, object data)
  218. {
  219. // uses LocalVariableDeclaration, we just have to put the end location on the stack
  220. if (usingStatement.EmbeddedStatement.EndLocation.IsEmpty) {
  221. return base.VisitUsingStatement(usingStatement, data);
  222. } else {
  223. endLocationStack.Push(usingStatement.EmbeddedStatement.EndLocation);
  224. base.VisitUsingStatement(usingStatement, data);
  225. endLocationStack.Pop();
  226. return null;
  227. }
  228. }
  229. public override object VisitSwitchSection(SwitchSection switchSection, object data)
  230. {
  231. if (language == SupportedLanguage.VBNet) {
  232. return VisitBlockStatement(switchSection, data);
  233. } else {
  234. return base.VisitSwitchSection(switchSection, data);
  235. }
  236. }
  237. public override object VisitForeachStatement(ForeachStatement foreachStatement, object data)
  238. {
  239. AddVariable(foreachStatement.TypeReference,
  240. foreachStatement.VariableName,
  241. foreachStatement.StartLocation,
  242. foreachStatement.EndLocation,
  243. false, true,
  244. foreachStatement.Expression,
  245. null,
  246. false);
  247. if (foreachStatement.Expression != null) {
  248. foreachStatement.Expression.AcceptVisitor(this, data);
  249. }
  250. if (foreachStatement.EmbeddedStatement == null) {
  251. return data;
  252. }
  253. return foreachStatement.EmbeddedStatement.AcceptVisitor(this, data);
  254. }
  255. public override object VisitTryCatchStatement(TryCatchStatement tryCatchStatement, object data)
  256. {
  257. if (tryCatchStatement == null) {
  258. return data;
  259. }
  260. if (tryCatchStatement.StatementBlock != null) {
  261. tryCatchStatement.StatementBlock.AcceptVisitor(this, data);
  262. }
  263. if (tryCatchStatement.CatchClauses != null) {
  264. foreach (CatchClause catchClause in tryCatchStatement.CatchClauses) {
  265. if (catchClause != null) {
  266. if (catchClause.TypeReference != null && catchClause.VariableName != null) {
  267. AddVariable(catchClause.TypeReference,
  268. catchClause.VariableName,
  269. catchClause.StartLocation,
  270. catchClause.StatementBlock.EndLocation,
  271. false, false, null, null, false);
  272. }
  273. catchClause.StatementBlock.AcceptVisitor(this, data);
  274. }
  275. }
  276. }
  277. if (tryCatchStatement.FinallyBlock != null) {
  278. return tryCatchStatement.FinallyBlock.AcceptVisitor(this, data);
  279. }
  280. return data;
  281. }
  282. }
  283. }