/latebindingapi/LateBindingApi.CodeGenerator.CSharp/CustomMethodManager.cs

# · C# · 275 lines · 232 code · 43 blank · 0 comment · 42 complexity · 596fe72abcbe2e56974e247d6ae965e8 MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Xml.Linq;
  4. using System.Xml.XPath;
  5. using System.Xml;
  6. using System.Linq;
  7. using System.Text;
  8. namespace LateBindingApi.CodeGenerator.CSharp
  9. {
  10. class CustomMethodManager
  11. {
  12. CSharpGenerator _parent;
  13. XDocument _document;
  14. XDocument _derived;
  15. internal CustomMethodManager(CSharpGenerator parent, XDocument document)
  16. {
  17. _parent = parent;
  18. _document = document;
  19. }
  20. public void ScanForOptionalMethods()
  21. {
  22. _derived = new XDocument();
  23. _derived.Add(new XElement("Document"));
  24. ScanForDerived("DispatchInterfaces", "Interface");
  25. ScanForDerived("Interfaces", "Interface");
  26. }
  27. private XElement GetMethodOverload(XElement itemMethod, IEnumerable<XElement> listParameters, int paramsCount)
  28. {
  29. foreach (XElement itemParameters in itemMethod.Elements("Parameters"))
  30. {
  31. if (itemParameters.Elements("Parameter").Count() == paramsCount)
  32. return itemParameters;
  33. }
  34. foreach (XElement itemParameters in listParameters)
  35. {
  36. if (itemParameters.Elements("Parameter").Count() == paramsCount)
  37. return itemParameters;
  38. }
  39. return null;
  40. }
  41. private XElement CloneParametersNode(XElement itemParameters, int parametersCount)
  42. {
  43. XElement itemMethod = itemParameters.Parent;
  44. XElement newParameters = new XElement("Parameters", new XAttribute("IsCustom","true"));
  45. if (itemParameters.Element("ReturnValue") != null)
  46. {
  47. newParameters.Add(new XElement("ReturnValue"));
  48. foreach (XAttribute item in itemParameters.Element("ReturnValue").Attributes())
  49. newParameters.Element("ReturnValue").Add(new XAttribute(item.Name, item.Value));
  50. }
  51. newParameters.Add(new XElement("RefLibraries"));
  52. foreach (XElement item in itemParameters.Element("RefLibraries").Elements("Ref"))
  53. {
  54. XElement newRef = new XElement(item.Name, item.Value);
  55. newRef.Add(new XAttribute("Key", item.Attribute("Key").Value));
  56. newParameters.Element("RefLibraries").Add(newRef);
  57. }
  58. int i = 1;
  59. foreach (XElement item in itemParameters.Elements("Parameter"))
  60. {
  61. if (i > parametersCount)
  62. break;
  63. XElement newParameter = new XElement("Parameter");
  64. foreach (XAttribute itemAttribute in item.Attributes())
  65. newParameter.Add(new XAttribute(itemAttribute.Name, itemAttribute.Value));
  66. newParameters.Add(newParameter);
  67. i++;
  68. }
  69. return newParameters;
  70. }
  71. private void ScanForDerived(string elements, string element)
  72. {
  73. var interfaces = (from a in _document.Element("LateBindingApi.CodeGenerator.Document").Element("Solution").Element("Projects").Elements("Project").
  74. Elements(elements).Elements(element)
  75. select a);
  76. foreach (XElement itemFace in interfaces)
  77. {
  78. foreach (XElement itemMethod in itemFace.Element("Methods").Elements("Method"))
  79. {
  80. if (itemMethod.Attribute("Name").Value == "Item")
  81. continue;
  82. List<XElement> newParameters = new List<XElement>();
  83. IEnumerable<XElement> listParameters = itemMethod.Elements("Parameters");
  84. foreach (XElement itemParameters in listParameters)
  85. {
  86. IEnumerable<XElement> nonOptionalParamNodes = (from a in itemParameters.Elements("Parameter")
  87. where a.Attribute("IsOptional").Value.Equals("false", StringComparison.InvariantCultureIgnoreCase)
  88. select a);
  89. int nonOptionalsCount = nonOptionalParamNodes.Count();
  90. IEnumerable<XElement> optionalParamNodes = (from a in itemParameters.Elements("Parameter")
  91. where a.Attribute("IsOptional").Value.Equals("true", StringComparison.InvariantCultureIgnoreCase)
  92. select a);
  93. int optionalsCount = optionalParamNodes.Count();
  94. if (optionalsCount > 0)
  95. {
  96. for (int i = nonOptionalsCount; i < (nonOptionalsCount+optionalsCount); i++)
  97. {
  98. XElement existingMethodOverload = GetMethodOverload(itemMethod, newParameters, i);
  99. if (null == existingMethodOverload)
  100. {
  101. XElement newParameter = CloneParametersNode(itemParameters, i);
  102. newParameters.Add(newParameter);
  103. }
  104. }
  105. }
  106. }
  107. foreach (XElement item in newParameters)
  108. itemMethod.Add(item);
  109. }
  110. }
  111. }
  112. private XElement HasCount(XElement itemFace)
  113. {
  114. XElement node = (from a in itemFace.Element("Properties").Elements("Property")
  115. where a.Attribute("Name").Value.Equals("Count", StringComparison.InvariantCultureIgnoreCase)
  116. select a).FirstOrDefault();
  117. if (null != node)
  118. {
  119. string type = (node.Element("Parameters").Element("ReturnValue").Attribute("Type").Value) ;
  120. if ("Int32" == type)
  121. return node;
  122. }
  123. node = (from a in itemFace.Element("Methods").Elements("Method")
  124. where a.Attribute("Name").Value.Equals("Count", StringComparison.InvariantCultureIgnoreCase)
  125. select a).FirstOrDefault();
  126. if (null != node)
  127. return node;
  128. return null;
  129. }
  130. private XElement HasItem(XElement itemFace)
  131. {
  132. XElement node = (from a in itemFace.Element("Properties").Elements("Property")
  133. where a.Attribute("Name").Value.Equals("Item", StringComparison.InvariantCultureIgnoreCase)
  134. select a).FirstOrDefault();
  135. if (null != node)
  136. return node;
  137. node = (from a in itemFace.Element("Methods").Elements("Method")
  138. where a.Attribute("Name").Value.Equals("Item", StringComparison.InvariantCultureIgnoreCase)
  139. select a).FirstOrDefault();
  140. if (null != node)
  141. return node;
  142. return null;
  143. }
  144. private XElement HasEnum(XElement itemFace)
  145. {
  146. XElement node = (from a in itemFace.Element("Properties").Elements("Property")
  147. where a.Attribute("Name").Value.Equals("_NewEnum", StringComparison.InvariantCultureIgnoreCase)
  148. select a).FirstOrDefault();
  149. if (null != node)
  150. return node;
  151. node = (from a in itemFace.Element("Methods").Elements("Method")
  152. where a.Attribute("Name").Value.Equals("_NewEnum", StringComparison.InvariantCultureIgnoreCase)
  153. select a).FirstOrDefault();
  154. if (null != node)
  155. return node;
  156. return null;
  157. }
  158. private void AddType(XElement type)
  159. {
  160. string id = type.Attribute("Key").Value;
  161. XElement node = (from a in _derived.Element("Document").Elements("Type")
  162. where a.Attribute("Key").Value.Equals(id, StringComparison.InvariantCultureIgnoreCase)
  163. select a).FirstOrDefault();
  164. if (null == node)
  165. {
  166. string name = type.Attribute("Name").Value;
  167. _derived.Element("Document").Add(new XElement("Type", new XAttribute("Name", name), new XAttribute("Key", id)));
  168. }
  169. }
  170. private XElement GetTypeByName(XElement projectNode, string name)
  171. {
  172. XElement node = (from a in projectNode.Element("DispatchInterfaces").Elements("Interface")
  173. where a.Attribute("Name").Value.Equals(name, StringComparison.InvariantCultureIgnoreCase)
  174. select a).FirstOrDefault();
  175. if (null != node)
  176. return node;
  177. node = (from a in projectNode.Element("Interfaces").Elements("Interface")
  178. where a.Attribute("Name").Value.Equals(name, StringComparison.InvariantCultureIgnoreCase)
  179. select a).FirstOrDefault();
  180. if (null != node)
  181. return node;
  182. node = (from a in projectNode.Element("CoClasses").Elements("CoClass")
  183. where a.Attribute("Name").Value.Equals(name, StringComparison.InvariantCultureIgnoreCase)
  184. select a).FirstOrDefault();
  185. if (null != node)
  186. return node;
  187. throw new Exception("name not found " + name);
  188. }
  189. private bool HasAttriute(XElement node, string attributeName)
  190. {
  191. foreach (XAttribute item in node.Attributes())
  192. {
  193. if (item.Name == attributeName)
  194. return true;
  195. }
  196. return false;
  197. }
  198. private XElement GetProjectNode(XElement returnValue)
  199. {
  200. XElement projectNode = returnValue.Parent;
  201. while (projectNode.Name != "Project")
  202. projectNode = projectNode.Parent;
  203. return projectNode;
  204. }
  205. public bool IsDerivedReturnValue(XElement returnValue)
  206. {
  207. string typeKey = returnValue.Attribute("TypeKey").Value;
  208. if (string.IsNullOrEmpty(typeKey))
  209. {
  210. if (returnValue.Attribute("IsExternal").Value.Equals("true", StringComparison.InvariantCultureIgnoreCase))
  211. return false;
  212. XElement projectNode = GetProjectNode(returnValue);
  213. XElement interfaceNode = GetTypeByName(projectNode, returnValue.Attribute("Type").Value as string);
  214. string id = interfaceNode.Attribute("Key").Value;
  215. return IsDerived(id);
  216. }
  217. else
  218. {
  219. XElement interfaceNode = CSharpGenerator.GetInterfaceOrClassFromKey(typeKey);
  220. string id = interfaceNode.Attribute("Key").Value;
  221. return IsDerived(id);
  222. }
  223. }
  224. public bool IsDerived(string id)
  225. {
  226. XElement node = (from a in _derived.Element("Document").Elements("Type")
  227. where a.Attribute("Key").Value.Equals(id, StringComparison.InvariantCultureIgnoreCase)
  228. select a).FirstOrDefault();
  229. return (node != null);
  230. }
  231. }
  232. }