PageRenderTime 35ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/src/DevCode/MoqaLate/InterfaceTextParsing/InterfaceLineTextLineTextParser.cs

http://moqalate.codeplex.com
C# | 342 lines | 253 code | 89 blank | 0 comment | 20 complexity | 4c6cc2a3489d723b99f77923cfc2c42d MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using MoqaLate.CodeModel;
  5. using MoqaLate.Common;
  6. using MoqaLate.ExtensionMethods;
  7. namespace MoqaLate.InterfaceTextParsing
  8. {
  9. public class InterfaceLineTextLineTextParser : IInterfaceLineTextParser
  10. {
  11. private const string UsingSymbol = "using ";
  12. private const string InterfaceSymbol = "interface ";
  13. private readonly ILogger _logger;
  14. private ClassSpecification _classSpec;
  15. private List<string> _linesOfInterfaceCode;
  16. public InterfaceLineTextLineTextParser(ILogger logger)
  17. {
  18. _logger = logger;
  19. }
  20. #region IInterfaceLineTextParser Members
  21. public ClassSpecification GenerateClass(List<string> linesOfInterfaceCode)
  22. {
  23. _classSpec = new ClassSpecification();
  24. _linesOfInterfaceCode = linesOfInterfaceCode;
  25. _linesOfInterfaceCode = CommentLineRemover.Remove(_linesOfInterfaceCode);
  26. _linesOfInterfaceCode = RemoveAttributes(_linesOfInterfaceCode);
  27. _classSpec = new ClassSpecification();
  28. ParseNamespace();
  29. ParseClassName();
  30. if (_classSpec.ClassName == null)
  31. {
  32. _classSpec.IsValid = false;
  33. return _classSpec;
  34. }
  35. ParseUsings();
  36. ParseProperties();
  37. ParseMethods();
  38. ParseEvents();
  39. return _classSpec;
  40. }
  41. #endregion
  42. private void ParseEvents()
  43. {
  44. _logger.Write("Parsing events");
  45. var lineNum = 0;
  46. foreach (var line in _linesOfInterfaceCode)
  47. {
  48. try
  49. {
  50. lineNum++;
  51. if (TypeOfLineIdentifier.Identify(line) == InterfaceDefinitionLineType.Event)
  52. {
  53. ParseEventLine(line);
  54. }
  55. }
  56. catch (Exception ex)
  57. {
  58. throw new ParseException(
  59. string.Format("Error parsing surrounding event in file '{0}' at line {1}", _classSpec.ClassName,
  60. lineNum), ex);
  61. }
  62. }
  63. }
  64. private void ParseEventLine(string line)
  65. {
  66. var trimmedLine = line.Trim();
  67. var eventType = trimmedLine.Replace("event ", "").Split(new char[] {' '})[0];
  68. var eventName =
  69. trimmedLine.Substring(trimmedLine.PositionOfSpaceBefore(trimmedLine.Length - 1)).TrimEnd(new[] {';'}).
  70. Trim();
  71. _classSpec.Events.Add(new Event {Name = eventName, Type = eventType});
  72. }
  73. private void ParseNamespace()
  74. {
  75. _logger.Write("Parsing containing namespace");
  76. var lineNum = 0;
  77. foreach (var line in _linesOfInterfaceCode)
  78. {
  79. try
  80. {
  81. lineNum++;
  82. if (TypeOfLineIdentifier.Identify(line) == InterfaceDefinitionLineType.Namespace)
  83. {
  84. ParseNameSpaceLine(line);
  85. }
  86. }
  87. catch (Exception ex)
  88. {
  89. throw new ParseException(
  90. string.Format("Error parsing surrounding namespace in file '{0}' at line {1}",
  91. _classSpec.ClassName,
  92. lineNum), ex);
  93. }
  94. }
  95. }
  96. private void ParseNameSpaceLine(string line)
  97. {
  98. _classSpec.OriginalInterfaceNamespace = line.Trim().Split(new[] {' '})[1];
  99. }
  100. private List<string> RemoveAttributes(List<string> linesOfInterfaceCode)
  101. {
  102. return linesOfInterfaceCode.Where(line => ! line.Trim().StartsWith("[")).ToList();
  103. }
  104. private void ParseProperties()
  105. {
  106. _logger.Write("Parsing properties");
  107. var lineNum = 0;
  108. foreach (var line in _linesOfInterfaceCode)
  109. {
  110. try
  111. {
  112. lineNum++;
  113. if (TypeOfLineIdentifier.Identify(line) == InterfaceDefinitionLineType.PropertyGetSet)
  114. {
  115. ParseGetterSetterPropertyLine(line);
  116. }
  117. if (TypeOfLineIdentifier.Identify(line) == InterfaceDefinitionLineType.PropertyGet)
  118. {
  119. ParseGetterOnlyPropertyLine(line);
  120. }
  121. if (TypeOfLineIdentifier.Identify(line) ==InterfaceDefinitionLineType.PropertySet)
  122. {
  123. ParseSetterOnlyPropertyLine(line);
  124. }
  125. }
  126. catch (Exception ex)
  127. {
  128. throw new ParseException(
  129. string.Format("Error parsing a property in file '{0}' at line {1}", _classSpec.ClassName,
  130. lineNum), ex);
  131. }
  132. }
  133. }
  134. private void ParseSetterOnlyPropertyLine(string line)
  135. {
  136. var prop = new Property
  137. {
  138. Type = line.Trim().Split(new[] {' '})[0],
  139. Accessor = PropertyAccessor.SetOny,
  140. Name = line.Trim().Split(new[] {' '})[1]
  141. };
  142. _classSpec.Properties.Add(prop);
  143. }
  144. private void ParseGetterOnlyPropertyLine(string line)
  145. {
  146. var prop = new Property
  147. {
  148. Type = line.Trim().Split(new[] {' '})[0],
  149. Accessor = PropertyAccessor.GetOny,
  150. Name = line.Trim().Split(new[] {' '})[1]
  151. };
  152. _classSpec.Properties.Add(prop);
  153. }
  154. private void ParseGetterSetterPropertyLine(string line)
  155. {
  156. var prop = new Property
  157. {
  158. Type = line.Trim().Split(new[] {' '})[0],
  159. Accessor = PropertyAccessor.GetAndSet,
  160. Name = line.Trim().Split(new[] {' '})[1]
  161. };
  162. _classSpec.Properties.Add(prop);
  163. }
  164. private void ParseUsings()
  165. {
  166. _logger.Write("Parsing using statements");
  167. var lineNum = 0;
  168. foreach (var line in _linesOfInterfaceCode)
  169. {
  170. try
  171. {
  172. lineNum++;
  173. if (TypeOfLineIdentifier.Identify(line) == InterfaceDefinitionLineType.Using)
  174. {
  175. ParseUsingLine(line);
  176. }
  177. }
  178. catch (Exception ex)
  179. {
  180. throw new ParseException(
  181. string.Format("Error parsing a using in file '{0}' at line {1}", _classSpec.ClassName,
  182. lineNum), ex);
  183. }
  184. }
  185. }
  186. private void ParseUsingLine(string line)
  187. {
  188. var namespaceNamePosition = line.IndexOf(UsingSymbol) + UsingSymbol.Length;
  189. var nameSpace = line.Substring(namespaceNamePosition);
  190. _classSpec.Usings.Add(nameSpace.Replace(";", ""));
  191. }
  192. private void ParseClassName()
  193. {
  194. _logger.Write("Parsing class name (looking for 'interface' text)");
  195. foreach (var line in _linesOfInterfaceCode)
  196. {
  197. if (TypeOfLineIdentifier.Identify(line) == InterfaceDefinitionLineType.Interface)
  198. {
  199. ParseInterfaceDeclarationLine(line);
  200. return;
  201. }
  202. }
  203. }
  204. private void ParseInterfaceDeclarationLine(string line)
  205. {
  206. if (! line.Trim().StartsWith(InterfaceSymbol))
  207. {
  208. var accessModifer = line.Trim().Split(new[] {' '})[0];
  209. _classSpec.IsPublic = accessModifer == "public";
  210. }
  211. var interfaceNamePosition = line.IndexOf(InterfaceSymbol) + InterfaceSymbol.Length;
  212. var interfaceName = line.Substring(interfaceNamePosition);
  213. if (interfaceName.Contains("<")) // look for generic types
  214. {
  215. var startPositionGeneicDeclarations = interfaceName.IndexOf("<");
  216. _classSpec.InterfaceGenericTypes = interfaceName.Substring(startPositionGeneicDeclarations);
  217. interfaceName = interfaceName.Remove(startPositionGeneicDeclarations);
  218. }
  219. _classSpec.ClassName = interfaceName.Substring(1) + "MoqaLate";
  220. _classSpec.OriginalInterfaceName = interfaceName;
  221. }
  222. private void ParseMethods()
  223. {
  224. _logger.Write("Parsing methods");
  225. foreach (var line in _linesOfInterfaceCode)
  226. {
  227. if (
  228. TypeOfLineIdentifier.Identify(line) == InterfaceDefinitionLineType.Method
  229. )
  230. {
  231. ParseMethodLine(line);
  232. }
  233. }
  234. }
  235. private void ParseMethodLine(string line)
  236. {
  237. var trimmdLine = line.Trim();
  238. var posOfStartOfMethodName = trimmdLine.PositionOfSpaceBefore('(');
  239. var returnType = trimmdLine.Substring(0, posOfStartOfMethodName);
  240. var nameAndParameters = trimmdLine.Substring(posOfStartOfMethodName + 1);
  241. var name = nameAndParameters.Substring(0, nameAndParameters.IndexOf('('));
  242. var indexOfOpenParen = nameAndParameters.IndexOf('(');
  243. var indexOfCloseParen = nameAndParameters.IndexOf(')');
  244. var parameters = nameAndParameters.Substring(indexOfOpenParen + 1, indexOfCloseParen - indexOfOpenParen - 1);
  245. _classSpec.Methods.Add(new Method
  246. {
  247. Name = name,
  248. ReturnType = returnType,
  249. Parameters = MethodParameterParser.Parse(parameters)
  250. });
  251. }
  252. }
  253. }