CrossBindingCodeGenerator.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using ILRuntime.CLR.Method;
  6. using ILRuntime.CLR.TypeSystem;
  7. using ILRuntime.Runtime.Intepreter;
  8. using System.Reflection;
  9. using System.Threading;
  10. namespace ILRuntime.Runtime.Enviorment
  11. {
  12. public class CrossBindingCodeGenerator
  13. {
  14. class PropertyGenerateInfo
  15. {
  16. public string Name;
  17. public Type ReturnType;
  18. public string GetterBody;
  19. public string SettingBody;
  20. public string Modifier;
  21. public string OverrideString;
  22. }
  23. public static string GenerateCrossBindingAdapterCode(Type baseType, string nameSpace)
  24. {
  25. StringBuilder sb = new StringBuilder();
  26. List<MethodInfo> virtMethods = new List<MethodInfo>();
  27. GetMethods(baseType, virtMethods);
  28. string clsName, realClsName;
  29. bool isByRef;
  30. baseType.GetClassName(out clsName, out realClsName, out isByRef, true);
  31. sb.Append(@"using System;
  32. using ILRuntime.CLR.Method;
  33. using ILRuntime.Runtime.Enviorment;
  34. using ILRuntime.Runtime.Intepreter;
  35. namespace ");
  36. sb.AppendLine(nameSpace);
  37. sb.Append(@"{
  38. public class ");
  39. sb.Append(clsName);
  40. sb.AppendLine(@"Adapter : CrossBindingAdaptor
  41. {");
  42. sb.Append(@" public override Type BaseCLRType
  43. {
  44. get
  45. {
  46. return typeof(");
  47. sb.Append(realClsName);
  48. sb.AppendLine(@");
  49. }
  50. }
  51. public override Type AdaptorType
  52. {
  53. get
  54. {
  55. return typeof(Adapter);
  56. }
  57. }
  58. public override object CreateCLRInstance(ILRuntime.Runtime.Enviorment.AppDomain appdomain, ILTypeInstance instance)
  59. {
  60. return new Adapter(appdomain, instance);
  61. }
  62. ");
  63. sb.AppendLine(string.Format(" public class Adapter : {0}, CrossBindingAdaptorType", realClsName));
  64. sb.AppendLine(" {");
  65. GenerateCrossBindingMethodInfo(sb, virtMethods);
  66. sb.AppendLine(@"
  67. bool isInvokingToString;
  68. ILTypeInstance instance;
  69. ILRuntime.Runtime.Enviorment.AppDomain appdomain;
  70. public Adapter()
  71. {
  72. }
  73. public Adapter(ILRuntime.Runtime.Enviorment.AppDomain appdomain, ILTypeInstance instance)
  74. {
  75. this.appdomain = appdomain;
  76. this.instance = instance;
  77. }
  78. public ILTypeInstance ILInstance { get { return instance; } }
  79. ");
  80. GenerateCrossBindingMethodBody(sb, virtMethods);
  81. sb.Append(@" public override string ToString()
  82. {
  83. IMethod m = appdomain.ObjectType.GetMethod("); sb.AppendLine("\"ToString\", 0);");
  84. sb.AppendLine(@" m = instance.Type.GetVirtualMethod(m);
  85. if (m == null || m is ILMethod)
  86. {
  87. if (!isInvokingToString)
  88. {
  89. isInvokingToString = true;
  90. string res = instance.ToString();
  91. isInvokingToString = false;
  92. return res;
  93. }
  94. else
  95. return instance.Type.FullName;
  96. }
  97. else
  98. return instance.Type.FullName;");
  99. sb.AppendLine(" }");
  100. sb.AppendLine(" }");
  101. sb.AppendLine(" }");
  102. sb.AppendLine("}");
  103. return sb.ToString();
  104. }
  105. static void GenerateCrossBindingMethodBody(StringBuilder sb, List<MethodInfo> virtMethods)
  106. {
  107. int index = 0;
  108. Dictionary<string, PropertyGenerateInfo> pendingProperties = new Dictionary<string, PropertyGenerateInfo>();
  109. foreach (var i in virtMethods)
  110. {
  111. if (ShouldSkip(i))
  112. continue;
  113. bool isProperty = i.IsSpecialName && (i.Name.StartsWith("get_") || i.Name.StartsWith("set_"));
  114. PropertyGenerateInfo pInfo = null;
  115. bool isGetter = false;
  116. bool isIndexFunc = false;
  117. bool isByRef;
  118. string clsName, realClsName;
  119. StringBuilder oriBuilder = null;
  120. if (isProperty)
  121. {
  122. string pName = i.Name.Substring(4);
  123. if (i.Name == "get_Item" || i.Name == "set_Item")
  124. {
  125. StringBuilder sBuilder = new StringBuilder();
  126. var p = i.GetParameters()[0];
  127. p.ParameterType.GetClassName(out clsName, out realClsName, out isByRef, true);
  128. pName = string.Format("this [{0}]", realClsName + " " + p.Name);
  129. isIndexFunc = true;
  130. }
  131. isGetter = i.Name.StartsWith("get_");
  132. oriBuilder = sb;
  133. sb = new StringBuilder();
  134. if (!pendingProperties.TryGetValue(pName, out pInfo))
  135. {
  136. pInfo = new PropertyGenerateInfo();
  137. pInfo.Name = pName;
  138. pendingProperties[pName] = pInfo;
  139. }
  140. if (pInfo.ReturnType == null)
  141. {
  142. if (isGetter)
  143. {
  144. pInfo.ReturnType = i.ReturnType;
  145. }
  146. else
  147. {
  148. pInfo.ReturnType = i.GetParameters()[0].ParameterType;
  149. }
  150. }
  151. }
  152. var param = i.GetParameters();
  153. string modifier = i.IsFamily ? "protected" : "public";
  154. string overrideStr = i.DeclaringType.IsInterface ? "" : (i.IsFinal ? "new " : "override ");
  155. string returnString = "";
  156. if (i.ReturnType != typeof(void))
  157. {
  158. i.ReturnType.GetClassName(out clsName, out realClsName, out isByRef, true);
  159. returnString = "return ";
  160. }
  161. else
  162. realClsName = "void";
  163. if (!isProperty)
  164. {
  165. sb.Append(string.Format(" {0} {3}{1} {2}(", modifier, realClsName, i.Name, overrideStr));
  166. GetParameterDefinition(sb, param, true);
  167. sb.AppendLine(@")
  168. {");
  169. }
  170. else
  171. {
  172. pInfo.Modifier = modifier;
  173. pInfo.OverrideString = overrideStr;
  174. }
  175. if (!i.IsAbstract)
  176. {
  177. sb.AppendLine(string.Format(" if (m{0}_{1}.CheckShouldInvokeBase(this.instance))", i.Name, index));
  178. if (isProperty)
  179. {
  180. string baseMethodName = isIndexFunc
  181. ? string.Format("base[{0}]", i.GetParameters()[0].Name)
  182. : string.Format("base.{0}", i.Name.Substring(4));
  183. if (isGetter)
  184. {
  185. sb.AppendLine(string.Format(" return {0};", baseMethodName));
  186. }
  187. else
  188. {
  189. sb.AppendLine(string.Format(" {0} = value;", baseMethodName));
  190. }
  191. }
  192. else
  193. sb.AppendLine(string.Format(" {2}base.{0}({1});", i.Name, GetParameterName(param, true), returnString));
  194. sb.AppendLine(" else");
  195. sb.AppendLine(string.Format(" {3}m{0}_{1}.Invoke(this.instance{2});", i.Name, index, GetParameterName(param, false), returnString));
  196. }
  197. else
  198. {
  199. sb.AppendLine(string.Format(" {3}m{0}_{1}.Invoke(this.instance{2});", i.Name, index, GetParameterName(param, false), returnString));
  200. }
  201. if (isProperty)
  202. {
  203. if (isGetter)
  204. {
  205. pInfo.GetterBody = sb.ToString();
  206. }
  207. else
  208. {
  209. pInfo.SettingBody = sb.ToString();
  210. }
  211. sb = oriBuilder;
  212. }
  213. else
  214. {
  215. sb.AppendLine(" }");
  216. sb.AppendLine();
  217. }
  218. index++;
  219. }
  220. foreach (var i in pendingProperties)
  221. {
  222. var pInfo = i.Value;
  223. string clsName, realClsName;
  224. bool isByRef;
  225. pInfo.ReturnType.GetClassName(out clsName, out realClsName, out isByRef, true);
  226. sb.AppendLine(string.Format(" {0} {3}{1} {2}", pInfo.Modifier, realClsName, pInfo.Name, pInfo.OverrideString));
  227. sb.AppendLine(" {");
  228. if (!string.IsNullOrEmpty(pInfo.GetterBody))
  229. {
  230. sb.AppendLine(" get");
  231. sb.AppendLine(" {");
  232. sb.AppendLine(pInfo.GetterBody);
  233. sb.AppendLine(" }");
  234. }
  235. if (!string.IsNullOrEmpty(pInfo.SettingBody))
  236. {
  237. sb.AppendLine(" set");
  238. sb.AppendLine(" {");
  239. sb.AppendLine(pInfo.SettingBody);
  240. sb.AppendLine(" }");
  241. }
  242. sb.AppendLine(" }");
  243. sb.AppendLine();
  244. }
  245. }
  246. static void GenerateCrossBindingMethodInfo(StringBuilder sb, List<MethodInfo> virtMethods)
  247. {
  248. int index = 0;
  249. foreach (var i in virtMethods)
  250. {
  251. if (ShouldSkip(i))
  252. continue;
  253. var param = i.GetParameters();
  254. if (NeedGenerateCrossBindingMethodClass(param))
  255. {
  256. GenerateCrossBindingMethodClass(sb, i.Name, index, param, i.ReturnType);
  257. sb.AppendLine(string.Format(" {0}_{1}Info m{0}_{1} = new {0}_{1}Info();", i.Name, index));
  258. }
  259. else
  260. {
  261. if (i.ReturnType != typeof(void))
  262. {
  263. sb.AppendLine(string.Format(" CrossBindingFunctionInfo<{0}> m{1}_{2} = new CrossBindingFunctionInfo<{0}>(\"{1}\");", GetParametersString(param, i.ReturnType), i.Name, index));
  264. }
  265. else
  266. {
  267. if (param.Length > 0)
  268. sb.AppendLine(string.Format(" CrossBindingMethodInfo<{0}> m{1}_{2} = new CrossBindingMethodInfo<{0}>(\"{1}\");", GetParametersString(param, i.ReturnType), i.Name, index));
  269. else
  270. sb.AppendLine(string.Format(" CrossBindingMethodInfo m{0}_{1} = new CrossBindingMethodInfo(\"{0}\");", i.Name, index));
  271. }
  272. }
  273. index++;
  274. }
  275. }
  276. static bool ShouldSkip(MethodInfo info)
  277. {
  278. var paramInfos = info.GetParameters();
  279. if (info.Name == "ToString" || info.Name == "GetHashCode" || info.Name == "Finalize")
  280. return paramInfos.Length == 0;
  281. if (info.Name == "Equals" && paramInfos.Length == 1 && paramInfos[0].ParameterType == typeof(object))
  282. return true;
  283. if (info.IsAssembly || info.IsFamilyOrAssembly || info.IsPrivate || info.IsFinal)
  284. return true;
  285. if (info.GetCustomAttributes(typeof(ObsoleteAttribute), true).Length > 0)
  286. return true;
  287. for (int i = 0; i < paramInfos.Length; ++i)
  288. {
  289. var paramType = paramInfos[i].ParameterType;
  290. if (paramType.IsByRef)
  291. paramType = paramType.GetElementType();
  292. if (paramType.IsPointer || paramType.IsNotPublic || paramType.IsNested && !paramType.IsNestedPublic)
  293. {
  294. return true;
  295. }
  296. }
  297. var returnType = info.ReturnType;
  298. if (returnType.IsByRef)
  299. returnType = returnType.GetElementType();
  300. if (returnType.IsNotPublic || returnType.IsNested && !returnType.IsNestedPublic)
  301. return true;
  302. return false;
  303. }
  304. static string GetParametersString(ParameterInfo[] param, Type returnType)
  305. {
  306. StringBuilder sb = new StringBuilder();
  307. bool first = true;
  308. foreach (var i in param)
  309. {
  310. if (!first)
  311. sb.Append(", ");
  312. else
  313. first = false;
  314. string clsName, realClsName;
  315. bool isByRef;
  316. i.ParameterType.GetClassName(out clsName, out realClsName, out isByRef, true);
  317. sb.Append(realClsName);
  318. }
  319. if (returnType != typeof(void))
  320. {
  321. if (!first)
  322. sb.Append(", ");
  323. string clsName, realClsName;
  324. bool isByRef;
  325. returnType.GetClassName(out clsName, out realClsName, out isByRef, true);
  326. sb.Append(realClsName);
  327. }
  328. return sb.ToString();
  329. }
  330. static string GetParametersTypeString(ParameterInfo[] param, Type returnType)
  331. {
  332. StringBuilder sb = new StringBuilder();
  333. bool first = true;
  334. foreach (var i in param)
  335. {
  336. if (!first)
  337. sb.Append(", ");
  338. else
  339. first = false;
  340. string clsName, realClsName;
  341. bool isByRef;
  342. sb.Append("typeof(");
  343. i.ParameterType.GetClassName(out clsName, out realClsName, out isByRef, true);
  344. sb.Append(realClsName);
  345. sb.Append(")");
  346. if (isByRef)
  347. sb.Append(".MakeByRefType()");
  348. }
  349. if (returnType != typeof(void))
  350. {
  351. if (!first)
  352. sb.Append(", ");
  353. string clsName, realClsName;
  354. bool isByRef;
  355. returnType.GetClassName(out clsName, out realClsName, out isByRef, true);
  356. sb.Append(realClsName);
  357. }
  358. return sb.ToString();
  359. }
  360. static bool NeedGenerateCrossBindingMethodClass(ParameterInfo[] param)
  361. {
  362. if (param.Length > 5)
  363. return true;
  364. foreach (var i in param)
  365. {
  366. if (i.IsOut || i.ParameterType.IsByRef)
  367. return true;
  368. }
  369. return false;
  370. }
  371. static string GetParameterName(ParameterInfo[] param, bool first)
  372. {
  373. StringBuilder sb = new StringBuilder();
  374. foreach (var p in param)
  375. {
  376. if (!first)
  377. sb.Append(", ");
  378. else
  379. first = false;
  380. if (p.IsOut)
  381. sb.Append("out ");
  382. else if (p.ParameterType.IsByRef)
  383. sb.Append("ref ");
  384. sb.Append(p.Name);
  385. }
  386. return sb.ToString();
  387. }
  388. static void GetParameterDefinition(StringBuilder sb, ParameterInfo[] param, bool first)
  389. {
  390. string clsName, realClsName;
  391. bool isByRef;
  392. foreach (var p in param)
  393. {
  394. if (!first)
  395. sb.Append(", ");
  396. else
  397. first = false;
  398. p.ParameterType.GetClassName(out clsName, out realClsName, out isByRef, true);
  399. if (p.IsOut)
  400. sb.Append("out ");
  401. else if (isByRef)
  402. sb.Append("ref ");
  403. sb.Append(realClsName);
  404. sb.Append(" ");
  405. sb.Append(p.Name);
  406. }
  407. }
  408. static void GenerateCrossBindingMethodClass(StringBuilder sb, string funcName, int index, ParameterInfo[] param, Type returnType)
  409. {
  410. sb.AppendLine(string.Format(" class {0}_{1}Info : CrossBindingMethodInfo", funcName, index));
  411. sb.Append(@" {
  412. static Type[] pTypes = new Type[] {");
  413. sb.Append(GetParametersTypeString(param, returnType));
  414. sb.AppendLine("};");
  415. sb.AppendLine();
  416. sb.AppendLine(string.Format(" public {0}_{1}Info()", funcName, index));
  417. sb.AppendLine(string.Format(" : base(\"{0}\")", funcName));
  418. sb.Append(@" {
  419. }
  420. protected override Type ReturnType { get { return ");
  421. string clsName, realClsName;
  422. bool isByRef;
  423. returnType.GetClassName(out clsName, out realClsName, out isByRef, true);
  424. string rtRealName = realClsName;
  425. bool hasReturn = returnType != typeof(void);
  426. if (!hasReturn)
  427. sb.Append("null");
  428. else
  429. {
  430. sb.AppendFormat("typeof({0})", realClsName);
  431. }
  432. sb.AppendLine(@"; } }
  433. protected override Type[] Parameters { get { return pTypes; } }");
  434. sb.AppendFormat(" public {0} Invoke(ILTypeInstance instance", !hasReturn ? "void" : realClsName);
  435. GetParameterDefinition(sb, param, false);
  436. sb.AppendLine(@")
  437. {
  438. EnsureMethod(instance);");
  439. GenInitParams(sb, param);
  440. sb.AppendLine(@"
  441. if (method != null)
  442. {
  443. invoking = true;");
  444. if (hasReturn)
  445. sb.AppendLine(string.Format(" {0} __res = default({0});", rtRealName));
  446. sb.AppendLine(@" try
  447. {
  448. using (var ctx = domain.BeginInvoke(method))
  449. {");
  450. Dictionary<ParameterInfo, int> refIndex = new Dictionary<ParameterInfo, int>();
  451. int idx = 0;
  452. foreach (var p in param)
  453. {
  454. if (p.ParameterType.IsByRef)
  455. {
  456. sb.AppendLine(GetPushString(p.ParameterType.GetElementType(), p.Name));
  457. refIndex[p] = idx++;
  458. }
  459. }
  460. sb.AppendLine(" ctx.PushObject(instance);");
  461. foreach (var p in param)
  462. {
  463. if (p.ParameterType.IsByRef)
  464. {
  465. sb.AppendLine(string.Format(" ctx.PushReference({0});", refIndex[p]));
  466. }
  467. else
  468. {
  469. sb.AppendLine(GetPushString(p.ParameterType, p.Name));
  470. }
  471. }
  472. sb.AppendLine(" ctx.Invoke();");
  473. if (hasReturn)
  474. sb.AppendLine(GetReadString(returnType, rtRealName, "", "__res"));
  475. foreach (var p in param)
  476. {
  477. if (p.ParameterType.IsByRef)
  478. {
  479. p.ParameterType.GetClassName(out clsName, out realClsName, out isByRef, true);
  480. sb.AppendLine(GetReadString(p.ParameterType.GetElementType(), realClsName, refIndex[p].ToString(), p.Name));
  481. }
  482. }
  483. sb.AppendLine(" }");
  484. sb.AppendLine(@" }
  485. finally
  486. {
  487. invoking = false;
  488. }");
  489. if (hasReturn)
  490. sb.AppendLine(" return __res;");
  491. sb.AppendLine(" }");
  492. if (hasReturn)
  493. sb.AppendLine(@" else
  494. return default(TResult);");
  495. sb.AppendLine(@" }
  496. public override void Invoke(ILTypeInstance instance)
  497. {
  498. throw new NotSupportedException();
  499. }
  500. }");
  501. }
  502. static void GetMethods(Type type, List<MethodInfo> list)
  503. {
  504. if (type == null)
  505. return;
  506. MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
  507. foreach (var i in methods)
  508. {
  509. if ((i.IsVirtual || i.IsAbstract || type.IsInterface) && !i.ContainsGenericParameters)
  510. {
  511. if (list.Any(m => IsMethodEqual(m, i)))
  512. continue;
  513. list.Add(i);
  514. }
  515. }
  516. var interfaceArray = type.GetInterfaces();
  517. if (interfaceArray != null)
  518. {
  519. for (int i = 0; i < interfaceArray.Length; ++i)
  520. {
  521. GetMethods(interfaceArray[i], list);
  522. }
  523. }
  524. }
  525. static bool IsMethodEqual(MethodInfo left, MethodInfo right)
  526. {
  527. var leftParams = left.GetParameters();
  528. var rightParams = right.GetParameters();
  529. if (leftParams.Length != rightParams.Length)
  530. {
  531. return false;
  532. }
  533. // 有些继承了多个interface的类,且这几个interface的类有相同函数名的时候,子类实现的接口就会带上interfere的fullName
  534. string leftMethodName = left.Name.Replace(left.DeclaringType.FullName, "");
  535. string rightMethodName = right.Name.Replace(right.DeclaringType.FullName, "");
  536. if (leftMethodName != rightMethodName)
  537. {
  538. return false;
  539. }
  540. for (int i = 0; i < leftParams.Length; ++i)
  541. {
  542. if (leftParams[i].ParameterType != rightParams[i].ParameterType)
  543. {
  544. return false;
  545. }
  546. }
  547. return true;
  548. }
  549. static void GenInitParams(StringBuilder sb, ParameterInfo[] param)
  550. {
  551. foreach (var p in param)
  552. {
  553. if (p.IsOut)
  554. {
  555. sb.AppendLine(string.Format(" {0} = default({1});", p.Name, p.ParameterType.GetElementType().FullName));
  556. }
  557. }
  558. }
  559. static string GetPushString(Type type, string argName)
  560. {
  561. if (type.IsPrimitive)
  562. {
  563. if (type == typeof(int))
  564. {
  565. return string.Format(" ctx.PushInteger({0});", argName);
  566. }
  567. else if (type == typeof(long))
  568. {
  569. return string.Format(" ctx.PushLong({0});", argName);
  570. }
  571. else if (type == typeof(short))
  572. {
  573. return string.Format(" ctx.PushInteger({0});", argName);
  574. }
  575. else if (type == typeof(bool))
  576. {
  577. return string.Format(" ctx.PushBool({0});", argName);
  578. }
  579. else if (type == typeof(ushort))
  580. {
  581. return string.Format(" ctx.PushInteger({0});", argName);
  582. }
  583. else if (type == typeof(float))
  584. {
  585. return string.Format(" ctx.PushFloat({0});", argName);
  586. }
  587. else if (type == typeof(double))
  588. {
  589. return string.Format(" ctx.PushDouble({0});", argName);
  590. }
  591. else if (type == typeof(byte))
  592. {
  593. return string.Format(" ctx.PushInteger({0});", argName);
  594. }
  595. else if (type == typeof(sbyte))
  596. {
  597. return string.Format(" ctx.PushInteger({0});", argName);
  598. }
  599. else if (type == typeof(uint))
  600. {
  601. return string.Format(" ctx.PushInteger((int){0});", argName);
  602. }
  603. else if (type == typeof(char))
  604. {
  605. return string.Format(" ctx.PushInteger((int){0});", argName);
  606. }
  607. else if (type == typeof(ulong))
  608. {
  609. return string.Format(" ctx.PushLong((long){0});", argName);
  610. }
  611. else
  612. throw new NotImplementedException();
  613. }
  614. else
  615. {
  616. return string.Format(" ctx.PushObject({0});", argName);
  617. }
  618. }
  619. static string GetReadString(Type type, string realClsName, string argName, string valName)
  620. {
  621. if (type.IsPrimitive)
  622. {
  623. if (type == typeof(int))
  624. {
  625. return string.Format(" {1} = ctx.ReadInteger({0});", argName, valName);
  626. }
  627. else if (type == typeof(long))
  628. {
  629. return string.Format(" {1} = ctx.ReadLong({0});", argName, valName);
  630. }
  631. else if (type == typeof(short))
  632. {
  633. return string.Format(" {1} = (short)ctx.ReadInteger({0});", argName, valName);
  634. }
  635. else if (type == typeof(bool))
  636. {
  637. return string.Format(" {1} = ctx.ReadBool({0});", argName, valName);
  638. }
  639. else if (type == typeof(ushort))
  640. {
  641. return string.Format(" {1} = (ushort)ctx.ReadInteger({0});", argName, valName);
  642. }
  643. else if (type == typeof(float))
  644. {
  645. return string.Format(" {1} = ctx.ReadFloat({0});", argName, valName);
  646. }
  647. else if (type == typeof(double))
  648. {
  649. return string.Format(" {1} = ctx.ReadDouble({0});", argName, valName);
  650. }
  651. else if (type == typeof(byte))
  652. {
  653. return string.Format(" {1} = (byte)ctx.ReadInteger({0});", argName, valName);
  654. }
  655. else if (type == typeof(sbyte))
  656. {
  657. return string.Format(" {1} = (sbyte)ctx.ReadInteger({0});", argName, valName);
  658. }
  659. else if (type == typeof(uint))
  660. {
  661. return string.Format(" {1} = (uint)ctx.ReadInteger({0});", argName, valName);
  662. }
  663. else if (type == typeof(char))
  664. {
  665. return string.Format(" {1} = (char)ctx.ReadInteger({0});", argName, valName);
  666. }
  667. else if (type == typeof(ulong))
  668. {
  669. return string.Format(" {1} = (ulong)ctx.ReadLong({0});", argName, valName);
  670. }
  671. else
  672. throw new NotImplementedException();
  673. }
  674. else
  675. {
  676. return string.Format(" {2} = ctx.ReadObject<{1}>({0});", argName, realClsName, valName);
  677. }
  678. }
  679. }
  680. }