/LateBindingApi.CodeGenerator.VB/CustomMethodManager.cs

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