PageRenderTime 63ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/NRefactory/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs

http://github.com/icsharpcode/ILSpy
C# | 2282 lines | 1898 code | 359 blank | 25 comment | 266 complexity | 9cc08f9a5125d3b1ef3bac7e12e363a3 MD5 | raw file
Possible License(s): LGPL-2.1, MIT, CC-BY-SA-3.0
  1. // Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
  2. // This code is distributed under MIT X11 license (for details please see \doc\license.txt)
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using ICSharpCode.NRefactory.PatternMatching;
  7. using ICSharpCode.NRefactory.TypeSystem;
  8. using ICSharpCode.NRefactory.VB.Ast;
  9. namespace ICSharpCode.NRefactory.VB.Visitors
  10. {
  11. public interface IEnvironmentProvider
  12. {
  13. string RootNamespace { get; }
  14. string GetTypeNameForAttribute(CSharp.Attribute attribute);
  15. TypeKind GetTypeKindForAstType(CSharp.AstType type);
  16. TypeCode ResolveExpression(CSharp.Expression expression);
  17. bool? IsReferenceType(CSharp.Expression expression);
  18. //ITypeResolveContext ResolveContext { get; }
  19. IType ResolveType(AstType type, TypeDeclaration entity = null);
  20. bool IsMethodGroup(CSharp.Expression expression);
  21. bool HasEvent(Expression expression);
  22. }
  23. /// <summary>
  24. /// Description of CSharpToVBConverterVisitor.
  25. /// </summary>
  26. public class CSharpToVBConverterVisitor : CSharp.IAstVisitor<object, VB.AstNode>
  27. {
  28. IEnvironmentProvider provider;
  29. Stack<BlockStatement> blocks;
  30. Stack<TypeDeclaration> types;
  31. Stack<MemberInfo> members;
  32. class MemberInfo
  33. {
  34. public bool inIterator;
  35. }
  36. public CSharpToVBConverterVisitor(IEnvironmentProvider provider)
  37. {
  38. this.provider = provider;
  39. this.blocks = new Stack<BlockStatement>();
  40. this.types = new Stack<TypeDeclaration>();
  41. this.members = new Stack<MemberInfo>();
  42. }
  43. public AstNode VisitAnonymousMethodExpression(CSharp.AnonymousMethodExpression anonymousMethodExpression, object data)
  44. {
  45. members.Push(new MemberInfo());
  46. var expr = new MultiLineLambdaExpression() {
  47. IsSub = true,
  48. Body = (BlockStatement)anonymousMethodExpression.Body.AcceptVisitor(this, data)
  49. };
  50. ConvertNodes(anonymousMethodExpression.Parameters, expr.Parameters);
  51. if (members.Pop().inIterator) {
  52. expr.Modifiers |= LambdaExpressionModifiers.Iterator;
  53. }
  54. return EndNode(anonymousMethodExpression, expr);
  55. }
  56. public AstNode VisitUndocumentedExpression(CSharp.UndocumentedExpression undocumentedExpression, object data)
  57. {
  58. var invocation = new InvocationExpression();
  59. switch (undocumentedExpression.UndocumentedExpressionType) {
  60. case CSharp.UndocumentedExpressionType.ArgListAccess:
  61. case CSharp.UndocumentedExpressionType.ArgList:
  62. invocation.Target = new IdentifierExpression { Identifier = "__ArgList" };
  63. break;
  64. case CSharp.UndocumentedExpressionType.RefValue:
  65. invocation.Target = new IdentifierExpression { Identifier = "__RefValue" };
  66. break;
  67. case CSharp.UndocumentedExpressionType.RefType:
  68. invocation.Target = new IdentifierExpression { Identifier = "__RefType" };
  69. break;
  70. case CSharp.UndocumentedExpressionType.MakeRef:
  71. invocation.Target = new IdentifierExpression { Identifier = "__MakeRef" };
  72. break;
  73. default:
  74. throw new Exception("Invalid value for UndocumentedExpressionType");
  75. }
  76. ConvertNodes(undocumentedExpression.Arguments, invocation.Arguments);
  77. return EndNode(undocumentedExpression, invocation);
  78. }
  79. public AstNode VisitArrayCreateExpression(CSharp.ArrayCreateExpression arrayCreateExpression, object data)
  80. {
  81. var expr = new ArrayCreateExpression() {
  82. Type = (AstType)arrayCreateExpression.Type.AcceptVisitor(this, data),
  83. Initializer = (ArrayInitializerExpression)arrayCreateExpression.Initializer.AcceptVisitor(this, data)
  84. };
  85. ConvertNodes(arrayCreateExpression.Arguments, expr.Arguments,
  86. n => new BinaryOperatorExpression(n, BinaryOperatorType.Subtract, new PrimitiveExpression(1)));
  87. ConvertNodes(arrayCreateExpression.AdditionalArraySpecifiers, expr.AdditionalArraySpecifiers);
  88. return EndNode(arrayCreateExpression, expr);
  89. }
  90. public AstNode VisitArrayInitializerExpression(CSharp.ArrayInitializerExpression arrayInitializerExpression, object data)
  91. {
  92. var expr = new ArrayInitializerExpression();
  93. ConvertNodes(arrayInitializerExpression.Elements, expr.Elements);
  94. return EndNode(arrayInitializerExpression, expr);
  95. }
  96. public AstNode VisitAsExpression(CSharp.AsExpression asExpression, object data)
  97. {
  98. return EndNode(asExpression, new CastExpression(CastType.TryCast, (AstType)asExpression.Type.AcceptVisitor(this, data), (Expression)asExpression.Expression.AcceptVisitor(this, data)));
  99. }
  100. public AstNode VisitAssignmentExpression(CSharp.AssignmentExpression assignmentExpression, object data)
  101. {
  102. var left = (Expression)assignmentExpression.Left.AcceptVisitor(this, data);
  103. var op = AssignmentOperatorType.None;
  104. var right = (Expression)assignmentExpression.Right.AcceptVisitor(this, data);
  105. switch (assignmentExpression.Operator) {
  106. case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Assign:
  107. op = AssignmentOperatorType.Assign;
  108. break;
  109. case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Add:
  110. if (provider.HasEvent(left)) {
  111. var addHandler = new AddRemoveHandlerStatement { IsAddHandler = true };
  112. addHandler.EventExpression = left;
  113. addHandler.DelegateExpression = right;
  114. return EndNode(assignmentExpression, addHandler);
  115. }
  116. op = AssignmentOperatorType.Add;
  117. break;
  118. case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Subtract:
  119. if (provider.HasEvent(left)) {
  120. var addHandler = new AddRemoveHandlerStatement { IsAddHandler = false };
  121. addHandler.EventExpression = left;
  122. addHandler.DelegateExpression = right;
  123. return EndNode(assignmentExpression, addHandler);
  124. }
  125. op = AssignmentOperatorType.Subtract;
  126. break;
  127. case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Multiply:
  128. op = AssignmentOperatorType.Multiply;
  129. break;
  130. case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Divide:
  131. op = AssignmentOperatorType.Divide;
  132. break;
  133. case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Modulus:
  134. op = AssignmentOperatorType.Assign;
  135. right = new BinaryOperatorExpression((Expression)left.Clone(), BinaryOperatorType.Modulus, right);
  136. break;
  137. case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.ShiftLeft:
  138. op = AssignmentOperatorType.ShiftLeft;
  139. break;
  140. case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.ShiftRight:
  141. op = AssignmentOperatorType.ShiftRight;
  142. break;
  143. case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.BitwiseAnd:
  144. op = AssignmentOperatorType.Assign;
  145. right = new BinaryOperatorExpression((Expression)left.Clone(), BinaryOperatorType.BitwiseAnd, right);
  146. break;
  147. case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.BitwiseOr:
  148. op = AssignmentOperatorType.Assign;
  149. right = new BinaryOperatorExpression((Expression)left.Clone(), BinaryOperatorType.BitwiseOr, right);
  150. break;
  151. case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.ExclusiveOr:
  152. op = AssignmentOperatorType.Assign;
  153. right = new BinaryOperatorExpression((Expression)left.Clone(), BinaryOperatorType.ExclusiveOr, right);
  154. break;
  155. default:
  156. throw new Exception("Invalid value for AssignmentOperatorType: " + assignmentExpression.Operator);
  157. }
  158. var expr = new AssignmentExpression(left, op, right);
  159. return EndNode(assignmentExpression, expr);
  160. }
  161. public AstNode VisitBaseReferenceExpression(CSharp.BaseReferenceExpression baseReferenceExpression, object data)
  162. {
  163. InstanceExpression result = new InstanceExpression(InstanceExpressionType.MyBase, baseReferenceExpression.StartLocation);
  164. return EndNode(baseReferenceExpression, result);
  165. }
  166. public AstNode VisitBinaryOperatorExpression(CSharp.BinaryOperatorExpression binaryOperatorExpression, object data)
  167. {
  168. var left = (Expression)binaryOperatorExpression.Left.AcceptVisitor(this, data);
  169. var op = BinaryOperatorType.None;
  170. var right = (Expression)binaryOperatorExpression.Right.AcceptVisitor(this, data);
  171. switch (binaryOperatorExpression.Operator) {
  172. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.BitwiseAnd:
  173. op = BinaryOperatorType.BitwiseAnd;
  174. break;
  175. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.BitwiseOr:
  176. op = BinaryOperatorType.BitwiseOr;
  177. break;
  178. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.ConditionalAnd:
  179. op = BinaryOperatorType.LogicalAnd;
  180. break;
  181. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.ConditionalOr:
  182. op = BinaryOperatorType.LogicalOr;
  183. break;
  184. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.ExclusiveOr:
  185. op = BinaryOperatorType.ExclusiveOr;
  186. break;
  187. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.GreaterThan:
  188. op = BinaryOperatorType.GreaterThan;
  189. break;
  190. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.GreaterThanOrEqual:
  191. op = BinaryOperatorType.GreaterThanOrEqual;
  192. break;
  193. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.Equality:
  194. if (IsReferentialEquality(binaryOperatorExpression))
  195. op = BinaryOperatorType.ReferenceEquality;
  196. else
  197. op = BinaryOperatorType.Equality;
  198. break;
  199. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.InEquality:
  200. if (IsReferentialEquality(binaryOperatorExpression))
  201. op = BinaryOperatorType.ReferenceInequality;
  202. else
  203. op = BinaryOperatorType.InEquality;
  204. break;
  205. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.LessThan:
  206. op = BinaryOperatorType.LessThan;
  207. break;
  208. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.LessThanOrEqual:
  209. op = BinaryOperatorType.LessThanOrEqual;
  210. break;
  211. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.Add:
  212. // TODO might be string concatenation
  213. op = BinaryOperatorType.Add;
  214. break;
  215. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.Subtract:
  216. op = BinaryOperatorType.Subtract;
  217. break;
  218. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.Multiply:
  219. op = BinaryOperatorType.Multiply;
  220. break;
  221. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.Divide:
  222. op = BinaryOperatorType.Divide;
  223. break;
  224. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.Modulus:
  225. op = BinaryOperatorType.Modulus;
  226. break;
  227. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.ShiftLeft:
  228. op = BinaryOperatorType.ShiftLeft;
  229. break;
  230. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.ShiftRight:
  231. op = BinaryOperatorType.ShiftRight;
  232. break;
  233. case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.NullCoalescing:
  234. var nullCoalescing = new ConditionalExpression {
  235. ConditionExpression = left,
  236. FalseExpression = right
  237. };
  238. return EndNode(binaryOperatorExpression, nullCoalescing);
  239. default:
  240. throw new Exception("Invalid value for BinaryOperatorType: " + binaryOperatorExpression.Operator);
  241. }
  242. return EndNode(binaryOperatorExpression, new BinaryOperatorExpression(left, op, right));
  243. }
  244. bool IsReferentialEquality(CSharp.BinaryOperatorExpression binaryOperatorExpression)
  245. {
  246. var left = provider.IsReferenceType(binaryOperatorExpression.Left);
  247. var right = provider.IsReferenceType(binaryOperatorExpression.Right);
  248. var leftCode = provider.ResolveExpression(binaryOperatorExpression.Left);
  249. var rightCode = provider.ResolveExpression(binaryOperatorExpression.Right);
  250. return (left == true || right == true) && (leftCode != TypeCode.String && rightCode != TypeCode.String);
  251. }
  252. public AstNode VisitCastExpression(CSharp.CastExpression castExpression, object data)
  253. {
  254. var expr = new CastExpression();
  255. expr.Type = (AstType)castExpression.Type.AcceptVisitor(this, data);
  256. // TODO read additional type information from annotation
  257. // (int)x is equivalent to CInt(Math.Truncate(x))
  258. expr.CastType = GetCastType(expr.Type, null);
  259. expr.Expression = (Expression)castExpression.Expression.AcceptVisitor(this, data);
  260. if (expr.CastType != CastType.CType)
  261. expr.Type = null;
  262. return EndNode(castExpression, expr);
  263. }
  264. CastType GetCastType(AstType type, object typeInformation)
  265. {
  266. var primType = type as PrimitiveType;
  267. if (primType == null)
  268. return CastType.CType;
  269. switch (primType.Keyword) {
  270. case "Boolean":
  271. return CastType.CBool;
  272. case "Byte":
  273. return CastType.CByte;
  274. case "Char":
  275. return CastType.CChar;
  276. case "Date":
  277. return CastType.CDate;
  278. case "Double":
  279. return CastType.CDbl;
  280. case "Decimal":
  281. return CastType.CDec;
  282. case "Integer":
  283. return CastType.CInt;
  284. case "Long":
  285. return CastType.CLng;
  286. case "Object":
  287. return CastType.CObj;
  288. case "SByte":
  289. return CastType.CSByte;
  290. case "Short":
  291. return CastType.CShort;
  292. case "Single":
  293. return CastType.CSng;
  294. case "String":
  295. return CastType.CStr;
  296. case "UInteger":
  297. return CastType.CUInt;
  298. case "ULong":
  299. return CastType.CULng;
  300. case "UShort":
  301. return CastType.CUShort;
  302. }
  303. return CastType.CType;
  304. }
  305. public AstNode VisitCheckedExpression(CSharp.CheckedExpression checkedExpression, object data)
  306. {
  307. blocks.Peek().AddChild(new Comment(" The following expression was wrapped in a checked-expression", false), AstNode.Roles.Comment);
  308. return EndNode(checkedExpression, checkedExpression.Expression.AcceptVisitor(this, data));
  309. }
  310. public AstNode VisitConditionalExpression(CSharp.ConditionalExpression conditionalExpression, object data)
  311. {
  312. var cond = new ConditionalExpression() {
  313. ConditionExpression = (Expression)conditionalExpression.Condition.AcceptVisitor(this, data),
  314. TrueExpression = (Expression)conditionalExpression.TrueExpression.AcceptVisitor(this, data),
  315. FalseExpression = (Expression)conditionalExpression.FalseExpression.AcceptVisitor(this, data)
  316. };
  317. return EndNode(conditionalExpression, cond);
  318. }
  319. public AstNode VisitDefaultValueExpression(CSharp.DefaultValueExpression defaultValueExpression, object data)
  320. {
  321. // Nothing is equivalent to default(T) for reference and value types.
  322. return EndNode(defaultValueExpression, new PrimitiveExpression(null));
  323. }
  324. public AstNode VisitDirectionExpression(CSharp.DirectionExpression directionExpression, object data)
  325. {
  326. return EndNode(directionExpression, (Expression)directionExpression.Expression.AcceptVisitor(this, data));
  327. }
  328. public AstNode VisitIdentifierExpression(CSharp.IdentifierExpression identifierExpression, object data)
  329. {
  330. var expr = new IdentifierExpression();
  331. expr.Identifier = new Identifier(identifierExpression.Identifier, TextLocation.Empty);
  332. ConvertNodes(identifierExpression.TypeArguments, expr.TypeArguments);
  333. if (provider.IsMethodGroup(identifierExpression)) {
  334. return EndNode(identifierExpression, new UnaryOperatorExpression(UnaryOperatorType.AddressOf, expr));
  335. }
  336. return EndNode(identifierExpression, expr);
  337. }
  338. public AstNode VisitIndexerExpression(CSharp.IndexerExpression indexerExpression, object data)
  339. {
  340. var expr = new InvocationExpression((Expression)indexerExpression.Target.AcceptVisitor(this, data));
  341. ConvertNodes(indexerExpression.Arguments, expr.Arguments);
  342. return EndNode(indexerExpression, expr);
  343. }
  344. public AstNode VisitInvocationExpression(CSharp.InvocationExpression invocationExpression, object data)
  345. {
  346. var expr = new InvocationExpression((Expression)invocationExpression.Target.AcceptVisitor(this, data));
  347. ConvertNodes(invocationExpression.Arguments, expr.Arguments);
  348. return EndNode(invocationExpression, expr);
  349. }
  350. public AstNode VisitIsExpression(CSharp.IsExpression isExpression, object data)
  351. {
  352. var expr = new TypeOfIsExpression() {
  353. Type = (AstType)isExpression.Type.AcceptVisitor(this, data),
  354. TypeOfExpression = (Expression)isExpression.Expression.AcceptVisitor(this, data)
  355. };
  356. return EndNode(isExpression, expr);
  357. }
  358. public AstNode VisitLambdaExpression(CSharp.LambdaExpression lambdaExpression, object data)
  359. {
  360. LambdaExpression expr = null;
  361. if (lambdaExpression.Body is CSharp.Expression) {
  362. var singleLine = new SingleLineFunctionLambdaExpression() {
  363. EmbeddedExpression = (Expression)lambdaExpression.Body.AcceptVisitor(this, data)
  364. };
  365. ConvertNodes(lambdaExpression.Parameters, singleLine.Parameters);
  366. expr = singleLine;
  367. } else
  368. throw new NotImplementedException();
  369. return EndNode(lambdaExpression, expr);
  370. }
  371. public AstNode VisitMemberReferenceExpression(CSharp.MemberReferenceExpression memberReferenceExpression, object data)
  372. {
  373. var memberAccessExpression = new MemberAccessExpression();
  374. memberAccessExpression.Target = (Expression)memberReferenceExpression.Target.AcceptVisitor(this, data);
  375. memberAccessExpression.MemberName = new Identifier(memberReferenceExpression.MemberName, TextLocation.Empty);
  376. ConvertNodes(memberReferenceExpression.TypeArguments, memberAccessExpression.TypeArguments);
  377. if (provider.IsMethodGroup(memberReferenceExpression)) {
  378. return EndNode(memberReferenceExpression, new UnaryOperatorExpression(UnaryOperatorType.AddressOf, memberAccessExpression));
  379. }
  380. return EndNode(memberReferenceExpression, memberAccessExpression);
  381. }
  382. public AstNode VisitNamedArgumentExpression(CSharp.NamedArgumentExpression namedArgumentExpression, object data)
  383. {
  384. Expression expr = new NamedArgumentExpression {
  385. Identifier = namedArgumentExpression.Name,
  386. Expression = (Expression)namedArgumentExpression.Expression.AcceptVisitor(this, data)
  387. };
  388. return EndNode(namedArgumentExpression, expr);
  389. }
  390. public AstNode VisitNamedExpression(CSharp.NamedExpression namedExpression, object data)
  391. {
  392. Expression expr = new FieldInitializerExpression {
  393. IsKey = true,
  394. Identifier = namedExpression.Name,
  395. Expression = (Expression)namedExpression.Expression.AcceptVisitor(this, data)
  396. };
  397. return EndNode(namedExpression, expr);
  398. }
  399. public AstNode VisitNullReferenceExpression(CSharp.NullReferenceExpression nullReferenceExpression, object data)
  400. {
  401. return EndNode(nullReferenceExpression, new PrimitiveExpression(null));
  402. }
  403. public AstNode VisitObjectCreateExpression(CSharp.ObjectCreateExpression objectCreateExpression, object data)
  404. {
  405. var expr = new ObjectCreationExpression((AstType)objectCreateExpression.Type.AcceptVisitor(this, data));
  406. ConvertNodes(objectCreateExpression.Arguments, expr.Arguments);
  407. var arg1 = expr.Arguments.FirstOrDefault() as UnaryOperatorExpression;
  408. if (arg1 != null && arg1.Operator == UnaryOperatorType.AddressOf) {
  409. arg1.Remove();
  410. return EndNode(objectCreateExpression, arg1);
  411. }
  412. if (!objectCreateExpression.Initializer.IsNull)
  413. expr.Initializer = (ArrayInitializerExpression)objectCreateExpression.Initializer.AcceptVisitor(this, data);
  414. return EndNode(objectCreateExpression, expr);
  415. }
  416. public AstNode VisitAnonymousTypeCreateExpression(CSharp.AnonymousTypeCreateExpression anonymousTypeCreateExpression, object data)
  417. {
  418. var expr = new AnonymousObjectCreationExpression();
  419. ConvertNodes(anonymousTypeCreateExpression.Initializers, expr.Initializer);
  420. return EndNode(anonymousTypeCreateExpression, expr);
  421. }
  422. public AstNode VisitParenthesizedExpression(CSharp.ParenthesizedExpression parenthesizedExpression, object data)
  423. {
  424. var result = new ParenthesizedExpression();
  425. result.Expression = (Expression)parenthesizedExpression.Expression.AcceptVisitor(this, data);
  426. return EndNode(parenthesizedExpression, result);
  427. }
  428. public AstNode VisitPointerReferenceExpression(CSharp.PointerReferenceExpression pointerReferenceExpression, object data)
  429. {
  430. return EndNode(pointerReferenceExpression,((Expression)pointerReferenceExpression.Target.AcceptVisitor(this, data)).Invoke("Dereference").Member(pointerReferenceExpression.MemberName));
  431. }
  432. public AstNode VisitPrimitiveExpression(CSharp.PrimitiveExpression primitiveExpression, object data)
  433. {
  434. Expression expr;
  435. if (!string.IsNullOrEmpty(primitiveExpression.Value as string) || primitiveExpression.Value is char)
  436. expr = ConvertToConcat(primitiveExpression.Value.ToString());
  437. else
  438. expr = new PrimitiveExpression(primitiveExpression.Value);
  439. return EndNode(primitiveExpression, expr);
  440. }
  441. Expression ConvertToConcat(string literal)
  442. {
  443. Stack<Expression> parts = new Stack<Expression>();
  444. int start = 0;
  445. for (int i = 0; i < literal.Length; i++) {
  446. string part;
  447. switch (literal[i]) {
  448. case '\0':
  449. part = literal.Substring(start, i - start);
  450. if (!string.IsNullOrEmpty(part))
  451. parts.Push(new PrimitiveExpression(part));
  452. parts.Push(new IdentifierExpression("vbNullChar"));
  453. start = i + 1;
  454. break;
  455. case '\b':
  456. part = literal.Substring(start, i - start);
  457. if (!string.IsNullOrEmpty(part))
  458. parts.Push(new PrimitiveExpression(part));
  459. parts.Push(new IdentifierExpression("vbBack"));
  460. start = i + 1;
  461. break;
  462. case '\f':
  463. part = literal.Substring(start, i - start);
  464. if (!string.IsNullOrEmpty(part))
  465. parts.Push(new PrimitiveExpression(part));
  466. parts.Push(new IdentifierExpression("vbFormFeed"));
  467. start = i + 1;
  468. break;
  469. case '\r':
  470. part = literal.Substring(start, i - start);
  471. if (!string.IsNullOrEmpty(part))
  472. parts.Push(new PrimitiveExpression(part));
  473. if (i + 1 < literal.Length && literal[i + 1] == '\n') {
  474. i++;
  475. parts.Push(new IdentifierExpression("vbCrLf"));
  476. } else
  477. parts.Push(new IdentifierExpression("vbCr"));
  478. start = i + 1;
  479. break;
  480. case '\n':
  481. part = literal.Substring(start, i - start);
  482. if (!string.IsNullOrEmpty(part))
  483. parts.Push(new PrimitiveExpression(part));
  484. parts.Push(new IdentifierExpression("vbLf"));
  485. start = i + 1;
  486. break;
  487. case '\t':
  488. part = literal.Substring(start, i - start);
  489. if (!string.IsNullOrEmpty(part))
  490. parts.Push(new PrimitiveExpression(part));
  491. parts.Push(new IdentifierExpression("vbTab"));
  492. start = i + 1;
  493. break;
  494. case '\v':
  495. part = literal.Substring(start, i - start);
  496. if (!string.IsNullOrEmpty(part))
  497. parts.Push(new PrimitiveExpression(part));
  498. parts.Push(new IdentifierExpression("vbVerticalTab"));
  499. start = i + 1;
  500. break;
  501. default:
  502. if ((int)literal[i] > 255) {
  503. part = literal.Substring(start, i - start);
  504. if (!string.IsNullOrEmpty(part))
  505. parts.Push(new PrimitiveExpression(part));
  506. parts.Push(new InvocationExpression(new IdentifierExpression("ChrW"), new PrimitiveExpression((int)literal[i])));
  507. } else
  508. continue;
  509. start = i + 1;
  510. break;
  511. }
  512. }
  513. if (start < literal.Length) {
  514. string part = literal.Substring(start);
  515. parts.Push(new PrimitiveExpression(part));
  516. }
  517. Expression current = parts.Pop();
  518. while (parts.Any())
  519. current = new BinaryOperatorExpression(parts.Pop(), BinaryOperatorType.Concat, current);
  520. return current;
  521. }
  522. public AstNode VisitSizeOfExpression(CSharp.SizeOfExpression sizeOfExpression, object data)
  523. {
  524. return EndNode(
  525. sizeOfExpression,
  526. new InvocationExpression(
  527. new IdentifierExpression() { Identifier = "__SizeOf" },
  528. new TypeReferenceExpression((AstType)sizeOfExpression.Type.AcceptVisitor(this, data))
  529. )
  530. );
  531. }
  532. public AstNode VisitStackAllocExpression(CSharp.StackAllocExpression stackAllocExpression, object data)
  533. {
  534. return EndNode(
  535. stackAllocExpression,
  536. new InvocationExpression(
  537. new IdentifierExpression() { Identifier = "__StackAlloc" },
  538. new TypeReferenceExpression((AstType)stackAllocExpression.Type.AcceptVisitor(this, data)),
  539. (Expression)stackAllocExpression.CountExpression.AcceptVisitor(this, data)
  540. )
  541. );
  542. }
  543. public AstNode VisitThisReferenceExpression(CSharp.ThisReferenceExpression thisReferenceExpression, object data)
  544. {
  545. InstanceExpression result = new InstanceExpression(InstanceExpressionType.Me, thisReferenceExpression.StartLocation);
  546. return EndNode(thisReferenceExpression, result);
  547. }
  548. public AstNode VisitTypeOfExpression(CSharp.TypeOfExpression typeOfExpression, object data)
  549. {
  550. var expr = new GetTypeExpression();
  551. expr.Type = (AstType)typeOfExpression.Type.AcceptVisitor(this, data);
  552. return EndNode(typeOfExpression, expr);
  553. }
  554. public AstNode VisitTypeReferenceExpression(CSharp.TypeReferenceExpression typeReferenceExpression, object data)
  555. {
  556. var expr = new TypeReferenceExpression((AstType)typeReferenceExpression.Type.AcceptVisitor(this, data));
  557. return EndNode(typeReferenceExpression, expr);
  558. }
  559. public AstNode VisitUnaryOperatorExpression(CSharp.UnaryOperatorExpression unaryOperatorExpression, object data)
  560. {
  561. Expression expr;
  562. switch (unaryOperatorExpression.Operator) {
  563. case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.Not:
  564. case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.BitNot:
  565. expr = new UnaryOperatorExpression() {
  566. Expression = (Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data),
  567. Operator = UnaryOperatorType.Not
  568. };
  569. break;
  570. case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.Minus:
  571. expr = new UnaryOperatorExpression() {
  572. Expression = (Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data),
  573. Operator = UnaryOperatorType.Minus
  574. };
  575. break;
  576. case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.Plus:
  577. expr = new UnaryOperatorExpression() {
  578. Expression = (Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data),
  579. Operator = UnaryOperatorType.Plus
  580. };
  581. break;
  582. case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.Increment:
  583. expr = new InvocationExpression();
  584. ((InvocationExpression)expr).Target = new IdentifierExpression() { Identifier = "__Increment" };
  585. ((InvocationExpression)expr).Arguments.Add((Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data));
  586. break;
  587. case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.PostIncrement:
  588. expr = new InvocationExpression();
  589. ((InvocationExpression)expr).Target = new IdentifierExpression() { Identifier = "__PostIncrement" };
  590. ((InvocationExpression)expr).Arguments.Add((Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data));
  591. break;
  592. case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.Decrement:
  593. expr = new InvocationExpression();
  594. ((InvocationExpression)expr).Target = new IdentifierExpression() { Identifier = "__Decrement" };
  595. ((InvocationExpression)expr).Arguments.Add((Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data));
  596. break;
  597. case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.PostDecrement:
  598. expr = new InvocationExpression();
  599. ((InvocationExpression)expr).Target = new IdentifierExpression() { Identifier = "__PostDecrement" };
  600. ((InvocationExpression)expr).Arguments.Add((Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data));
  601. break;
  602. case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.AddressOf:
  603. expr = new UnaryOperatorExpression() {
  604. Expression = (Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data),
  605. Operator = UnaryOperatorType.AddressOf
  606. };
  607. break;
  608. case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.Dereference:
  609. expr = new InvocationExpression();
  610. ((InvocationExpression)expr).Target = new IdentifierExpression() { Identifier = "__Dereference" };
  611. ((InvocationExpression)expr).Arguments.Add((Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data));
  612. break;
  613. case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.Await:
  614. expr = new UnaryOperatorExpression() {
  615. Expression = (Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data),
  616. Operator = UnaryOperatorType.Await
  617. };
  618. break;
  619. default:
  620. throw new Exception("Invalid value for UnaryOperatorType");
  621. }
  622. return EndNode(unaryOperatorExpression, expr);
  623. }
  624. public AstNode VisitUncheckedExpression(CSharp.UncheckedExpression uncheckedExpression, object data)
  625. {
  626. blocks.Peek().AddChild(new Comment(" The following expression was wrapped in a unchecked-expression", false), AstNode.Roles.Comment);
  627. return EndNode(uncheckedExpression, uncheckedExpression.Expression.AcceptVisitor(this, data));
  628. }
  629. public AstNode VisitQueryExpression(CSharp.QueryExpression queryExpression, object data)
  630. {
  631. var expr = new QueryExpression();
  632. ConvertNodes(queryExpression.Clauses, expr.QueryOperators);
  633. return EndNode(queryExpression, expr);
  634. }
  635. public AstNode VisitQueryContinuationClause(CSharp.QueryContinuationClause queryContinuationClause, object data)
  636. {
  637. throw new NotImplementedException();
  638. }
  639. public AstNode VisitQueryFromClause(CSharp.QueryFromClause queryFromClause, object data)
  640. {
  641. var op = new FromQueryOperator();
  642. op.Variables.Add(
  643. new CollectionRangeVariableDeclaration {
  644. Identifier = new VariableIdentifier { Name = queryFromClause.Identifier },
  645. Type = (AstType)queryFromClause.Type.AcceptVisitor(this, data),
  646. Expression = (Expression)queryFromClause.Expression.AcceptVisitor(this, data)
  647. }
  648. );
  649. return EndNode(queryFromClause, op);
  650. }
  651. public AstNode VisitQueryLetClause(CSharp.QueryLetClause queryLetClause, object data)
  652. {
  653. throw new NotImplementedException();
  654. }
  655. public AstNode VisitQueryWhereClause(CSharp.QueryWhereClause queryWhereClause, object data)
  656. {
  657. throw new NotImplementedException();
  658. }
  659. public AstNode VisitQueryJoinClause(CSharp.QueryJoinClause queryJoinClause, object data)
  660. {
  661. throw new NotImplementedException();
  662. }
  663. public AstNode VisitQueryOrderClause(CSharp.QueryOrderClause queryOrderClause, object data)
  664. {
  665. var op = new OrderByQueryOperator();
  666. ConvertNodes(queryOrderClause.Orderings, op.Expressions);
  667. return EndNode(queryOrderClause, op);
  668. }
  669. public AstNode VisitQueryOrdering(CSharp.QueryOrdering queryOrdering, object data)
  670. {
  671. var expr = new OrderExpression();
  672. expr.Direction = (QueryOrderingDirection)queryOrdering.Direction;
  673. expr.Expression = (Expression)queryOrdering.Expression.AcceptVisitor(this, data);
  674. return EndNode(queryOrdering, expr);
  675. }
  676. int selectVarCount = 0;
  677. public AstNode VisitQuerySelectClause(CSharp.QuerySelectClause querySelectClause, object data)
  678. {
  679. var op = new SelectQueryOperator();
  680. op.Variables.Add(
  681. new VariableInitializer {
  682. Identifier = new VariableIdentifier { Name = "SelectVar" + selectVarCount },
  683. Expression = (Expression)querySelectClause.Expression.AcceptVisitor(this, data)
  684. });
  685. return EndNode(querySelectClause, op);
  686. }
  687. public AstNode VisitQueryGroupClause(CSharp.QueryGroupClause queryGroupClause, object data)
  688. {
  689. var op = new GroupByQueryOperator();
  690. throw new NotImplementedException();
  691. //return EndNode(queryGroupClause, op);
  692. }
  693. public AstNode VisitAttribute(CSharp.Attribute attribute, object data)
  694. {
  695. var attr = new VB.Ast.Attribute();
  696. AttributeTarget target;
  697. Enum.TryParse(((CSharp.AttributeSection)attribute.Parent).AttributeTarget, true, out target);
  698. attr.Target = target;
  699. attr.Type = (AstType)attribute.Type.AcceptVisitor(this, data);
  700. ConvertNodes(attribute.Arguments, attr.Arguments);
  701. return EndNode(attribute, attr);
  702. }
  703. public AstNode VisitAttributeSection(CSharp.AttributeSection attributeSection, object data)
  704. {
  705. AttributeBlock block = new AttributeBlock();
  706. ConvertNodes(attributeSection.Attributes, block.Attributes);
  707. return EndNode(attributeSection, block);
  708. }
  709. public AstNode VisitDelegateDeclaration(CSharp.DelegateDeclaration delegateDeclaration, object data)
  710. {
  711. var result = new DelegateDeclaration();
  712. ConvertNodes(delegateDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), result.Attributes);
  713. ConvertNodes(delegateDeclaration.ModifierTokens, result.ModifierTokens);
  714. result.Name = new Identifier(delegateDeclaration.Name, TextLocation.Empty);
  715. result.IsSub = IsSub(delegateDeclaration.ReturnType);
  716. ConvertNodes(delegateDeclaration.Parameters, result.Parameters);
  717. ConvertNodes(delegateDeclaration.TypeParameters, result.TypeParameters);
  718. ConvertNodes(delegateDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), result.ReturnTypeAttributes);
  719. if (!result.IsSub)
  720. result.ReturnType = (AstType)delegateDeclaration.ReturnType.AcceptVisitor(this, data);
  721. return EndNode(delegateDeclaration, result);
  722. }
  723. public AstNode VisitNamespaceDeclaration(CSharp.NamespaceDeclaration namespaceDeclaration, object data)
  724. {
  725. var newNamespace = new NamespaceDeclaration();
  726. foreach (string id in namespaceDeclaration.Identifiers) {
  727. newNamespace.Identifiers.Add(new Identifier(id, TextLocation.Empty));
  728. }
  729. ConvertNodes(namespaceDeclaration.Members, newNamespace.Members);
  730. return EndNode(namespaceDeclaration, newNamespace);
  731. }
  732. public AstNode VisitTypeDeclaration(CSharp.TypeDeclaration typeDeclaration, object data)
  733. {
  734. // TODO add missing features!
  735. if (typeDeclaration.ClassType == CSharp.ClassType.Enum) {
  736. var type = new EnumDeclaration();
  737. CopyAnnotations(typeDeclaration, type);
  738. ConvertNodes(typeDeclaration.Attributes, type.Attributes);
  739. ConvertNodes(typeDeclaration.ModifierTokens, type.ModifierTokens);
  740. if (typeDeclaration.BaseTypes.Any()) {
  741. var first = typeDeclaration.BaseTypes.First();
  742. type.UnderlyingType = (AstType)first.AcceptVisitor(this, data);
  743. }
  744. type.Name = new Identifier(typeDeclaration.Name, TextLocation.Empty);
  745. ConvertNodes(typeDeclaration.Members, type.Members);
  746. return EndNode(typeDeclaration, type);
  747. } else {
  748. var type = new TypeDeclaration();
  749. CopyAnnotations(typeDeclaration, type);
  750. CSharp.Attribute stdModAttr;
  751. if (typeDeclaration.ClassType == CSharp.ClassType.Class && HasAttribute(typeDeclaration.Attributes, "Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute", out stdModAttr)) {
  752. type.ClassType = ClassType.Module;
  753. // remove AttributeSection if only one attribute is present
  754. var attrSec = (CSharp.AttributeSection)stdModAttr.Parent;
  755. if (attrSec.Attributes.Count == 1)
  756. attrSec.Remove();
  757. else
  758. stdModAttr.Remove();
  759. } else {
  760. switch (typeDeclaration.ClassType) {
  761. case CSharp.ClassType.Class:
  762. type.ClassType = ClassType.Class;
  763. break;
  764. case CSharp.ClassType.Struct:
  765. type.ClassType = ClassType.Struct;
  766. break;
  767. case CSharp.ClassType.Interface:
  768. type.ClassType = ClassType.Interface;
  769. break;
  770. default:
  771. throw new InvalidOperationException("Invalid value for ClassType");
  772. }
  773. }
  774. if ((typeDeclaration.Modifiers & CSharp.Modifiers.Static) == CSharp.Modifiers.Static) {
  775. type.ClassType = ClassType.Module;
  776. typeDeclaration.Modifiers &= ~CSharp.Modifiers.Static;
  777. }
  778. ConvertNodes(typeDeclaration.Attributes, type.Attributes);
  779. ConvertNodes(typeDeclaration.ModifierTokens, type.ModifierTokens);
  780. if (typeDeclaration.BaseTypes.Any()) {
  781. var first = typeDeclaration.BaseTypes.First();
  782. if (provider.GetTypeKindForAstType(first) != TypeKind.Interface) {
  783. ConvertNodes(typeDeclaration.BaseTypes.Skip(1), type.ImplementsTypes);
  784. type.InheritsType = (AstType)first.AcceptVisitor(this, data);
  785. } else
  786. ConvertNodes(typeDeclaration.BaseTypes, type.ImplementsTypes);
  787. }
  788. type.Name = typeDeclaration.Name;
  789. types.Push(type);
  790. ConvertNodes(typeDeclaration.Members, type.Members);
  791. types.Pop();
  792. return EndNode(typeDeclaration, type);
  793. }
  794. }
  795. public AstNode VisitUsingAliasDeclaration(CSharp.UsingAliasDeclaration usingAliasDeclaration, object data)
  796. {
  797. var imports = new ImportsStatement();
  798. var clause = new AliasImportsClause() {
  799. Name = new Identifier(usingAliasDeclaration.Alias, TextLocation.Empty),
  800. Alias = (AstType)usingAliasDeclaration.Import.AcceptVisitor(this, data)
  801. };
  802. imports.AddChild(clause, ImportsStatement.ImportsClauseRole);
  803. return EndNode(usingAliasDeclaration, imports);
  804. }
  805. public AstNode VisitUsingDeclaration(CSharp.UsingDeclaration usingDeclaration, object data)
  806. {
  807. var imports = new ImportsStatement();
  808. var clause = new MemberImportsClause() {
  809. Member = (AstType)usingDeclaration.Import.AcceptVisitor(this, data)
  810. };
  811. imports.AddChild(clause, ImportsStatement.ImportsClauseRole);
  812. return EndNode(usingDeclaration, imports);
  813. }
  814. public AstNode VisitExternAliasDeclaration(CSharp.ExternAliasDeclaration externAliasDeclaration, object data)
  815. {
  816. throw new NotImplementedException();
  817. }
  818. public AstNode VisitBlockStatement(CSharp.BlockStatement blockStatement, object data)
  819. {
  820. var block = new BlockStatement();
  821. blocks.Push(block);
  822. ConvertNodes(blockStatement, block.Statements);
  823. blocks.Pop();
  824. return EndNode(blockStatement, block);
  825. }
  826. public AstNode VisitBreakStatement(CSharp.BreakStatement breakStatement, object data)
  827. {
  828. var exit = new ExitStatement(ExitKind.None);
  829. foreach (var stmt in breakStatement.Ancestors) {
  830. if (stmt is CSharp.MethodDeclaration) {
  831. exit.ExitKind = IsSub(((CSharp.MethodDeclaration)stmt).ReturnType) ? ExitKind.Sub : ExitKind.Function;
  832. break;
  833. }
  834. if (stmt is CSharp.PropertyDeclaration) {
  835. exit.ExitKind = ExitKind.Property;
  836. break;
  837. }
  838. if (stmt is CSharp.DoWhileStatement) {
  839. exit.ExitKind = ExitKind.Do;
  840. break;
  841. }
  842. if (stmt is CSharp.ForStatement || stmt is CSharp.ForeachStatement) {
  843. exit.ExitKind = ExitKind.For;
  844. break;
  845. }
  846. if (stmt is CSharp.WhileStatement) {
  847. exit.ExitKind = ExitKind.While;
  848. break;
  849. }
  850. if (stmt is CSharp.SwitchStatement) {
  851. exit.ExitKind = ExitKind.Select;
  852. break;
  853. }
  854. if (stmt is CSharp.TryCatchStatement) {
  855. exit.ExitKind = ExitKind.Try;
  856. break;
  857. }
  858. }
  859. return EndNode(breakStatement, exit);
  860. }
  861. public AstNode VisitCheckedStatement(CSharp.CheckedStatement checkedStatement, object data)
  862. {
  863. blocks.Peek().AddChild(new Comment(" The following expression was wrapped in a checked-statement", false), AstNode.Roles.Comment);
  864. var body = (BlockStatement)checkedStatement.Body.AcceptVisitor(this, data);
  865. foreach (var stmt in body) {
  866. stmt.Remove();
  867. blocks.Peek().Add(stmt);
  868. }
  869. return EndNode<AstNode>(checkedStatement, null);
  870. }
  871. public AstNode VisitContinueStatement(CSharp.ContinueStatement continueStatement, object data)
  872. {
  873. var @continue = new ContinueStatement(ContinueKind.None);
  874. foreach (var stmt in continueStatement.Ancestors) {
  875. if (stmt is CSharp.DoWhileStatement) {
  876. @continue.ContinueKind = ContinueKind.Do;
  877. break;
  878. }
  879. if (stmt is CSharp.ForStatement || stmt is CSharp.ForeachStatement) {
  880. @continue.ContinueKind = ContinueKind.For;
  881. break;
  882. }
  883. if (stmt is CSharp.WhileStatement) {
  884. @continue.ContinueKind = ContinueKind.While;
  885. break;
  886. }
  887. }
  888. return EndNode(continueStatement, @continue);
  889. }
  890. public AstNode VisitDoWhileStatement(CSharp.DoWhileStatement doWhileStatement, object data)
  891. {
  892. var stmt = new DoLoopStatement();
  893. stmt.ConditionType = ConditionType.LoopWhile;
  894. stmt.Expression = (Expression)doWhileStatement.Condition.AcceptVisitor(this, data);
  895. stmt.Body = (BlockStatement)doWhileStatement.EmbeddedStatement.AcceptVisitor(this, data);
  896. return EndNode(doWhileStatement, stmt);
  897. }
  898. public AstNode VisitEmptyStatement(CSharp.EmptyStatement emptyStatement, object data)
  899. {
  900. return EndNode<Statement>(emptyStatement, null);
  901. }
  902. public AstNode VisitExpressionStatement(CSharp.ExpressionStatement expressionStatement, object data)
  903. {
  904. var node = expressionStatement.Expression.AcceptVisitor(this, data);
  905. if (node is Expression)
  906. node = new ExpressionStatement((Expression)node);
  907. return EndNode(expressionStatement, node);
  908. }
  909. public AstNode VisitFixedStatement(CSharp.FixedStatement fixedStatement, object data)
  910. {
  911. var block = blocks.Peek();
  912. block.AddChild(new Comment(" Emulating fixed-Statement, might not be entirely correct!", false), AstNode.Roles.Comment);
  913. var variables = new LocalDeclarationStatement();
  914. variables.Modifiers = Modifiers.Dim;
  915. var stmt = new TryStatement();
  916. stmt.FinallyBlock = new BlockStatement();
  917. foreach (var decl in fixedStatement.Variables) {
  918. var v = new VariableDeclaratorWithTypeAndInitializer {
  919. Identifiers = { new VariableIdentifier { Name = decl.Name } },
  920. Type = new SimpleType("GCHandle"),
  921. Initializer = new InvocationExpression(
  922. new MemberAccessExpression { Target = new IdentifierExpression { Identifier = "GCHandle" }, MemberName = "Alloc" },
  923. (Expression)decl.Initializer.AcceptVisitor(this, data),
  924. new MemberAccessExpression { Target = new IdentifierExpression { Identifier = "GCHandleType" }, MemberName = "Pinned" }
  925. )
  926. };
  927. variables.Variables.Add(v);
  928. stmt.FinallyBlock.Add(new IdentifierExpression { Identifier = decl.Name }.Invoke("Free"));
  929. }
  930. block.Add(variables);
  931. stmt.Body = (BlockStatement)fixedStatement.EmbeddedStatement.AcceptVisitor(this, data);
  932. foreach (var ident in stmt.Body.Descendants.OfType<IdentifierExpression>()) {
  933. ident.ReplaceWith(expr => ((Expression)expr).Invoke("AddrOfPinnedObject"));
  934. }
  935. return EndNode(fixedStatement, stmt);
  936. }
  937. public AstNode VisitForeachStatement(CSharp.ForeachStatement foreachStatement, object data)
  938. {
  939. var stmt = new ForEachStatement() {
  940. Body = (BlockStatement)foreachStatement.EmbeddedStatement.AcceptVisitor(this, data),
  941. InExpression = (Expression)foreachStatement.InExpression.AcceptVisitor(this, data),
  942. Variable = new VariableInitializer() {
  943. Identifier = new VariableIdentifier() { Name = foreachStatement.VariableName },
  944. Type = (AstType)foreachStatement.VariableType.AcceptVisitor(this, data)
  945. }
  946. };
  947. return EndNode(foreachStatement, stmt);
  948. }
  949. public AstNode VisitForStatement(CSharp.ForStatement forStatement, object data)
  950. {
  951. // for (;;) ;
  952. if (!forStatement.Initializers.Any() && forStatement.Condition.IsNull && !forStatement.Iterators.Any())
  953. return EndNode(forStatement, new WhileStatement() { Condition = new PrimitiveExpression(true), Body = (BlockStatement)forStatement.EmbeddedStatement.AcceptVisitor(this, data) });
  954. CSharp.AstNode counterLoop = new CSharp.ForStatement() {
  955. Initializers = {
  956. new NamedNode(
  957. "iteratorVar",
  958. new Choice {
  959. new CSharp.VariableDeclarationStatement {
  960. Type = new Choice {
  961. new CSharp.PrimitiveType("long"),
  962. new CSharp.PrimitiveType("ulong"),
  963. new CSharp.PrimitiveType("int"),
  964. new CSharp.PrimitiveType("uint"),
  965. new CSharp.PrimitiveType("short"),
  966. new CSharp.PrimitiveType("ushort"),
  967. new CSharp.PrimitiveType("sbyte"),
  968. new CSharp.PrimitiveType("byte")
  969. },
  970. Variables = {
  971. new AnyNode()
  972. }
  973. },
  974. new CSharp.ExpressionStatement(
  975. new CSharp.AssignmentExpression()
  976. )
  977. })
  978. },
  979. Condition = new NamedNode(
  980. "condition",
  981. new CSharp.BinaryOperatorExpression {
  982. Left = new NamedNode("ident", new CSharp.IdentifierExpression(Pattern.AnyString)),
  983. Operator = CSharp.BinaryOperatorType.Any,
  984. Right = new AnyNode("endExpr")
  985. }),
  986. Iterators = {
  987. new CSharp.ExpressionStatement(
  988. new NamedNode(
  989. "increment",
  990. new CSharp.AssignmentExpression {
  991. Left = new Backreference("ident"),
  992. Operator = CSharp.AssignmentOperatorType.Any,
  993. Right = new NamedNode("factor", new AnyNode())
  994. }
  995. )
  996. )
  997. },
  998. EmbeddedStatement = new NamedNode("body", new AnyNode())
  999. };
  1000. var match = counterLoop.Match(forStatement);
  1001. if (match.Success) {
  1002. var init = match.Get<CSharp.Statement>("iteratorVar").SingleOrDefault();
  1003. AstNode iteratorVariable;
  1004. if (init is CSharp.VariableDeclarationStatement) {
  1005. var var = ((CSharp.VariableDeclarationStatement)init).Variables.First();
  1006. iteratorVariable = new VariableInitializer() {
  1007. Identifier = new VariableIdentifier { Name = var.Name },
  1008. Type = (AstType)((CSharp.VariableDeclarationStatement)init).Type.AcceptVisitor(this, data),
  1009. Expression = (Expression)var.Initializer.AcceptVisitor(this, data)
  1010. };
  1011. } else if (init is CSharp.ExpressionStatement) {
  1012. iteratorVariable = init.AcceptVisitor(this, data);
  1013. } else goto end;
  1014. Expression toExpr = Expression.Null;
  1015. var cond = match.Get<CSharp.BinaryOperatorExpression>("condition").SingleOrDefault();
  1016. var endExpr = (Expression)match.Get<CSharp.Expression>("endExpr").SingleOrDefault().AcceptVisitor(this, data);
  1017. if (cond.Operator == CSharp.BinaryOperatorType.LessThanOrEqual ||
  1018. cond.Operator == CSharp.BinaryOperatorType.GreaterThanOrEqual) {
  1019. toExpr = endExpr;
  1020. }
  1021. if (cond.Operator == CSharp.BinaryOperatorType.LessThan)
  1022. toExpr = new BinaryOperatorExpression(endExpr, BinaryOperatorType.Subtract, new PrimitiveExpression(1));
  1023. if (cond.Operator == CSharp.BinaryOperatorType.GreaterThan)
  1024. toExpr = new BinaryOperatorExpression(endExpr, BinaryOperatorType.Add, new PrimitiveExpression(1));
  1025. Expression stepExpr = Expression.Null;
  1026. var increment = match.Get<CSharp.AssignmentExpression>("increment").SingleOrDefault();
  1027. var factorExpr = (Expression)match.Get<CSharp.Expression>("factor").SingleOrDefault().AcceptVisitor(this, data);
  1028. if (increment.Operator == CSharp.AssignmentOperatorType.Add && (factorExpr is PrimitiveExpression && !IsEqual(((PrimitiveExpression)factorExpr).Value, 1)))
  1029. stepExpr = factorExpr;
  1030. if (increment.Operator == CSharp.AssignmentOperatorType.Subtract)
  1031. stepExpr = new UnaryOperatorExpression(UnaryOperatorType.Minus, factorExpr);
  1032. return new ForStatement() {
  1033. Variable = iteratorVariable,
  1034. ToExpression = toExpr,
  1035. StepExpression = stepExpr,
  1036. Body = (BlockStatement)match.Get<CSharp.Statement>("body").Single().AcceptVisitor(this, data)
  1037. };
  1038. }
  1039. end:
  1040. var stmt = new WhileStatement() {
  1041. Condition = (Expression)forStatement.Condition.AcceptVisitor(this, data),
  1042. Body = (BlockStatement)forStatement.EmbeddedStatement.AcceptVisitor(this, data)
  1043. };
  1044. ConvertNodes(forStatement.Iterators, stmt.Body.Statements);
  1045. foreach (var initializer in forStatement.Initializers)
  1046. blocks.Peek().Statements.Add((Statement)initializer.AcceptVisitor(this, data));
  1047. return EndNode(forStatement, stmt);
  1048. }
  1049. bool IsEqual(object value, int num)
  1050. {
  1051. if (value is byte)
  1052. return (byte)value == num;
  1053. if (value is sbyte)
  1054. return (sbyte)value == num;
  1055. if (value is short)
  1056. return (short)value == num;
  1057. if (value is ushort)
  1058. return (ushort)value == num;
  1059. if (value is int)
  1060. return (int)value == num;
  1061. if (value is uint)
  1062. return (uint)value == num;
  1063. if (value is long)
  1064. return (long)value == num;
  1065. if (value is ulong)
  1066. return (ulong)value == (ulong)num;
  1067. throw new InvalidCastException();
  1068. }
  1069. public AstNode VisitGotoCaseStatement(CSharp.GotoCaseStatement gotoCaseStatement, object data)
  1070. {
  1071. throw new NotImplementedException();
  1072. }
  1073. public AstNode VisitGotoDefaultStatement(CSharp.GotoDefaultStatement gotoDefaultStatement, object data)
  1074. {
  1075. throw new NotImplementedException();
  1076. }
  1077. public AstNode VisitGotoStatement(CSharp.GotoStatement gotoStatement, object data)
  1078. {
  1079. return EndNode(gotoStatement, new GoToStatement() { Label = new IdentifierExpression() { Identifier = gotoStatement.Label } });
  1080. }
  1081. public AstNode VisitIfElseStatement(CSharp.IfElseStatement ifElseStatement, object data)
  1082. {
  1083. var stmt = new IfElseStatement();
  1084. stmt.Condition = (Expression)ifElseStatement.Condition.AcceptVisitor(this, data);
  1085. stmt.Body = (Statement)ifElseStatement.TrueStatement.AcceptVisitor(this, data);
  1086. stmt.ElseBlock = (Statement)ifElseStatement.FalseStatement.AcceptVisitor(this, data);
  1087. return EndNode(ifElseStatement, stmt);
  1088. }
  1089. public AstNode VisitLabelStatement(CSharp.LabelStatement labelStatement, object data)
  1090. {
  1091. return EndNode(labelStatement, new LabelDeclarationStatement() { Label = new IdentifierExpression() { Identifier = labelStatement.Label } });
  1092. }
  1093. public AstNode VisitLockStatement(CSharp.LockStatement lockStatement, object data)
  1094. {
  1095. var stmt = new SyncLockStatement();
  1096. stmt.Expression = (Expression)lockStatement.Expression.AcceptVisitor(this, data);
  1097. stmt.Body = (BlockStatement)lockStatement.EmbeddedStatement.AcceptVisitor(this, data);
  1098. return EndNode(lockStatement, stmt);
  1099. }
  1100. public AstNode VisitReturnStatement(CSharp.ReturnStatement returnStatement, object data)
  1101. {
  1102. var stmt = new ReturnStatement((Expression)returnStatement.Expression.AcceptVisitor(this, data));
  1103. return EndNode(returnStatement, stmt);
  1104. }
  1105. public AstNode VisitSwitchStatement(CSharp.SwitchStatement switchStatement, object data)
  1106. {
  1107. var stmt = new SelectStatement() { Expression = (Expression)switchStatement.Expression.AcceptVisitor(this, data) };
  1108. ConvertNodes(switchStatement.SwitchSections, stmt.Cases);
  1109. return EndNode(switchStatement, stmt);
  1110. }
  1111. public AstNode VisitSwitchSection(CSharp.SwitchSection switchSection, object data)
  1112. {
  1113. var caseStmt = new CaseStatement();
  1114. ConvertNodes(switchSection.CaseLabels, caseStmt.Clauses);
  1115. if (switchSection.Statements.Count == 1 && switchSection.Statements.FirstOrDefault() is CSharp.BlockStatement)
  1116. caseStmt.Body = (BlockStatement)switchSection.Statements.FirstOrDefault().AcceptVisitor(this, data);
  1117. else {
  1118. caseStmt.Body = new BlockStatement();
  1119. ConvertNodes(switchSection.Statements, caseStmt.Body.Statements);
  1120. }
  1121. if (caseStmt.Body.LastOrDefault() is ExitStatement && ((ExitStatement)caseStmt.Body.LastOrDefault()).ExitKind == ExitKind.Select)
  1122. caseStmt.Body.LastOrDefault().Remove();
  1123. return EndNode(switchSection, caseStmt);
  1124. }
  1125. public AstNode VisitCaseLabel(CSharp.CaseLabel caseLabel, object data)
  1126. {
  1127. return EndNode(caseLabel, new SimpleCaseClause() { Expression = (Expression)caseLabel.Expression.AcceptVisitor(this, data) });
  1128. }
  1129. public AstNode VisitThrowStatement(CSharp.ThrowStatement throwStatement, object data)
  1130. {
  1131. return EndNode(throwStatement, new ThrowStatement((Expression)throwStatement.Expression.AcceptVisitor(this, data)));
  1132. }
  1133. public AstNode VisitTryCatchStatement(CSharp.TryCatchStatement tryCatchStatement, object data)
  1134. {
  1135. var stmt = new TryStatement();
  1136. stmt.Body = (BlockStatement)tryCatchStatement.TryBlock.AcceptVisitor(this, data);
  1137. stmt.FinallyBlock = (BlockStatement)tryCatchStatement.FinallyBlock.AcceptVisitor(this, data);
  1138. ConvertNodes(tryCatchStatement.CatchClauses, stmt.CatchBlocks);
  1139. return EndNode(tryCatchStatement, stmt);
  1140. }
  1141. public AstNode VisitCatchClause(CSharp.CatchClause catchClause, object data)
  1142. {
  1143. var clause = new CatchBlock();
  1144. clause.ExceptionType = (AstType)catchClause.Type.AcceptVisitor(this, data);
  1145. clause.ExceptionVariable = catchClause.VariableName;
  1146. ConvertNodes(catchClause.Body.Statements, clause.Statements);
  1147. return EndNode(catchClause, clause);
  1148. }
  1149. public AstNode VisitUncheckedStatement(CSharp.UncheckedStatement uncheckedStatement, object data)
  1150. {
  1151. throw new NotImplementedException();
  1152. }
  1153. public AstNode VisitUnsafeStatement(CSharp.UnsafeStatement unsafeStatement, object data)
  1154. {
  1155. throw new NotImplementedException();
  1156. }
  1157. public AstNode VisitUsingStatement(CSharp.UsingStatement usingStatement, object data)
  1158. {
  1159. var stmt = new UsingStatement();
  1160. stmt.Resources.Add(usingStatement.ResourceAcquisition.AcceptVisitor(this, data));
  1161. stmt.Body = (BlockStatement)usingStatement.EmbeddedStatement.AcceptVisitor(this, data);
  1162. return EndNode(usingStatement, stmt);
  1163. }
  1164. public AstNode VisitVariableDeclarationStatement(CSharp.VariableDeclarationStatement variableDeclarationStatement, object data)
  1165. {
  1166. var decl = new LocalDeclarationStatement();
  1167. decl.Modifiers = Modifiers.Dim;
  1168. ConvertNodes(variableDeclarationStatement.Variables, decl.Variables);
  1169. return EndNode(variableDeclarationStatement, decl);
  1170. }
  1171. public AstNode VisitWhileStatement(CSharp.WhileStatement whileStatement, object data)
  1172. {
  1173. var stmt = new WhileStatement() {
  1174. Condition = (Expression)whileStatement.Condition.AcceptVisitor(this, data),
  1175. Body = (BlockStatement)whileStatement.EmbeddedStatement.AcceptVisitor(this, data)
  1176. };
  1177. return EndNode(whileStatement, stmt);
  1178. }
  1179. public AstNode VisitYieldBreakStatement(CSharp.YieldBreakStatement yieldBreakStatement, object data)
  1180. {
  1181. var frame = members.Peek();
  1182. frame.inIterator = true;
  1183. return EndNode(yieldBreakStatement, new ReturnStatement());
  1184. }
  1185. public AstNode VisitYieldReturnStatement(CSharp.YieldReturnStatement yieldReturnStatement, object data)
  1186. {
  1187. var frame = members.Peek();
  1188. frame.inIterator = true;
  1189. return EndNode(yieldReturnStatement, new YieldStatement((Expression)yieldReturnStatement.Expression.AcceptVisitor(this, data)));
  1190. }
  1191. public AstNode VisitAccessor(CSharp.Accessor accessor, object data)
  1192. {
  1193. var result = new Accessor();
  1194. ConvertNodes(accessor.Attributes, result.Attributes);
  1195. ConvertNodes(accessor.ModifierTokens, result.ModifierTokens);
  1196. result.Body = (BlockStatement)accessor.Body.AcceptVisitor(this, data);
  1197. return EndNode(accessor, result);
  1198. }
  1199. public AstNode VisitConstructorDeclaration(CSharp.ConstructorDeclaration constructorDeclaration, object data)
  1200. {
  1201. var result = new ConstructorDeclaration();
  1202. ConvertNodes(constructorDeclaration.Attributes, result.Attributes);
  1203. ConvertNodes(constructorDeclaration.ModifierTokens, result.ModifierTokens);
  1204. ConvertNodes(constructorDeclaration.Parameters, result.Parameters);
  1205. result.Body = (BlockStatement)constructorDeclaration.Body.AcceptVisitor(this, data);
  1206. if (!constructorDeclaration.Initializer.IsNull)
  1207. result.Body.Statements.InsertBefore(result.Body.FirstOrDefault(), (Statement)constructorDeclaration.Initializer.AcceptVisitor(this, data));
  1208. return EndNode(constructorDeclaration, result);
  1209. }
  1210. public AstNode VisitConstructorInitializer(CSharp.ConstructorInitializer constructorInitializer, object data)
  1211. {
  1212. var result = new InvocationExpression(
  1213. new MemberAccessExpression() {
  1214. Target = new InstanceExpression(constructorInitializer.ConstructorInitializerType == CSharp.ConstructorInitializerType.This ? InstanceExpressionType.Me : InstanceExpressionType.MyBase, TextLocation.Empty),
  1215. MemberName = new Identifier("New", TextLocation.Empty)
  1216. }
  1217. );
  1218. ConvertNodes(constructorInitializer.Arguments, result.Arguments);
  1219. return EndNode(constructorInitializer, new ExpressionStatement(result));
  1220. }
  1221. public AstNode VisitDestructorDeclaration(CSharp.DestructorDeclaration destructorDeclaration, object data)
  1222. {
  1223. var finalizer = new MethodDeclaration() { Name = "Finalize", IsSub = true };
  1224. ConvertNodes(destructorDeclaration.Attributes, finalizer.Attributes);
  1225. ConvertNodes(destructorDeclaration.ModifierTokens, finalizer.ModifierTokens);
  1226. finalizer.Body = (BlockStatement)destructorDeclaration.Body.AcceptVisitor(this, data);
  1227. return EndNode(destructorDeclaration, finalizer);
  1228. }
  1229. public AstNode VisitEnumMemberDeclaration(CSharp.EnumMemberDeclaration enumMemberDeclaration, object data)
  1230. {
  1231. var result = new EnumMemberDeclaration();
  1232. ConvertNodes(enumMemberDeclaration.Attributes, result.Attributes);
  1233. result.Name = new Identifier(enumMemberDeclaration.Name, TextLocation.Empty);
  1234. result.Value = (Expression)enumMemberDeclaration.Initializer.AcceptVisitor(this, data);
  1235. return EndNode(enumMemberDeclaration, result);
  1236. }
  1237. public AstNode VisitEventDeclaration(CSharp.EventDeclaration eventDeclaration, object data)
  1238. {
  1239. members.Push(new MemberInfo());
  1240. foreach (var evt in eventDeclaration.Variables) {
  1241. var result = new EventDeclaration();
  1242. ConvertNodes(eventDeclaration.Attributes, result.Attributes);
  1243. if (types.Any() && types.Peek().ClassType == ClassType.Module)
  1244. eventDeclaration.Modifiers &= ~CSharp.Modifiers.Static;
  1245. result.Modifiers = ConvertModifiers(eventDeclaration.Modifiers, eventDeclaration);
  1246. result.Name = evt.Name;
  1247. result.ReturnType = (AstType)eventDeclaration.ReturnType.AcceptVisitor(this, data);
  1248. // CreateImplementsClausesForEvent(result);
  1249. types.Peek().Members.Add(result);
  1250. }
  1251. members.Pop();
  1252. return EndNode<EventDeclaration>(eventDeclaration, null);
  1253. }
  1254. public AstNode VisitCustomEventDeclaration(CSharp.CustomEventDeclaration customEventDeclaration, object data)
  1255. {
  1256. var result = new EventDeclaration();
  1257. members.Push(new MemberInfo());
  1258. ConvertNodes(customEventDeclaration.Attributes, result.Attributes);
  1259. if (types.Any() && types.Peek().ClassType == ClassType.Module)
  1260. customEventDeclaration.Modifiers &= ~CSharp.Modifiers.Static;
  1261. result.Modifiers = ConvertModifiers(customEventDeclaration.Modifiers, customEventDeclaration);
  1262. result.IsCustom = true;
  1263. result.Name = new Identifier(customEventDeclaration.Name, TextLocation.Empty);
  1264. result.ReturnType = (AstType)customEventDeclaration.ReturnType.AcceptVisitor(this, data);
  1265. if (!customEventDeclaration.PrivateImplementationType.IsNull)
  1266. result.ImplementsClause.Add(
  1267. new InterfaceMemberSpecifier((AstType)customEventDeclaration.PrivateImplementationType.AcceptVisitor(this, data), customEventDeclaration.Name));
  1268. // else
  1269. // CreateImplementsClausesForEvent(result);
  1270. result.AddHandlerBlock = (Accessor)customEventDeclaration.AddAccessor.AcceptVisitor(this, data);
  1271. result.RemoveHandlerBlock = (Accessor)customEventDeclaration.RemoveAccessor.AcceptVisitor(this, data);
  1272. members.Pop();
  1273. return EndNode(customEventDeclaration, result);
  1274. }
  1275. public AstNode VisitFieldDeclaration(CSharp.FieldDeclaration fieldDeclaration, object data)
  1276. {
  1277. var decl = new FieldDeclaration();
  1278. members.Push(new MemberInfo());
  1279. ConvertNodes(fieldDeclaration.Attributes, decl.Attributes);
  1280. if (types.Any() && types.Peek().ClassType == ClassType.Module)
  1281. fieldDeclaration.Modifiers &= ~CSharp.Modifiers.Static;
  1282. decl.Modifiers = ConvertModifiers(fieldDeclaration.Modifiers, fieldDeclaration);
  1283. ConvertNodes(fieldDeclaration.Variables, decl.Variables);
  1284. members.Pop();
  1285. return EndNode(fieldDeclaration, decl);
  1286. }
  1287. public AstNode VisitIndexerDeclaration(CSharp.IndexerDeclaration indexerDeclaration, object data)
  1288. {
  1289. var decl = new PropertyDeclaration();
  1290. members.Push(new MemberInfo());
  1291. ConvertNodes(indexerDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), decl.Attributes);
  1292. decl.Getter = (Accessor)indexerDeclaration.Getter.AcceptVisitor(this, data);
  1293. if (types.Any() && types.Peek().ClassType == ClassType.Module)
  1294. indexerDeclaration.Modifiers &= ~CSharp.Modifiers.Static;
  1295. decl.Modifiers = ConvertModifiers(indexerDeclaration.Modifiers, indexerDeclaration);
  1296. decl.Name = new Identifier(indexerDeclaration.Name, TextLocation.Empty);
  1297. ConvertNodes(indexerDeclaration.Parameters, decl.Parameters);
  1298. ConvertNodes(indexerDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), decl.ReturnTypeAttributes);
  1299. if (!indexerDeclaration.PrivateImplementationType.IsNull)
  1300. decl.ImplementsClause.Add(
  1301. new InterfaceMemberSpecifier((AstType)indexerDeclaration.PrivateImplementationType.AcceptVisitor(this, data),
  1302. indexerDeclaration.Name));
  1303. decl.ReturnType = (AstType)indexerDeclaration.ReturnType.AcceptVisitor(this, data);
  1304. decl.Setter = (Accessor)indexerDeclaration.Setter.AcceptVisitor(this, data);
  1305. if (!decl.Setter.IsNull) {
  1306. decl.Setter.Parameters.Add(new ParameterDeclaration() {
  1307. Name = new Identifier("value", TextLocation.Empty),
  1308. Type = (AstType)indexerDeclaration.ReturnType.AcceptVisitor(this, data),
  1309. });
  1310. }
  1311. members.Pop();
  1312. return EndNode(indexerDeclaration, decl);
  1313. }
  1314. public AstNode VisitMethodDeclaration(CSharp.MethodDeclaration methodDeclaration, object data)
  1315. {
  1316. CSharp.Attribute attr;
  1317. if (types.Any() && types.Peek().ClassType == ClassType.Module)
  1318. methodDeclaration.Modifiers &= ~CSharp.Modifiers.Static;
  1319. if ((methodDeclaration.Modifiers & CSharp.Modifiers.Extern) == CSharp.Modifiers.Extern && HasAttribute(methodDeclaration.Attributes, "System.Runtime.InteropServices.DllImportAttribute", out attr)) {
  1320. var result = new ExternalMethodDeclaration();
  1321. members.Push(new MemberInfo());
  1322. // remove AttributeSection if only one attribute is present
  1323. var attrSec = (CSharp.AttributeSection)attr.Parent;
  1324. if (attrSec.Attributes.Count == 1)
  1325. attrSec.Remove();
  1326. else
  1327. attr.Remove();
  1328. result.Library = (attr.Arguments.First().AcceptVisitor(this, data) as PrimitiveExpression).Value.ToString();
  1329. result.CharsetModifier = ConvertCharset(attr.Arguments);
  1330. result.Alias = ConvertAlias(attr.Arguments);
  1331. ConvertNodes(methodDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), result.Attributes);
  1332. ConvertNodes(methodDeclaration.ModifierTokens, result.ModifierTokens);
  1333. result.Name = new Identifier(methodDeclaration.Name, TextLocation.Empty);
  1334. result.IsSub = IsSub(methodDeclaration.ReturnType);
  1335. ConvertNodes(methodDeclaration.Parameters, result.Parameters);
  1336. ConvertNodes(methodDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), result.ReturnTypeAttributes);
  1337. if (!result.IsSub)
  1338. result.ReturnType = (AstType)methodDeclaration.ReturnType.AcceptVisitor(this, data);
  1339. if (members.Pop().inIterator) {
  1340. result.Modifiers |= Modifiers.Iterator;
  1341. }
  1342. return EndNode(methodDeclaration, result);
  1343. } else {
  1344. var result = new MethodDeclaration();
  1345. members.Push(new MemberInfo());
  1346. ConvertNodes(methodDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), result.Attributes);
  1347. ConvertNodes(methodDeclaration.ModifierTokens, result.ModifierTokens);
  1348. result.Name = new Identifier(methodDeclaration.Name, TextLocation.Empty);
  1349. result.IsSub = IsSub(methodDeclaration.ReturnType);
  1350. ConvertNodes(methodDeclaration.Parameters, result.Parameters);
  1351. ConvertNodes(methodDeclaration.TypeParameters, result.TypeParameters);
  1352. ConvertNodes(methodDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), result.ReturnTypeAttributes);
  1353. if (!methodDeclaration.PrivateImplementationType.IsNull)
  1354. result.ImplementsClause.Add(
  1355. new InterfaceMemberSpecifier((AstType)methodDeclaration.PrivateImplementationType.AcceptVisitor(this, data),
  1356. methodDeclaration.Name));
  1357. // else
  1358. // CreateImplementsClausesForMethod(result);
  1359. if (!result.IsSub)
  1360. result.ReturnType = (AstType)methodDeclaration.ReturnType.AcceptVisitor(this, data);
  1361. if (methodDeclaration.IsExtensionMethod) {
  1362. result.Attributes.Add(
  1363. new AttributeBlock {
  1364. Attributes = {
  1365. new Ast.Attribute {
  1366. Type = AstType.FromName("System.Runtime.CompilerServices.ExtensionAttribute")
  1367. }
  1368. }
  1369. });
  1370. }
  1371. result.Body = (BlockStatement)methodDeclaration.Body.AcceptVisitor(this, data);
  1372. if (members.Pop().inIterator) {
  1373. result.Modifiers |= Modifiers.Iterator;
  1374. }
  1375. return EndNode(methodDeclaration, result);
  1376. }
  1377. }
  1378. void CreateImplementsClausesForMethod(MethodDeclaration result)
  1379. {
  1380. if (!types.Any()) return;
  1381. var current = types.Peek();
  1382. if (current.ClassType == ClassType.Interface)
  1383. return;
  1384. foreach (var type in current.ImplementsTypes) {
  1385. var resolved = provider.ResolveType(type, current);
  1386. var found = resolved.GetMembers(m => m.SymbolKind == SymbolKind.Method && m.Name == result.Name.Name);
  1387. if (found.FirstOrDefault() != null) {
  1388. result.ImplementsClause.Add(new InterfaceMemberSpecifier((AstType)type.Clone(), found.FirstOrDefault().Name));
  1389. }
  1390. }
  1391. }
  1392. void CreateImplementsClausesForEvent(EventDeclaration result)
  1393. {
  1394. if (!types.Any()) return;
  1395. var current = types.Peek();
  1396. if (current.ClassType == ClassType.Interface)
  1397. return;
  1398. foreach (var type in current.ImplementsTypes) {
  1399. var resolved = provider.ResolveType(type, current);
  1400. var found = resolved.GetMembers(m => m.SymbolKind == SymbolKind.Event && m.Name == result.Name.Name);
  1401. if (found.FirstOrDefault() != null) {
  1402. result.ImplementsClause.Add(new InterfaceMemberSpecifier((AstType)type.Clone(), found.FirstOrDefault().Name));
  1403. }
  1404. }
  1405. }
  1406. string ConvertAlias(CSharp.AstNodeCollection<CSharp.Expression> arguments)
  1407. {
  1408. var pattern = new CSharp.AssignmentExpression() {
  1409. Left = new CSharp.IdentifierExpression("EntryPoint"),
  1410. Operator = CSharp.AssignmentOperatorType.Assign,
  1411. Right = new AnyNode("alias")
  1412. };
  1413. var result = arguments
  1414. .Select(expr => pattern.Match(expr))
  1415. .FirstOrDefault(r => r.Success);
  1416. if (result.Success && result.Has("alias")) {
  1417. return result.Get<CSharp.PrimitiveExpression>("alias")
  1418. .First().Value.ToString();
  1419. }
  1420. return null;
  1421. }
  1422. CharsetModifier ConvertCharset(CSharp.AstNodeCollection<CSharp.Expression> arguments)
  1423. {
  1424. var pattern = new CSharp.AssignmentExpression() {
  1425. Left = new CSharp.IdentifierExpression("CharSet"),
  1426. Operator = CSharp.AssignmentOperatorType.Assign,
  1427. Right = new NamedNode(
  1428. "modifier",
  1429. new CSharp.MemberReferenceExpression() {
  1430. Target = new CSharp.IdentifierExpression("CharSet"),
  1431. MemberName = Pattern.AnyString
  1432. })
  1433. };
  1434. var result = arguments
  1435. .Select(expr => pattern.Match(expr))
  1436. .FirstOrDefault(r => r.Success);
  1437. if (result.Success && result.Has("modifier")) {
  1438. switch (result.Get<CSharp.MemberReferenceExpression>("modifier").First().MemberName) {
  1439. case "Auto":
  1440. return CharsetModifier.Auto;
  1441. case "Ansi":
  1442. return CharsetModifier.Ansi;
  1443. case "Unicode":
  1444. return CharsetModifier.Unicode;
  1445. }
  1446. }
  1447. return CharsetModifier.None;
  1448. }
  1449. bool IsSub(CSharp.AstType returnType)
  1450. {
  1451. var t = returnType as CSharp.PrimitiveType;
  1452. return t != null && t.Keyword == "void";
  1453. }
  1454. public AstNode VisitOperatorDeclaration(CSharp.OperatorDeclaration operatorDeclaration, object data)
  1455. {
  1456. MemberDeclaration result;
  1457. members.Push(new MemberInfo());
  1458. if (types.Any() && types.Peek().ClassType == ClassType.Module)
  1459. operatorDeclaration.Modifiers &= ~CSharp.Modifiers.Static;
  1460. if (operatorDeclaration.OperatorType == CSharp.OperatorType.Increment || operatorDeclaration.OperatorType == CSharp.OperatorType.Decrement) {
  1461. var m = new MethodDeclaration();
  1462. result = m;
  1463. ConvertNodes(operatorDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), m.Attributes);
  1464. ConvertNodes(operatorDeclaration.ModifierTokens, m.ModifierTokens);
  1465. m.Name = operatorDeclaration.OperatorType == CSharp.OperatorType.Increment ? "op_Increment" : "op_Decrement";
  1466. ConvertNodes(operatorDeclaration.Parameters, m.Parameters);
  1467. ConvertNodes(operatorDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), m.ReturnTypeAttributes);
  1468. m.ReturnType = (AstType)operatorDeclaration.ReturnType.AcceptVisitor(this, data);
  1469. m.Body = (BlockStatement)operatorDeclaration.Body.AcceptVisitor(this, data);
  1470. } else {
  1471. var op = new OperatorDeclaration();
  1472. result = op;
  1473. ConvertNodes(operatorDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), op.Attributes);
  1474. ConvertNodes(operatorDeclaration.ModifierTokens, op.ModifierTokens);
  1475. switch (operatorDeclaration.OperatorType) {
  1476. case ICSharpCode.NRefactory.CSharp.OperatorType.LogicalNot:
  1477. case ICSharpCode.NRefactory.CSharp.OperatorType.OnesComplement:
  1478. op.Operator = OverloadableOperatorType.Not;
  1479. break;
  1480. case ICSharpCode.NRefactory.CSharp.OperatorType.True:
  1481. op.Operator = OverloadableOperatorType.IsTrue;
  1482. break;
  1483. case ICSharpCode.NRefactory.CSharp.OperatorType.False:
  1484. op.Operator = OverloadableOperatorType.IsFalse;
  1485. break;
  1486. case ICSharpCode.NRefactory.CSharp.OperatorType.Implicit:
  1487. op.Modifiers |= Modifiers.Widening;
  1488. op.Operator = OverloadableOperatorType.CType;
  1489. break;
  1490. case ICSharpCode.NRefactory.CSharp.OperatorType.Explicit:
  1491. op.Modifiers |= Modifiers.Narrowing;
  1492. op.Operator = OverloadableOperatorType.CType;
  1493. break;
  1494. case ICSharpCode.NRefactory.CSharp.OperatorType.Addition:
  1495. op.Operator = OverloadableOperatorType.Add;
  1496. break;
  1497. case ICSharpCode.NRefactory.CSharp.OperatorType.Subtraction:
  1498. op.Operator = OverloadableOperatorType.Subtract;
  1499. break;
  1500. case ICSharpCode.NRefactory.CSharp.OperatorType.UnaryPlus:
  1501. op.Operator = OverloadableOperatorType.UnaryPlus;
  1502. break;
  1503. case ICSharpCode.NRefactory.CSharp.OperatorType.UnaryNegation:
  1504. op.Operator = OverloadableOperatorType.UnaryMinus;
  1505. break;
  1506. case ICSharpCode.NRefactory.CSharp.OperatorType.Multiply:
  1507. op.Operator = OverloadableOperatorType.Multiply;
  1508. break;
  1509. case ICSharpCode.NRefactory.CSharp.OperatorType.Division:
  1510. op.Operator = OverloadableOperatorType.Divide;
  1511. break;
  1512. case ICSharpCode.NRefactory.CSharp.OperatorType.Modulus:
  1513. op.Operator = OverloadableOperatorType.Modulus;
  1514. break;
  1515. case ICSharpCode.NRefactory.CSharp.OperatorType.BitwiseAnd:
  1516. op.Operator = OverloadableOperatorType.BitwiseAnd;
  1517. break;
  1518. case ICSharpCode.NRefactory.CSharp.OperatorType.BitwiseOr:
  1519. op.Operator = OverloadableOperatorType.BitwiseOr;
  1520. break;
  1521. case ICSharpCode.NRefactory.CSharp.OperatorType.ExclusiveOr:
  1522. op.Operator = OverloadableOperatorType.ExclusiveOr;
  1523. break;
  1524. case ICSharpCode.NRefactory.CSharp.OperatorType.LeftShift:
  1525. op.Operator = OverloadableOperatorType.ShiftLeft;
  1526. break;
  1527. case ICSharpCode.NRefactory.CSharp.OperatorType.RightShift:
  1528. op.Operator = OverloadableOperatorType.ShiftRight;
  1529. break;
  1530. case ICSharpCode.NRefactory.CSharp.OperatorType.Equality:
  1531. op.Operator = OverloadableOperatorType.Equality;
  1532. break;
  1533. case ICSharpCode.NRefactory.CSharp.OperatorType.Inequality:
  1534. op.Operator = OverloadableOperatorType.InEquality;
  1535. break;
  1536. case ICSharpCode.NRefactory.CSharp.OperatorType.GreaterThan:
  1537. op.Operator = OverloadableOperatorType.GreaterThan;
  1538. break;
  1539. case ICSharpCode.NRefactory.CSharp.OperatorType.LessThan:
  1540. op.Operator = OverloadableOperatorType.LessThan;
  1541. break;
  1542. case ICSharpCode.NRefactory.CSharp.OperatorType.GreaterThanOrEqual:
  1543. op.Operator = OverloadableOperatorType.GreaterThanOrEqual;
  1544. break;
  1545. case ICSharpCode.NRefactory.CSharp.OperatorType.LessThanOrEqual:
  1546. op.Operator = OverloadableOperatorType.LessThanOrEqual;
  1547. break;
  1548. default:
  1549. throw new Exception("Invalid value for OperatorType");
  1550. }
  1551. ConvertNodes(operatorDeclaration.Parameters, op.Parameters);
  1552. ConvertNodes(operatorDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), op.ReturnTypeAttributes);
  1553. op.ReturnType = (AstType)operatorDeclaration.ReturnType.AcceptVisitor(this, data);
  1554. op.Body = (BlockStatement)operatorDeclaration.Body.AcceptVisitor(this, data);
  1555. }
  1556. members.Pop();
  1557. return EndNode(operatorDeclaration, result);
  1558. }
  1559. public AstNode VisitParameterDeclaration(CSharp.ParameterDeclaration parameterDeclaration, object data)
  1560. {
  1561. var param = new ParameterDeclaration();
  1562. ConvertNodes(parameterDeclaration.Attributes, param.Attributes);
  1563. param.Modifiers = ConvertParamModifiers(parameterDeclaration.ParameterModifier);
  1564. if ((parameterDeclaration.ParameterModifier & ICSharpCode.NRefactory.CSharp.ParameterModifier.Out) == ICSharpCode.NRefactory.CSharp.ParameterModifier.Out) {
  1565. AttributeBlock block = new AttributeBlock();
  1566. block.Attributes.Add(new Ast.Attribute() { Type = new SimpleType("Out") });
  1567. param.Attributes.Add(block);
  1568. }
  1569. param.Name = new Identifier(parameterDeclaration.Name, TextLocation.Empty);
  1570. param.Type = (AstType)parameterDeclaration.Type.AcceptVisitor(this, data);
  1571. param.OptionalValue = (Expression)parameterDeclaration.DefaultExpression.AcceptVisitor(this, data);
  1572. if (!param.OptionalValue.IsNull)
  1573. param.Modifiers |= Modifiers.Optional;
  1574. return EndNode(parameterDeclaration, param);
  1575. }
  1576. Modifiers ConvertParamModifiers(CSharp.ParameterModifier mods)
  1577. {
  1578. switch (mods) {
  1579. case ICSharpCode.NRefactory.CSharp.ParameterModifier.None:
  1580. case ICSharpCode.NRefactory.CSharp.ParameterModifier.This:
  1581. return Modifiers.None;
  1582. case ICSharpCode.NRefactory.CSharp.ParameterModifier.Ref:
  1583. case ICSharpCode.NRefactory.CSharp.ParameterModifier.Out:
  1584. return Modifiers.ByRef;
  1585. case ICSharpCode.NRefactory.CSharp.ParameterModifier.Params:
  1586. return Modifiers.ParamArray;
  1587. default:
  1588. throw new Exception("Invalid value for ParameterModifier");
  1589. }
  1590. }
  1591. public AstNode VisitPropertyDeclaration(CSharp.PropertyDeclaration propertyDeclaration, object data)
  1592. {
  1593. var decl = new PropertyDeclaration();
  1594. members.Push(new MemberInfo());
  1595. if (types.Any() && types.Peek().ClassType == ClassType.Module)
  1596. propertyDeclaration.Modifiers &= ~CSharp.Modifiers.Static;
  1597. ConvertNodes(propertyDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), decl.Attributes);
  1598. decl.Getter = (Accessor)propertyDeclaration.Getter.AcceptVisitor(this, data);
  1599. decl.Modifiers = ConvertModifiers(propertyDeclaration.Modifiers, propertyDeclaration);
  1600. decl.Name = new Identifier(propertyDeclaration.Name, TextLocation.Empty);
  1601. ConvertNodes(propertyDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), decl.ReturnTypeAttributes);
  1602. if (!propertyDeclaration.PrivateImplementationType.IsNull)
  1603. decl.ImplementsClause.Add(
  1604. new InterfaceMemberSpecifier((AstType)propertyDeclaration.PrivateImplementationType.AcceptVisitor(this, data),
  1605. propertyDeclaration.Name));
  1606. decl.ReturnType = (AstType)propertyDeclaration.ReturnType.AcceptVisitor(this, data);
  1607. decl.Setter = (Accessor)propertyDeclaration.Setter.AcceptVisitor(this, data);
  1608. if (!decl.Setter.IsNull) {
  1609. decl.Setter.Parameters.Add(new ParameterDeclaration() {
  1610. Name = new Identifier("value", TextLocation.Empty),
  1611. Type = (AstType)propertyDeclaration.ReturnType.AcceptVisitor(this, data),
  1612. });
  1613. }
  1614. if (members.Pop().inIterator) {
  1615. decl.Modifiers |= Modifiers.Iterator;
  1616. }
  1617. return EndNode(propertyDeclaration, decl);
  1618. }
  1619. public AstNode VisitVariableInitializer(CSharp.VariableInitializer variableInitializer, object data)
  1620. {
  1621. var decl = new VariableDeclaratorWithTypeAndInitializer();
  1622. // look for type in parent
  1623. decl.Type = (AstType)variableInitializer.Parent
  1624. .GetChildByRole(ICSharpCode.NRefactory.CSharp.Roles.Type)
  1625. .AcceptVisitor(this, data);
  1626. decl.Identifiers.Add(new VariableIdentifier() { Name = variableInitializer.Name });
  1627. decl.Initializer = (Expression)variableInitializer.Initializer.AcceptVisitor(this, data);
  1628. return EndNode(variableInitializer, decl);
  1629. }
  1630. public AstNode VisitFixedFieldDeclaration(CSharp.FixedFieldDeclaration fixedFieldDeclaration, object data)
  1631. {
  1632. throw new NotImplementedException();
  1633. }
  1634. public AstNode VisitFixedVariableInitializer(CSharp.FixedVariableInitializer fixedVariableInitializer, object data)
  1635. {
  1636. throw new NotImplementedException();
  1637. }
  1638. public AstNode VisitSyntaxTree(CSharp.SyntaxTree syntaxTree, object data)
  1639. {
  1640. var unit = new CompilationUnit();
  1641. foreach (var node in syntaxTree.Children)
  1642. unit.AddChild(node.AcceptVisitor(this, null), CompilationUnit.MemberRole);
  1643. return EndNode(syntaxTree, unit);
  1644. }
  1645. public AstNode VisitSimpleType(CSharp.SimpleType simpleType, object data)
  1646. {
  1647. var type = new SimpleType(simpleType.Identifier);
  1648. ConvertNodes(simpleType.TypeArguments, type.TypeArguments);
  1649. return EndNode(simpleType, type);
  1650. }
  1651. public AstNode VisitMemberType(CSharp.MemberType memberType, object data)
  1652. {
  1653. AstType target = null;
  1654. if (memberType.Target is CSharp.SimpleType && ((CSharp.SimpleType)(memberType.Target)).Identifier.Equals("global", StringComparison.Ordinal))
  1655. target = new PrimitiveType("Global");
  1656. else
  1657. target = (AstType)memberType.Target.AcceptVisitor(this, data);
  1658. var type = new QualifiedType(target, new Identifier(memberType.MemberName, TextLocation.Empty));
  1659. ConvertNodes(memberType.TypeArguments, type.TypeArguments);
  1660. return EndNode(memberType, type);
  1661. }
  1662. public AstNode VisitComposedType(CSharp.ComposedType composedType, object data)
  1663. {
  1664. AstType type = new ComposedType();
  1665. ConvertNodes(composedType.ArraySpecifiers, ((ComposedType)type).ArraySpecifiers);
  1666. ((ComposedType)type).BaseType = (AstType)composedType.BaseType.AcceptVisitor(this, data);
  1667. ((ComposedType)type).HasNullableSpecifier = composedType.HasNullableSpecifier;
  1668. for (int i = 0; i < composedType.PointerRank; i++) {
  1669. var tmp = new SimpleType() { Identifier = "__Pointer" };
  1670. tmp.TypeArguments.Add(type);
  1671. type = tmp;
  1672. }
  1673. return EndNode(composedType, type);
  1674. }
  1675. public AstNode VisitArraySpecifier(CSharp.ArraySpecifier arraySpecifier, object data)
  1676. {
  1677. return EndNode(arraySpecifier, new ArraySpecifier(arraySpecifier.Dimensions));
  1678. }
  1679. public AstNode VisitPrimitiveType(CSharp.PrimitiveType primitiveType, object data)
  1680. {
  1681. string typeName;
  1682. switch (primitiveType.Keyword) {
  1683. case "object":
  1684. typeName = "Object";
  1685. break;
  1686. case "bool":
  1687. typeName = "Boolean";
  1688. break;
  1689. case "char":
  1690. typeName = "Char";
  1691. break;
  1692. case "sbyte":
  1693. typeName = "SByte";
  1694. break;
  1695. case "byte":
  1696. typeName = "Byte";
  1697. break;
  1698. case "short":
  1699. typeName = "Short";
  1700. break;
  1701. case "ushort":
  1702. typeName = "UShort";
  1703. break;
  1704. case "int":
  1705. typeName = "Integer";
  1706. break;
  1707. case "uint":
  1708. typeName = "UInteger";
  1709. break;
  1710. case "long":
  1711. typeName = "Long";
  1712. break;
  1713. case "ulong":
  1714. typeName = "ULong";
  1715. break;
  1716. case "float":
  1717. typeName = "Single";
  1718. break;
  1719. case "double":
  1720. typeName = "Double";
  1721. break;
  1722. case "decimal":
  1723. typeName = "Decimal";
  1724. break;
  1725. case "string":
  1726. typeName = "String";
  1727. break;
  1728. // generic constraints
  1729. case "new":
  1730. typeName = "New";
  1731. break;
  1732. case "struct":
  1733. typeName = "Structure";
  1734. break;
  1735. case "class":
  1736. typeName = "Class";
  1737. break;
  1738. case "void":
  1739. typeName = "Void";
  1740. break;
  1741. default:
  1742. typeName = "unknown";
  1743. break;
  1744. }
  1745. return EndNode(primitiveType, new PrimitiveType(typeName));
  1746. }
  1747. public AstNode VisitComment (CSharp.Comment comment, object data)
  1748. {
  1749. var c = new Comment (comment.Content, comment.CommentType == CSharp.CommentType.Documentation);
  1750. if (comment.CommentType == CSharp.CommentType.MultiLine)
  1751. throw new NotImplementedException ();
  1752. return EndNode (comment, c);
  1753. }
  1754. public AstNode VisitPreProcessorDirective (CSharp.PreProcessorDirective preProcessorDirective, object data)
  1755. {
  1756. // TODO
  1757. return null;
  1758. }
  1759. public AstNode VisitTypeParameterDeclaration(CSharp.TypeParameterDeclaration typeParameterDeclaration, object data)
  1760. {
  1761. var param = new TypeParameterDeclaration() {
  1762. Variance = typeParameterDeclaration.Variance,
  1763. Name = typeParameterDeclaration.Name
  1764. };
  1765. var constraint = typeParameterDeclaration.Parent
  1766. .GetChildrenByRole(ICSharpCode.NRefactory.CSharp.Roles.Constraint)
  1767. .SingleOrDefault(c => c.TypeParameter.Identifier == typeParameterDeclaration.Name);
  1768. if (constraint != null)
  1769. ConvertNodes(constraint.BaseTypes, param.Constraints);
  1770. // TODO : typeParameterDeclaration.Attributes get lost?
  1771. //ConvertNodes(typeParameterDeclaration.Attributes
  1772. return EndNode(typeParameterDeclaration, param);
  1773. }
  1774. public AstNode VisitConstraint(CSharp.Constraint constraint, object data)
  1775. {
  1776. throw new NotImplementedException();
  1777. }
  1778. public AstNode VisitCSharpTokenNode(CSharp.CSharpTokenNode cSharpTokenNode, object data)
  1779. {
  1780. var mod = cSharpTokenNode as CSharp.CSharpModifierToken;
  1781. if (mod != null) {
  1782. var convertedModifiers = ConvertModifiers(mod.Modifier, mod.Parent);
  1783. VBModifierToken token = null;
  1784. if (convertedModifiers != Modifiers.None) {
  1785. token = new VBModifierToken(TextLocation.Empty, convertedModifiers);
  1786. return EndNode(cSharpTokenNode, token);
  1787. }
  1788. return EndNode(cSharpTokenNode, token);
  1789. } else {
  1790. throw new NotSupportedException("Should never visit individual tokens");
  1791. }
  1792. }
  1793. Modifiers ConvertModifiers(CSharp.Modifiers modifier, CSharp.AstNode container)
  1794. {
  1795. if ((modifier & CSharp.Modifiers.Any) == CSharp.Modifiers.Any)
  1796. return Modifiers.Any;
  1797. var mod = Modifiers.None;
  1798. if ((modifier & CSharp.Modifiers.Const) == CSharp.Modifiers.Const)
  1799. mod |= Modifiers.Const;
  1800. if ((modifier & CSharp.Modifiers.Abstract) == CSharp.Modifiers.Abstract) {
  1801. if (container is CSharp.TypeDeclaration)
  1802. mod |= Modifiers.MustInherit;
  1803. else
  1804. mod |= Modifiers.MustOverride;
  1805. }
  1806. if ((modifier & CSharp.Modifiers.Static) == CSharp.Modifiers.Static)
  1807. mod |= Modifiers.Shared;
  1808. if ((modifier & CSharp.Modifiers.Public) == CSharp.Modifiers.Public)
  1809. mod |= Modifiers.Public;
  1810. if ((modifier & CSharp.Modifiers.Protected) == CSharp.Modifiers.Protected)
  1811. mod |= Modifiers.Protected;
  1812. if ((modifier & CSharp.Modifiers.Internal) == CSharp.Modifiers.Internal)
  1813. mod |= Modifiers.Friend;
  1814. if ((modifier & CSharp.Modifiers.Private) == CSharp.Modifiers.Private)
  1815. mod |= Modifiers.Private;
  1816. if (container is CSharp.IndexerDeclaration)
  1817. mod |= Modifiers.Default;
  1818. bool writeable = IsWriteableProperty(container);
  1819. bool readable = IsReadableProperty(container);
  1820. if (writeable && !readable)
  1821. mod |= Modifiers.WriteOnly;
  1822. if (readable && !writeable)
  1823. mod |= Modifiers.ReadOnly;
  1824. if ((modifier & CSharp.Modifiers.Override) == CSharp.Modifiers.Override)
  1825. mod |= Modifiers.Overrides;
  1826. if ((modifier & CSharp.Modifiers.Virtual) == CSharp.Modifiers.Virtual)
  1827. mod |= Modifiers.Overridable;
  1828. if ((modifier & CSharp.Modifiers.Async) == CSharp.Modifiers.Async)
  1829. mod |= Modifiers.Async;
  1830. return mod;
  1831. }
  1832. bool IsReadableProperty(ICSharpCode.NRefactory.CSharp.AstNode container)
  1833. {
  1834. if (container is CSharp.IndexerDeclaration) {
  1835. var i = container as CSharp.IndexerDeclaration;
  1836. return !i.Getter.IsNull;
  1837. }
  1838. if (container is CSharp.PropertyDeclaration) {
  1839. var p = container as CSharp.PropertyDeclaration;
  1840. return !p.Getter.IsNull;
  1841. }
  1842. return false;
  1843. }
  1844. bool IsWriteableProperty(ICSharpCode.NRefactory.CSharp.AstNode container)
  1845. {
  1846. if (container is CSharp.IndexerDeclaration) {
  1847. var i = container as CSharp.IndexerDeclaration;
  1848. return !i.Setter.IsNull;
  1849. }
  1850. if (container is CSharp.PropertyDeclaration) {
  1851. var p = container as CSharp.PropertyDeclaration;
  1852. return !p.Setter.IsNull;
  1853. }
  1854. return false;
  1855. }
  1856. public AstNode VisitIdentifier(CSharp.Identifier identifier, object data)
  1857. {
  1858. var ident = new Identifier(identifier.Name, identifier.StartLocation);
  1859. return EndNode(identifier, ident);
  1860. }
  1861. public AstNode VisitPatternPlaceholder(CSharp.AstNode placeholder, ICSharpCode.NRefactory.PatternMatching.Pattern pattern, object data)
  1862. {
  1863. throw new NotImplementedException();
  1864. }
  1865. void ConvertNodes<T>(IEnumerable<CSharp.AstNode> nodes, VB.AstNodeCollection<T> result, Func<T, T> transform = null) where T: VB.AstNode
  1866. {
  1867. foreach (var node in nodes) {
  1868. T n = (T)node.AcceptVisitor(this, null);
  1869. if (transform != null)
  1870. n = transform(n);
  1871. if (n != null)
  1872. result.Add(n);
  1873. }
  1874. }
  1875. T EndNode<T>(CSharp.AstNode node, T result) where T : VB.AstNode
  1876. {
  1877. if (result != null) {
  1878. CopyAnnotations(node, result);
  1879. }
  1880. return result;
  1881. }
  1882. void CopyAnnotations<T>(CSharp.AstNode node, T result) where T : VB.AstNode
  1883. {
  1884. foreach (var ann in node.Annotations)
  1885. result.AddAnnotation(ann);
  1886. }
  1887. bool HasAttribute(CSharp.AstNodeCollection<CSharp.AttributeSection> attributes, string name, out CSharp.Attribute foundAttribute)
  1888. {
  1889. foreach (var attr in attributes.SelectMany(a => a.Attributes)) {
  1890. if (provider.GetTypeNameForAttribute(attr) == name) {
  1891. foundAttribute = attr;
  1892. return true;
  1893. }
  1894. }
  1895. foundAttribute = null;
  1896. return false;
  1897. }
  1898. public AstNode VisitDocumentationReference(CSharp.DocumentationReference documentationReference, object data)
  1899. {
  1900. throw new NotImplementedException();
  1901. }
  1902. public AstNode VisitNewLine(CSharp.NewLineNode newLineNode, object data)
  1903. {
  1904. return null;
  1905. }
  1906. public AstNode VisitWhitespace(CSharp.WhitespaceNode whitespaceNode, object data)
  1907. {
  1908. return null;
  1909. }
  1910. public AstNode VisitText(CSharp.TextNode textNode, object data)
  1911. {
  1912. return null;
  1913. }
  1914. public AstNode VisitNullNode(ICSharpCode.NRefactory.CSharp.AstNode nullNode, object data)
  1915. {
  1916. return null;
  1917. }
  1918. public AstNode VisitErrorNode(ICSharpCode.NRefactory.CSharp.AstNode errorNode, object data)
  1919. {
  1920. return null;
  1921. }
  1922. }
  1923. }