1 | // Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team |
---|
2 | // |
---|
3 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this |
---|
4 | // software and associated documentation files (the "Software"), to deal in the Software |
---|
5 | // without restriction, including without limitation the rights to use, copy, modify, merge, |
---|
6 | // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons |
---|
7 | // to whom the Software is furnished to do so, subject to the following conditions: |
---|
8 | // |
---|
9 | // The above copyright notice and this permission notice shall be included in all copies or |
---|
10 | // substantial portions of the Software. |
---|
11 | // |
---|
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
---|
13 | // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR |
---|
14 | // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE |
---|
15 | // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
---|
16 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
---|
17 | // DEALINGS IN THE SOFTWARE. |
---|
18 | |
---|
19 | using System; |
---|
20 | using System.CodeDom; |
---|
21 | using System.Collections.Generic; |
---|
22 | using System.IO; |
---|
23 | using System.Linq; |
---|
24 | using ICSharpCode.NRefactory.CSharp.Refactoring; |
---|
25 | using ICSharpCode.NRefactory.CSharp.Resolver; |
---|
26 | using ICSharpCode.NRefactory.CSharp.TypeSystem; |
---|
27 | using ICSharpCode.NRefactory.PatternMatching; |
---|
28 | using ICSharpCode.NRefactory.Semantics; |
---|
29 | using ICSharpCode.NRefactory.TypeSystem; |
---|
30 | |
---|
31 | namespace ICSharpCode.NRefactory.CSharp |
---|
32 | { |
---|
33 | /// <summary> |
---|
34 | /// Converts from C# AST to CodeDom. |
---|
35 | /// </summary> |
---|
36 | /// <remarks> |
---|
37 | /// The conversion is intended for use in the SharpDevelop forms designer. |
---|
38 | /// </remarks> |
---|
39 | public class CodeDomConvertVisitor : IAstVisitor<CodeObject> |
---|
40 | { |
---|
41 | CSharpAstResolver resolver; |
---|
42 | |
---|
43 | /// <summary> |
---|
44 | /// Gets/Sets whether the visitor should convert short type names into |
---|
45 | /// fully qualified type names. |
---|
46 | /// The default is <c>false</c>. |
---|
47 | /// </summary> |
---|
48 | public bool UseFullyQualifiedTypeNames { get; set; } |
---|
49 | |
---|
50 | /// <summary> |
---|
51 | /// Gets whether the visitor is allowed to produce snippet nodes for |
---|
52 | /// code that cannot be converted. |
---|
53 | /// The default is <c>true</c>. If this property is set to <c>false</c>, |
---|
54 | /// unconvertible code will throw a NotSupportedException. |
---|
55 | /// </summary> |
---|
56 | public bool AllowSnippetNodes { get; set; } |
---|
57 | |
---|
58 | public CodeDomConvertVisitor() |
---|
59 | { |
---|
60 | this.AllowSnippetNodes = true; |
---|
61 | } |
---|
62 | |
---|
63 | /// <summary> |
---|
64 | /// Converts a syntax tree to CodeDom. |
---|
65 | /// </summary> |
---|
66 | /// <param name="syntaxTree">The input syntax tree.</param> |
---|
67 | /// <param name="compilation">The current compilation.</param> |
---|
68 | /// <param name="unresolvedFile">CSharpUnresolvedFile, used for resolving.</param> |
---|
69 | /// <returns>Converted CodeCompileUnit</returns> |
---|
70 | /// <remarks> |
---|
71 | /// This conversion process requires a resolver because it needs to distinguish field/property/event references etc. |
---|
72 | /// </remarks> |
---|
73 | public CodeCompileUnit Convert(ICompilation compilation, SyntaxTree syntaxTree, CSharpUnresolvedFile unresolvedFile) |
---|
74 | { |
---|
75 | if (syntaxTree == null) |
---|
76 | throw new ArgumentNullException("syntaxTree"); |
---|
77 | if (compilation == null) |
---|
78 | throw new ArgumentNullException("compilation"); |
---|
79 | |
---|
80 | CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, unresolvedFile); |
---|
81 | return (CodeCompileUnit)Convert(syntaxTree, resolver); |
---|
82 | } |
---|
83 | |
---|
84 | /// <summary> |
---|
85 | /// Converts a C# AST node to CodeDom. |
---|
86 | /// </summary> |
---|
87 | /// <param name="node">The input node.</param> |
---|
88 | /// <param name="resolver">The AST resolver.</param> |
---|
89 | /// <returns>The node converted into CodeDom</returns> |
---|
90 | /// <remarks> |
---|
91 | /// This conversion process requires a resolver because it needs to distinguish field/property/event references etc. |
---|
92 | /// </remarks> |
---|
93 | public CodeObject Convert(AstNode node, CSharpAstResolver resolver) |
---|
94 | { |
---|
95 | if (node == null) |
---|
96 | throw new ArgumentNullException("node"); |
---|
97 | if (resolver == null) |
---|
98 | throw new ArgumentNullException("resolver"); |
---|
99 | try { |
---|
100 | this.resolver = resolver; |
---|
101 | return node.AcceptVisitor(this); |
---|
102 | } finally { |
---|
103 | this.resolver = null; |
---|
104 | } |
---|
105 | } |
---|
106 | |
---|
107 | ResolveResult Resolve(AstNode node) |
---|
108 | { |
---|
109 | if (resolver == null) |
---|
110 | return ErrorResolveResult.UnknownError; |
---|
111 | else |
---|
112 | return resolver.Resolve(node); |
---|
113 | } |
---|
114 | |
---|
115 | CodeExpression Convert(Expression expr) |
---|
116 | { |
---|
117 | return (CodeExpression)expr.AcceptVisitor(this); |
---|
118 | } |
---|
119 | |
---|
120 | CodeExpression[] Convert(IEnumerable<Expression> expressions) |
---|
121 | { |
---|
122 | List<CodeExpression> result = new List<CodeExpression>(); |
---|
123 | foreach (Expression expr in expressions) { |
---|
124 | CodeExpression e = Convert(expr); |
---|
125 | if (e != null) |
---|
126 | result.Add(e); |
---|
127 | } |
---|
128 | return result.ToArray(); |
---|
129 | } |
---|
130 | |
---|
131 | CodeTypeReference Convert(AstType type) |
---|
132 | { |
---|
133 | return (CodeTypeReference)type.AcceptVisitor(this); |
---|
134 | } |
---|
135 | |
---|
136 | CodeTypeReference[] Convert(IEnumerable<AstType> types) |
---|
137 | { |
---|
138 | List<CodeTypeReference> result = new List<CodeTypeReference>(); |
---|
139 | foreach (AstType type in types) { |
---|
140 | CodeTypeReference e = Convert(type); |
---|
141 | if (e != null) |
---|
142 | result.Add(e); |
---|
143 | } |
---|
144 | return result.ToArray(); |
---|
145 | } |
---|
146 | |
---|
147 | public CodeTypeReference Convert(IType type) |
---|
148 | { |
---|
149 | if (type.Kind == TypeKind.Array) { |
---|
150 | ArrayType a = (ArrayType)type; |
---|
151 | return new CodeTypeReference(Convert(a.ElementType), a.Dimensions); |
---|
152 | } else if (type is ParameterizedType) { |
---|
153 | var pt = (ParameterizedType)type; |
---|
154 | return new CodeTypeReference(pt.GetDefinition().ReflectionName, pt.TypeArguments.Select(Convert).ToArray()); |
---|
155 | } else { |
---|
156 | return new CodeTypeReference(type.ReflectionName); |
---|
157 | } |
---|
158 | } |
---|
159 | |
---|
160 | CodeStatement Convert(Statement stmt) |
---|
161 | { |
---|
162 | return (CodeStatement)stmt.AcceptVisitor(this); |
---|
163 | } |
---|
164 | |
---|
165 | CodeStatement[] ConvertBlock(BlockStatement block) |
---|
166 | { |
---|
167 | List<CodeStatement> result = new List<CodeStatement>(); |
---|
168 | foreach (Statement stmt in block.Statements) { |
---|
169 | if (stmt is EmptyStatement) |
---|
170 | continue; |
---|
171 | CodeStatement s = Convert(stmt); |
---|
172 | if (s != null) |
---|
173 | result.Add(s); |
---|
174 | } |
---|
175 | return result.ToArray(); |
---|
176 | } |
---|
177 | |
---|
178 | CodeStatement[] ConvertEmbeddedStatement(Statement embeddedStatement) |
---|
179 | { |
---|
180 | BlockStatement block = embeddedStatement as BlockStatement; |
---|
181 | if (block != null) { |
---|
182 | return ConvertBlock(block); |
---|
183 | } else if (embeddedStatement is EmptyStatement) { |
---|
184 | return new CodeStatement[0]; |
---|
185 | } |
---|
186 | CodeStatement s = Convert(embeddedStatement); |
---|
187 | if (s != null) |
---|
188 | return new CodeStatement[] { s }; |
---|
189 | else |
---|
190 | return new CodeStatement[0]; |
---|
191 | } |
---|
192 | |
---|
193 | string MakeSnippet(AstNode node) |
---|
194 | { |
---|
195 | if (!AllowSnippetNodes) |
---|
196 | throw new NotSupportedException(); |
---|
197 | StringWriter w = new StringWriter(); |
---|
198 | CSharpOutputVisitor v = new CSharpOutputVisitor(w, FormattingOptionsFactory.CreateMono ()); |
---|
199 | node.AcceptVisitor(v); |
---|
200 | return w.ToString(); |
---|
201 | } |
---|
202 | |
---|
203 | /// <summary> |
---|
204 | /// Converts an expression by storing it as C# snippet. |
---|
205 | /// This is used for expressions that cannot be represented in CodeDom. |
---|
206 | /// </summary> |
---|
207 | CodeSnippetExpression MakeSnippetExpression(Expression expr) |
---|
208 | { |
---|
209 | return new CodeSnippetExpression(MakeSnippet(expr)); |
---|
210 | } |
---|
211 | |
---|
212 | CodeSnippetStatement MakeSnippetStatement(Statement stmt) |
---|
213 | { |
---|
214 | return new CodeSnippetStatement(MakeSnippet(stmt)); |
---|
215 | } |
---|
216 | |
---|
217 | CodeObject IAstVisitor<CodeObject>.VisitNullNode(AstNode nullNode) |
---|
218 | { |
---|
219 | return null; |
---|
220 | } |
---|
221 | |
---|
222 | CodeObject IAstVisitor<CodeObject>.VisitErrorNode(AstNode errorNode) |
---|
223 | { |
---|
224 | return null; |
---|
225 | } |
---|
226 | |
---|
227 | CodeObject IAstVisitor<CodeObject>.VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression) |
---|
228 | { |
---|
229 | return MakeSnippetExpression(anonymousMethodExpression); |
---|
230 | } |
---|
231 | |
---|
232 | CodeObject IAstVisitor<CodeObject>.VisitUndocumentedExpression(UndocumentedExpression undocumentedExpression) |
---|
233 | { |
---|
234 | return MakeSnippetExpression(undocumentedExpression); |
---|
235 | } |
---|
236 | |
---|
237 | CodeObject IAstVisitor<CodeObject>.VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression) |
---|
238 | { |
---|
239 | CodeArrayCreateExpression ace = new CodeArrayCreateExpression(); |
---|
240 | int dimensions = arrayCreateExpression.Arguments.Count; |
---|
241 | int nestingDepth = arrayCreateExpression.AdditionalArraySpecifiers.Count; |
---|
242 | if (dimensions > 0) |
---|
243 | nestingDepth++; |
---|
244 | if (nestingDepth > 1 || dimensions > 1) { |
---|
245 | // CodeDom does not support jagged or multi-dimensional arrays |
---|
246 | return MakeSnippetExpression(arrayCreateExpression); |
---|
247 | } |
---|
248 | if (arrayCreateExpression.Type.IsNull) { |
---|
249 | ace.CreateType = Convert(Resolve(arrayCreateExpression).Type); |
---|
250 | } else { |
---|
251 | ace.CreateType = Convert(arrayCreateExpression.Type); |
---|
252 | } |
---|
253 | if (arrayCreateExpression.Arguments.Count == 1) { |
---|
254 | ace.SizeExpression = Convert(arrayCreateExpression.Arguments.Single()); |
---|
255 | } |
---|
256 | ace.Initializers.AddRange(Convert(arrayCreateExpression.Initializer.Elements)); |
---|
257 | return ace; |
---|
258 | } |
---|
259 | |
---|
260 | CodeObject IAstVisitor<CodeObject>.VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression) |
---|
261 | { |
---|
262 | // Array initializers should be handled by the parent node |
---|
263 | return MakeSnippetExpression(arrayInitializerExpression); |
---|
264 | } |
---|
265 | |
---|
266 | CodeObject IAstVisitor<CodeObject>.VisitAsExpression(AsExpression asExpression) |
---|
267 | { |
---|
268 | return MakeSnippetExpression(asExpression); |
---|
269 | } |
---|
270 | |
---|
271 | CodeObject IAstVisitor<CodeObject>.VisitAssignmentExpression(AssignmentExpression assignmentExpression) |
---|
272 | { |
---|
273 | // assignments are only supported as statements, not as expressions |
---|
274 | return MakeSnippetExpression(assignmentExpression); |
---|
275 | } |
---|
276 | |
---|
277 | CodeObject IAstVisitor<CodeObject>.VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression) |
---|
278 | { |
---|
279 | return new CodeBaseReferenceExpression(); |
---|
280 | } |
---|
281 | |
---|
282 | CodeObject IAstVisitor<CodeObject>.VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression) |
---|
283 | { |
---|
284 | CodeBinaryOperatorType op; |
---|
285 | switch (binaryOperatorExpression.Operator) { |
---|
286 | case BinaryOperatorType.BitwiseAnd: |
---|
287 | op = CodeBinaryOperatorType.BitwiseAnd; |
---|
288 | break; |
---|
289 | case BinaryOperatorType.BitwiseOr: |
---|
290 | op = CodeBinaryOperatorType.BitwiseOr; |
---|
291 | break; |
---|
292 | case BinaryOperatorType.ConditionalAnd: |
---|
293 | op = CodeBinaryOperatorType.BooleanAnd; |
---|
294 | break; |
---|
295 | case BinaryOperatorType.ConditionalOr: |
---|
296 | op = CodeBinaryOperatorType.BooleanOr; |
---|
297 | break; |
---|
298 | case BinaryOperatorType.GreaterThan: |
---|
299 | op = CodeBinaryOperatorType.GreaterThan; |
---|
300 | break; |
---|
301 | case BinaryOperatorType.GreaterThanOrEqual: |
---|
302 | op = CodeBinaryOperatorType.GreaterThanOrEqual; |
---|
303 | break; |
---|
304 | case BinaryOperatorType.LessThan: |
---|
305 | op = CodeBinaryOperatorType.LessThan; |
---|
306 | break; |
---|
307 | case BinaryOperatorType.LessThanOrEqual: |
---|
308 | op = CodeBinaryOperatorType.LessThanOrEqual; |
---|
309 | break; |
---|
310 | case BinaryOperatorType.Add: |
---|
311 | op = CodeBinaryOperatorType.Add; |
---|
312 | break; |
---|
313 | case BinaryOperatorType.Subtract: |
---|
314 | op = CodeBinaryOperatorType.Subtract; |
---|
315 | break; |
---|
316 | case BinaryOperatorType.Multiply: |
---|
317 | op = CodeBinaryOperatorType.Multiply; |
---|
318 | break; |
---|
319 | case BinaryOperatorType.Divide: |
---|
320 | op = CodeBinaryOperatorType.Divide; |
---|
321 | break; |
---|
322 | case BinaryOperatorType.Modulus: |
---|
323 | op = CodeBinaryOperatorType.Modulus; |
---|
324 | break; |
---|
325 | case BinaryOperatorType.Equality: |
---|
326 | case BinaryOperatorType.InEquality: |
---|
327 | OperatorResolveResult rr = Resolve(binaryOperatorExpression) as OperatorResolveResult; |
---|
328 | if (rr != null && rr.GetChildResults().Any(cr => cr.Type.IsReferenceType == true)) { |
---|
329 | if (binaryOperatorExpression.Operator == BinaryOperatorType.Equality) |
---|
330 | op = CodeBinaryOperatorType.IdentityEquality; |
---|
331 | else |
---|
332 | op = CodeBinaryOperatorType.IdentityInequality; |
---|
333 | } else { |
---|
334 | if (binaryOperatorExpression.Operator == BinaryOperatorType.Equality) { |
---|
335 | op = CodeBinaryOperatorType.ValueEquality; |
---|
336 | } else { |
---|
337 | // CodeDom is retarded and does not support ValueInequality, so we'll simulate it using |
---|
338 | // ValueEquality and Not... but CodeDom doesn't have Not either, so we use |
---|
339 | // '(a == b) == false' |
---|
340 | return new CodeBinaryOperatorExpression( |
---|
341 | new CodeBinaryOperatorExpression( |
---|
342 | Convert(binaryOperatorExpression.Left), |
---|
343 | CodeBinaryOperatorType.ValueEquality, |
---|
344 | Convert(binaryOperatorExpression.Right) |
---|
345 | ), |
---|
346 | CodeBinaryOperatorType.ValueEquality, |
---|
347 | new CodePrimitiveExpression(false) |
---|
348 | ); |
---|
349 | } |
---|
350 | } |
---|
351 | break; |
---|
352 | default: |
---|
353 | // not supported: xor, shift, null coalescing |
---|
354 | return MakeSnippetExpression(binaryOperatorExpression); |
---|
355 | } |
---|
356 | return new CodeBinaryOperatorExpression(Convert(binaryOperatorExpression.Left), op, Convert(binaryOperatorExpression.Right)); |
---|
357 | } |
---|
358 | |
---|
359 | CodeObject IAstVisitor<CodeObject>.VisitCastExpression(CastExpression castExpression) |
---|
360 | { |
---|
361 | return new CodeCastExpression(Convert(castExpression.Type), Convert(castExpression.Expression)); |
---|
362 | } |
---|
363 | |
---|
364 | CodeObject IAstVisitor<CodeObject>.VisitCheckedExpression(CheckedExpression checkedExpression) |
---|
365 | { |
---|
366 | return MakeSnippetExpression(checkedExpression); |
---|
367 | } |
---|
368 | |
---|
369 | CodeObject IAstVisitor<CodeObject>.VisitConditionalExpression(ConditionalExpression conditionalExpression) |
---|
370 | { |
---|
371 | return MakeSnippetExpression(conditionalExpression); |
---|
372 | } |
---|
373 | |
---|
374 | CodeObject IAstVisitor<CodeObject>.VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression) |
---|
375 | { |
---|
376 | return new CodeDefaultValueExpression(Convert(defaultValueExpression.Type)); |
---|
377 | } |
---|
378 | |
---|
379 | CodeObject IAstVisitor<CodeObject>.VisitDirectionExpression(DirectionExpression directionExpression) |
---|
380 | { |
---|
381 | System.CodeDom.FieldDirection direction; |
---|
382 | if (directionExpression.FieldDirection == FieldDirection.Out) { |
---|
383 | direction = System.CodeDom.FieldDirection.Out; |
---|
384 | } else { |
---|
385 | direction = System.CodeDom.FieldDirection.Ref; |
---|
386 | } |
---|
387 | return new CodeDirectionExpression(direction, Convert(directionExpression.Expression)); |
---|
388 | } |
---|
389 | |
---|
390 | CodeObject IAstVisitor<CodeObject>.VisitIdentifierExpression(IdentifierExpression identifierExpression) |
---|
391 | { |
---|
392 | ResolveResult rr = Resolve(identifierExpression); |
---|
393 | LocalResolveResult lrr = rr as LocalResolveResult; |
---|
394 | if (lrr != null && lrr.IsParameter) { |
---|
395 | if (lrr.Variable.Name == "value" && identifierExpression.Ancestors.Any(a => a is Accessor)) { |
---|
396 | return new CodePropertySetValueReferenceExpression(); |
---|
397 | } else { |
---|
398 | return new CodeArgumentReferenceExpression(lrr.Variable.Name); |
---|
399 | } |
---|
400 | } |
---|
401 | MemberResolveResult mrr = rr as MemberResolveResult; |
---|
402 | if (mrr != null) { |
---|
403 | return HandleMemberReference(null, identifierExpression.Identifier, identifierExpression.TypeArguments, mrr); |
---|
404 | } |
---|
405 | TypeResolveResult trr = rr as TypeResolveResult; |
---|
406 | if (trr != null) { |
---|
407 | CodeTypeReference typeRef; |
---|
408 | if (UseFullyQualifiedTypeNames) { |
---|
409 | typeRef = Convert(trr.Type); |
---|
410 | } else { |
---|
411 | typeRef = new CodeTypeReference(identifierExpression.Identifier); |
---|
412 | typeRef.TypeArguments.AddRange(Convert(identifierExpression.TypeArguments)); |
---|
413 | } |
---|
414 | return new CodeTypeReferenceExpression(typeRef); |
---|
415 | } |
---|
416 | MethodGroupResolveResult mgrr = rr as MethodGroupResolveResult; |
---|
417 | if (mgrr != null || identifierExpression.TypeArguments.Any()) { |
---|
418 | return new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), identifierExpression.Identifier, Convert(identifierExpression.TypeArguments)); |
---|
419 | } |
---|
420 | return new CodeVariableReferenceExpression(identifierExpression.Identifier); |
---|
421 | } |
---|
422 | |
---|
423 | CodeObject IAstVisitor<CodeObject>.VisitIndexerExpression(IndexerExpression indexerExpression) |
---|
424 | { |
---|
425 | if (Resolve(indexerExpression) is ArrayAccessResolveResult) |
---|
426 | return new CodeArrayIndexerExpression(Convert(indexerExpression.Target), Convert(indexerExpression.Arguments)); |
---|
427 | else |
---|
428 | return new CodeIndexerExpression(Convert(indexerExpression.Target), Convert(indexerExpression.Arguments)); |
---|
429 | } |
---|
430 | |
---|
431 | CodeObject IAstVisitor<CodeObject>.VisitInvocationExpression(InvocationExpression invocationExpression) |
---|
432 | { |
---|
433 | MemberResolveResult rr = Resolve(invocationExpression) as MemberResolveResult; |
---|
434 | CSharpInvocationResolveResult csRR = rr as CSharpInvocationResolveResult; |
---|
435 | if (csRR != null && csRR.IsDelegateInvocation) { |
---|
436 | return new CodeDelegateInvokeExpression(Convert(invocationExpression.Target), Convert(invocationExpression.Arguments)); |
---|
437 | } |
---|
438 | |
---|
439 | Expression methodExpr = invocationExpression.Target; |
---|
440 | while (methodExpr is ParenthesizedExpression) |
---|
441 | methodExpr = ((ParenthesizedExpression)methodExpr).Expression; |
---|
442 | CodeMethodReferenceExpression mr = null; |
---|
443 | MemberReferenceExpression mre = methodExpr as MemberReferenceExpression; |
---|
444 | if (mre != null) { |
---|
445 | mr = new CodeMethodReferenceExpression(Convert(mre.Target), mre.MemberName, Convert(mre.TypeArguments)); |
---|
446 | } |
---|
447 | IdentifierExpression id = methodExpr as IdentifierExpression; |
---|
448 | if (id != null) { |
---|
449 | CodeExpression target; |
---|
450 | if (rr != null && rr.Member.IsStatic) |
---|
451 | target = new CodeTypeReferenceExpression(Convert(rr.Member.DeclaringType)); |
---|
452 | else |
---|
453 | target = new CodeThisReferenceExpression(); |
---|
454 | |
---|
455 | mr = new CodeMethodReferenceExpression(target, id.Identifier, Convert(id.TypeArguments)); |
---|
456 | } |
---|
457 | if (mr != null) |
---|
458 | return new CodeMethodInvokeExpression(mr, Convert(invocationExpression.Arguments)); |
---|
459 | else |
---|
460 | return MakeSnippetExpression(invocationExpression); |
---|
461 | } |
---|
462 | |
---|
463 | CodeObject IAstVisitor<CodeObject>.VisitIsExpression(IsExpression isExpression) |
---|
464 | { |
---|
465 | return MakeSnippetExpression(isExpression); |
---|
466 | } |
---|
467 | |
---|
468 | CodeObject IAstVisitor<CodeObject>.VisitLambdaExpression(LambdaExpression lambdaExpression) |
---|
469 | { |
---|
470 | return MakeSnippetExpression(lambdaExpression); |
---|
471 | } |
---|
472 | |
---|
473 | CodeObject IAstVisitor<CodeObject>.VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) |
---|
474 | { |
---|
475 | CodeExpression target = Convert(memberReferenceExpression.Target); |
---|
476 | ResolveResult rr = Resolve(memberReferenceExpression); |
---|
477 | MemberResolveResult mrr = rr as MemberResolveResult; |
---|
478 | TypeResolveResult trr = rr as TypeResolveResult; |
---|
479 | if (mrr != null) { |
---|
480 | return HandleMemberReference(target, memberReferenceExpression.MemberName, memberReferenceExpression.TypeArguments, mrr); |
---|
481 | } else if (trr != null) { |
---|
482 | return new CodeTypeReferenceExpression(Convert(trr.Type)); |
---|
483 | } else { |
---|
484 | if (memberReferenceExpression.TypeArguments.Any() || rr is MethodGroupResolveResult) { |
---|
485 | return new CodeMethodReferenceExpression(target, memberReferenceExpression.MemberName, Convert(memberReferenceExpression.TypeArguments)); |
---|
486 | } else { |
---|
487 | return new CodePropertyReferenceExpression(target, memberReferenceExpression.MemberName); |
---|
488 | } |
---|
489 | } |
---|
490 | } |
---|
491 | |
---|
492 | CodeExpression HandleMemberReference(CodeExpression target, string identifier, AstNodeCollection<AstType> typeArguments, MemberResolveResult mrr) |
---|
493 | { |
---|
494 | if (target == null) { |
---|
495 | if (mrr.Member.IsStatic) |
---|
496 | target = new CodeTypeReferenceExpression(Convert(mrr.Member.DeclaringType)); |
---|
497 | else |
---|
498 | target = new CodeThisReferenceExpression(); |
---|
499 | } |
---|
500 | if (mrr.Member is IField) { |
---|
501 | return new CodeFieldReferenceExpression(target, identifier); |
---|
502 | } else if (mrr.Member is IMethod) { |
---|
503 | return new CodeMethodReferenceExpression(target, identifier, Convert(typeArguments)); |
---|
504 | } else if (mrr.Member is IEvent) { |
---|
505 | return new CodeEventReferenceExpression(target, identifier); |
---|
506 | } else { |
---|
507 | return new CodePropertyReferenceExpression(target, identifier); |
---|
508 | } |
---|
509 | } |
---|
510 | |
---|
511 | CodeObject IAstVisitor<CodeObject>.VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression) |
---|
512 | { |
---|
513 | return MakeSnippetExpression(namedArgumentExpression); |
---|
514 | } |
---|
515 | |
---|
516 | CodeObject IAstVisitor<CodeObject>.VisitNamedExpression(NamedExpression namedExpression) |
---|
517 | { |
---|
518 | return MakeSnippetExpression(namedExpression); |
---|
519 | } |
---|
520 | |
---|
521 | CodeObject IAstVisitor<CodeObject>.VisitNullReferenceExpression(NullReferenceExpression nullReferenceExpression) |
---|
522 | { |
---|
523 | return new CodePrimitiveExpression(null); |
---|
524 | } |
---|
525 | |
---|
526 | CodeObject IAstVisitor<CodeObject>.VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression) |
---|
527 | { |
---|
528 | if (!objectCreateExpression.Initializer.IsNull) |
---|
529 | return MakeSnippetExpression(objectCreateExpression); |
---|
530 | return new CodeObjectCreateExpression(Convert(objectCreateExpression.Type), Convert(objectCreateExpression.Arguments)); |
---|
531 | } |
---|
532 | |
---|
533 | CodeObject IAstVisitor<CodeObject>.VisitAnonymousTypeCreateExpression(AnonymousTypeCreateExpression anonymousTypeCreateExpression) |
---|
534 | { |
---|
535 | return MakeSnippetExpression(anonymousTypeCreateExpression); |
---|
536 | } |
---|
537 | |
---|
538 | CodeObject IAstVisitor<CodeObject>.VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression) |
---|
539 | { |
---|
540 | // CodeDom generators will insert parentheses where necessary |
---|
541 | return Convert(parenthesizedExpression.Expression); |
---|
542 | } |
---|
543 | |
---|
544 | CodeObject IAstVisitor<CodeObject>.VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression) |
---|
545 | { |
---|
546 | return MakeSnippetExpression(pointerReferenceExpression); |
---|
547 | } |
---|
548 | |
---|
549 | CodeObject IAstVisitor<CodeObject>.VisitPrimitiveExpression(PrimitiveExpression primitiveExpression) |
---|
550 | { |
---|
551 | return new CodePrimitiveExpression(primitiveExpression.Value); |
---|
552 | } |
---|
553 | |
---|
554 | CodeObject IAstVisitor<CodeObject>.VisitSizeOfExpression(SizeOfExpression sizeOfExpression) |
---|
555 | { |
---|
556 | return MakeSnippetExpression(sizeOfExpression); |
---|
557 | } |
---|
558 | |
---|
559 | CodeObject IAstVisitor<CodeObject>.VisitStackAllocExpression(StackAllocExpression stackAllocExpression) |
---|
560 | { |
---|
561 | return MakeSnippetExpression(stackAllocExpression); |
---|
562 | } |
---|
563 | |
---|
564 | CodeObject IAstVisitor<CodeObject>.VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression) |
---|
565 | { |
---|
566 | return new CodeThisReferenceExpression(); |
---|
567 | } |
---|
568 | |
---|
569 | CodeObject IAstVisitor<CodeObject>.VisitTypeOfExpression(TypeOfExpression typeOfExpression) |
---|
570 | { |
---|
571 | return new CodeTypeOfExpression(Convert(typeOfExpression.Type)); |
---|
572 | } |
---|
573 | |
---|
574 | CodeObject IAstVisitor<CodeObject>.VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression) |
---|
575 | { |
---|
576 | return new CodeTypeReferenceExpression(Convert(typeReferenceExpression.Type)); |
---|
577 | } |
---|
578 | |
---|
579 | CodeObject IAstVisitor<CodeObject>.VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression) |
---|
580 | { |
---|
581 | switch (unaryOperatorExpression.Operator) { |
---|
582 | case UnaryOperatorType.Not: |
---|
583 | return new CodeBinaryOperatorExpression( |
---|
584 | Convert(unaryOperatorExpression.Expression), |
---|
585 | CodeBinaryOperatorType.ValueEquality, |
---|
586 | new CodePrimitiveExpression(false)); |
---|
587 | case UnaryOperatorType.Minus: |
---|
588 | return new CodeBinaryOperatorExpression( |
---|
589 | new CodePrimitiveExpression(0), |
---|
590 | CodeBinaryOperatorType.Subtract, |
---|
591 | Convert(unaryOperatorExpression.Expression)); |
---|
592 | case UnaryOperatorType.Plus: |
---|
593 | return Convert(unaryOperatorExpression.Expression); |
---|
594 | default: |
---|
595 | return MakeSnippetExpression(unaryOperatorExpression); |
---|
596 | } |
---|
597 | } |
---|
598 | |
---|
599 | CodeObject IAstVisitor<CodeObject>.VisitUncheckedExpression(UncheckedExpression uncheckedExpression) |
---|
600 | { |
---|
601 | return MakeSnippetExpression(uncheckedExpression); |
---|
602 | } |
---|
603 | |
---|
604 | CodeObject IAstVisitor<CodeObject>.VisitQueryExpression(QueryExpression queryExpression) |
---|
605 | { |
---|
606 | return MakeSnippetExpression(queryExpression); |
---|
607 | } |
---|
608 | |
---|
609 | CodeObject IAstVisitor<CodeObject>.VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause) |
---|
610 | { |
---|
611 | throw new NotSupportedException(); |
---|
612 | } |
---|
613 | |
---|
614 | CodeObject IAstVisitor<CodeObject>.VisitQueryFromClause(QueryFromClause queryFromClause) |
---|
615 | { |
---|
616 | throw new NotSupportedException(); |
---|
617 | } |
---|
618 | |
---|
619 | CodeObject IAstVisitor<CodeObject>.VisitQueryLetClause(QueryLetClause queryLetClause) |
---|
620 | { |
---|
621 | throw new NotSupportedException(); |
---|
622 | } |
---|
623 | |
---|
624 | CodeObject IAstVisitor<CodeObject>.VisitQueryWhereClause(QueryWhereClause queryWhereClause) |
---|
625 | { |
---|
626 | throw new NotSupportedException(); |
---|
627 | } |
---|
628 | |
---|
629 | CodeObject IAstVisitor<CodeObject>.VisitQueryJoinClause(QueryJoinClause queryJoinClause) |
---|
630 | { |
---|
631 | throw new NotSupportedException(); |
---|
632 | } |
---|
633 | |
---|
634 | CodeObject IAstVisitor<CodeObject>.VisitQueryOrderClause(QueryOrderClause queryOrderClause) |
---|
635 | { |
---|
636 | throw new NotSupportedException(); |
---|
637 | } |
---|
638 | |
---|
639 | CodeObject IAstVisitor<CodeObject>.VisitQueryOrdering(QueryOrdering queryOrdering) |
---|
640 | { |
---|
641 | throw new NotSupportedException(); |
---|
642 | } |
---|
643 | |
---|
644 | CodeObject IAstVisitor<CodeObject>.VisitQuerySelectClause(QuerySelectClause querySelectClause) |
---|
645 | { |
---|
646 | throw new NotSupportedException(); |
---|
647 | } |
---|
648 | |
---|
649 | CodeObject IAstVisitor<CodeObject>.VisitQueryGroupClause(QueryGroupClause queryGroupClause) |
---|
650 | { |
---|
651 | throw new NotSupportedException(); |
---|
652 | } |
---|
653 | |
---|
654 | CodeObject IAstVisitor<CodeObject>.VisitAttribute(Attribute attribute) |
---|
655 | { |
---|
656 | throw new NotSupportedException(); |
---|
657 | } |
---|
658 | |
---|
659 | CodeObject IAstVisitor<CodeObject>.VisitAttributeSection(AttributeSection attributeSection) |
---|
660 | { |
---|
661 | throw new NotSupportedException(); |
---|
662 | } |
---|
663 | |
---|
664 | CodeAttributeDeclaration Convert(Attribute attribute) |
---|
665 | { |
---|
666 | var attr = new CodeAttributeDeclaration(Convert(attribute.Type)); |
---|
667 | foreach (Expression expr in attribute.Arguments) { |
---|
668 | NamedExpression ne = expr as NamedExpression; |
---|
669 | if (ne != null) |
---|
670 | attr.Arguments.Add(new CodeAttributeArgument(ne.Name, Convert(ne.Expression))); |
---|
671 | else |
---|
672 | attr.Arguments.Add(new CodeAttributeArgument(Convert(expr))); |
---|
673 | } |
---|
674 | return attr; |
---|
675 | } |
---|
676 | |
---|
677 | CodeAttributeDeclaration[] Convert(IEnumerable<AttributeSection> attributeSections) |
---|
678 | { |
---|
679 | List<CodeAttributeDeclaration> result = new List<CodeAttributeDeclaration>(); |
---|
680 | foreach (AttributeSection section in attributeSections) { |
---|
681 | foreach (Attribute attr in section.Attributes) { |
---|
682 | CodeAttributeDeclaration attrDecl = Convert(attr); |
---|
683 | if (attrDecl != null) |
---|
684 | result.Add(attrDecl); |
---|
685 | } |
---|
686 | } |
---|
687 | return result.ToArray(); |
---|
688 | } |
---|
689 | |
---|
690 | CodeObject IAstVisitor<CodeObject>.VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration) |
---|
691 | { |
---|
692 | CodeTypeDelegate d = new CodeTypeDelegate(delegateDeclaration.Name); |
---|
693 | d.Attributes = ConvertMemberAttributes(delegateDeclaration.Modifiers, SymbolKind.TypeDefinition); |
---|
694 | d.CustomAttributes.AddRange(Convert(delegateDeclaration.Attributes)); |
---|
695 | d.ReturnType = Convert(delegateDeclaration.ReturnType); |
---|
696 | d.Parameters.AddRange(Convert(delegateDeclaration.Parameters)); |
---|
697 | d.TypeParameters.AddRange(ConvertTypeParameters(delegateDeclaration.TypeParameters, delegateDeclaration.Constraints)); |
---|
698 | return d; |
---|
699 | } |
---|
700 | |
---|
701 | MemberAttributes ConvertMemberAttributes(Modifiers modifiers, SymbolKind symbolKind) |
---|
702 | { |
---|
703 | MemberAttributes a = 0; |
---|
704 | if ((modifiers & Modifiers.Abstract) != 0) |
---|
705 | a |= MemberAttributes.Abstract; |
---|
706 | if ((modifiers & Modifiers.Sealed) != 0) |
---|
707 | a |= MemberAttributes.Final; |
---|
708 | if (symbolKind != SymbolKind.TypeDefinition && (modifiers & (Modifiers.Abstract | Modifiers.Override | Modifiers.Virtual)) == 0) |
---|
709 | a |= MemberAttributes.Final; |
---|
710 | if ((modifiers & Modifiers.Static) != 0) |
---|
711 | a |= MemberAttributes.Static; |
---|
712 | if ((modifiers & Modifiers.Override) != 0) |
---|
713 | a |= MemberAttributes.Override; |
---|
714 | if ((modifiers & Modifiers.Const) != 0) |
---|
715 | a |= MemberAttributes.Const; |
---|
716 | if ((modifiers & Modifiers.New) != 0) |
---|
717 | a |= MemberAttributes.New; |
---|
718 | |
---|
719 | if ((modifiers & Modifiers.Public) != 0) |
---|
720 | a |= MemberAttributes.Public; |
---|
721 | else if ((modifiers & (Modifiers.Protected | Modifiers.Internal)) == (Modifiers.Protected | Modifiers.Internal)) |
---|
722 | a |= MemberAttributes.FamilyOrAssembly; |
---|
723 | else if ((modifiers & Modifiers.Protected) != 0) |
---|
724 | a |= MemberAttributes.Family; |
---|
725 | else if ((modifiers & Modifiers.Internal) != 0) |
---|
726 | a |= MemberAttributes.Assembly; |
---|
727 | else if ((modifiers & Modifiers.Private) != 0) |
---|
728 | a |= MemberAttributes.Private; |
---|
729 | |
---|
730 | return a; |
---|
731 | } |
---|
732 | |
---|
733 | CodeObject IAstVisitor<CodeObject>.VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration) |
---|
734 | { |
---|
735 | CodeNamespace ns = new CodeNamespace(namespaceDeclaration.Name); |
---|
736 | foreach (AstNode node in namespaceDeclaration.Members) { |
---|
737 | CodeObject r = node.AcceptVisitor(this); |
---|
738 | |
---|
739 | CodeNamespaceImport import = r as CodeNamespaceImport; |
---|
740 | if (import != null) |
---|
741 | ns.Imports.Add(import); |
---|
742 | |
---|
743 | CodeTypeDeclaration typeDecl = r as CodeTypeDeclaration; |
---|
744 | if (typeDecl != null) |
---|
745 | ns.Types.Add(typeDecl); |
---|
746 | } |
---|
747 | return ns; |
---|
748 | } |
---|
749 | |
---|
750 | Stack<CodeTypeDeclaration> typeStack = new Stack<CodeTypeDeclaration>(); |
---|
751 | |
---|
752 | CodeObject IAstVisitor<CodeObject>.VisitTypeDeclaration(TypeDeclaration typeDeclaration) |
---|
753 | { |
---|
754 | //bool isNestedType = typeStack.Count > 0; |
---|
755 | CodeTypeDeclaration typeDecl = new CodeTypeDeclaration(typeDeclaration.Name); |
---|
756 | typeDecl.Attributes = ConvertMemberAttributes(typeDeclaration.Modifiers, SymbolKind.TypeDefinition); |
---|
757 | typeDecl.CustomAttributes.AddRange(Convert(typeDeclaration.Attributes)); |
---|
758 | |
---|
759 | switch (typeDeclaration.ClassType) { |
---|
760 | case ClassType.Struct: |
---|
761 | typeDecl.IsStruct = true; |
---|
762 | break; |
---|
763 | case ClassType.Interface: |
---|
764 | typeDecl.IsInterface = true; |
---|
765 | break; |
---|
766 | case ClassType.Enum: |
---|
767 | typeDecl.IsEnum = true; |
---|
768 | break; |
---|
769 | default: |
---|
770 | typeDecl.IsClass = true; |
---|
771 | break; |
---|
772 | } |
---|
773 | typeDecl.IsPartial = (typeDeclaration.Modifiers & Modifiers.Partial) == Modifiers.Partial; |
---|
774 | |
---|
775 | typeDecl.BaseTypes.AddRange(Convert(typeDeclaration.BaseTypes)); |
---|
776 | typeDecl.TypeParameters.AddRange(ConvertTypeParameters(typeDeclaration.TypeParameters, typeDeclaration.Constraints)); |
---|
777 | |
---|
778 | typeStack.Push(typeDecl); |
---|
779 | foreach (var member in typeDeclaration.Members) { |
---|
780 | CodeTypeMember m = member.AcceptVisitor(this) as CodeTypeMember; |
---|
781 | if (m != null) |
---|
782 | typeDecl.Members.Add(m); |
---|
783 | } |
---|
784 | typeStack.Pop(); |
---|
785 | return typeDecl; |
---|
786 | } |
---|
787 | |
---|
788 | void AddTypeMember(CodeTypeMember member) |
---|
789 | { |
---|
790 | if (typeStack.Count != 0) |
---|
791 | typeStack.Peek().Members.Add(member); |
---|
792 | } |
---|
793 | |
---|
794 | CodeObject IAstVisitor<CodeObject>.VisitUsingAliasDeclaration(UsingAliasDeclaration usingAliasDeclaration) |
---|
795 | { |
---|
796 | return new CodeSnippetTypeMember(MakeSnippet(usingAliasDeclaration)); |
---|
797 | } |
---|
798 | |
---|
799 | CodeObject IAstVisitor<CodeObject>.VisitUsingDeclaration(UsingDeclaration usingDeclaration) |
---|
800 | { |
---|
801 | return new CodeNamespaceImport(usingDeclaration.Namespace); |
---|
802 | } |
---|
803 | |
---|
804 | CodeObject IAstVisitor<CodeObject>.VisitExternAliasDeclaration(ExternAliasDeclaration externAliasDeclaration) |
---|
805 | { |
---|
806 | return new CodeSnippetTypeMember(MakeSnippet(externAliasDeclaration)); |
---|
807 | } |
---|
808 | |
---|
809 | CodeObject IAstVisitor<CodeObject>.VisitBlockStatement(BlockStatement blockStatement) |
---|
810 | { |
---|
811 | return new CodeConditionStatement(new CodePrimitiveExpression(true), ConvertBlock(blockStatement)); |
---|
812 | } |
---|
813 | |
---|
814 | CodeObject IAstVisitor<CodeObject>.VisitBreakStatement(BreakStatement breakStatement) |
---|
815 | { |
---|
816 | return MakeSnippetStatement(breakStatement); |
---|
817 | } |
---|
818 | |
---|
819 | CodeObject IAstVisitor<CodeObject>.VisitCheckedStatement(CheckedStatement checkedStatement) |
---|
820 | { |
---|
821 | return MakeSnippetStatement(checkedStatement); |
---|
822 | } |
---|
823 | |
---|
824 | CodeObject IAstVisitor<CodeObject>.VisitContinueStatement(ContinueStatement continueStatement) |
---|
825 | { |
---|
826 | return MakeSnippetStatement(continueStatement); |
---|
827 | } |
---|
828 | |
---|
829 | CodeObject IAstVisitor<CodeObject>.VisitDoWhileStatement(DoWhileStatement doWhileStatement) |
---|
830 | { |
---|
831 | // do { } while (expr); |
---|
832 | // |
---|
833 | // emulate with: |
---|
834 | // for (bool _do = true; _do; _do = expr) {} |
---|
835 | string varName = "_do" + doWhileStatement.Ancestors.OfType<DoWhileStatement>().Count(); |
---|
836 | return new CodeIterationStatement( |
---|
837 | new CodeVariableDeclarationStatement(typeof(bool), varName, new CodePrimitiveExpression(true)), |
---|
838 | new CodeVariableReferenceExpression(varName), |
---|
839 | new CodeAssignStatement(new CodeVariableReferenceExpression(varName), Convert(doWhileStatement.Condition)), |
---|
840 | ConvertEmbeddedStatement(doWhileStatement.EmbeddedStatement) |
---|
841 | ); |
---|
842 | } |
---|
843 | |
---|
844 | CodeObject IAstVisitor<CodeObject>.VisitEmptyStatement(EmptyStatement emptyStatement) |
---|
845 | { |
---|
846 | return EmptyStatement(); |
---|
847 | } |
---|
848 | |
---|
849 | CodeStatement EmptyStatement() |
---|
850 | { |
---|
851 | return new CodeExpressionStatement(new CodeObjectCreateExpression(new CodeTypeReference(typeof(object)))); |
---|
852 | } |
---|
853 | |
---|
854 | CodeObject IAstVisitor<CodeObject>.VisitExpressionStatement(ExpressionStatement expressionStatement) |
---|
855 | { |
---|
856 | AssignmentExpression assignment = expressionStatement.Expression as AssignmentExpression; |
---|
857 | if (assignment != null && assignment.Operator == AssignmentOperatorType.Assign) { |
---|
858 | return new CodeAssignStatement(Convert(assignment.Left), Convert(assignment.Right)); |
---|
859 | } else if (assignment != null && CanBeDuplicatedForCompoundAssignment(assignment.Left)) { |
---|
860 | CodeBinaryOperatorType op; |
---|
861 | switch (assignment.Operator) { |
---|
862 | case AssignmentOperatorType.Add: |
---|
863 | op = CodeBinaryOperatorType.Add; |
---|
864 | break; |
---|
865 | case AssignmentOperatorType.Subtract: |
---|
866 | op = CodeBinaryOperatorType.Subtract; |
---|
867 | break; |
---|
868 | case AssignmentOperatorType.Multiply: |
---|
869 | op = CodeBinaryOperatorType.Multiply; |
---|
870 | break; |
---|
871 | case AssignmentOperatorType.Divide: |
---|
872 | op = CodeBinaryOperatorType.Divide; |
---|
873 | break; |
---|
874 | case AssignmentOperatorType.Modulus: |
---|
875 | op = CodeBinaryOperatorType.Modulus; |
---|
876 | break; |
---|
877 | case AssignmentOperatorType.BitwiseAnd: |
---|
878 | op = CodeBinaryOperatorType.BitwiseAnd; |
---|
879 | break; |
---|
880 | case AssignmentOperatorType.BitwiseOr: |
---|
881 | op = CodeBinaryOperatorType.BitwiseOr; |
---|
882 | break; |
---|
883 | default: |
---|
884 | return MakeSnippetStatement(expressionStatement); |
---|
885 | } |
---|
886 | var cboe = new CodeBinaryOperatorExpression(Convert(assignment.Left), op, Convert(assignment.Right)); |
---|
887 | return new CodeAssignStatement(Convert(assignment.Left), cboe); |
---|
888 | } |
---|
889 | UnaryOperatorExpression unary = expressionStatement.Expression as UnaryOperatorExpression; |
---|
890 | if (unary != null && CanBeDuplicatedForCompoundAssignment(unary.Expression)) { |
---|
891 | var op = unary.Operator; |
---|
892 | if (op == UnaryOperatorType.Increment || op == UnaryOperatorType.PostIncrement) { |
---|
893 | var cboe = new CodeBinaryOperatorExpression(Convert(unary.Expression), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1)); |
---|
894 | return new CodeAssignStatement(Convert(unary.Expression), cboe); |
---|
895 | } else if (op == UnaryOperatorType.Decrement || op == UnaryOperatorType.PostDecrement) { |
---|
896 | var cboe = new CodeBinaryOperatorExpression(Convert(unary.Expression), CodeBinaryOperatorType.Subtract, new CodePrimitiveExpression(1)); |
---|
897 | return new CodeAssignStatement(Convert(unary.Expression), cboe); |
---|
898 | } |
---|
899 | } |
---|
900 | if (assignment != null && assignment.Operator == AssignmentOperatorType.Add) { |
---|
901 | var rr = Resolve(assignment.Left); |
---|
902 | if (!rr.IsError && rr.Type.Kind == TypeKind.Delegate) { |
---|
903 | var expr = (MemberReferenceExpression)assignment.Left; |
---|
904 | var memberRef = (CodeEventReferenceExpression)HandleMemberReference(Convert(expr.Target), expr.MemberName, expr.TypeArguments, (MemberResolveResult)rr); |
---|
905 | return new CodeAttachEventStatement(memberRef, Convert(assignment.Right)); |
---|
906 | } |
---|
907 | } |
---|
908 | return new CodeExpressionStatement(Convert(expressionStatement.Expression)); |
---|
909 | } |
---|
910 | |
---|
911 | bool CanBeDuplicatedForCompoundAssignment(Expression expr) |
---|
912 | { |
---|
913 | return expr is IdentifierExpression; |
---|
914 | } |
---|
915 | |
---|
916 | CodeObject IAstVisitor<CodeObject>.VisitFixedStatement(FixedStatement fixedStatement) |
---|
917 | { |
---|
918 | return MakeSnippetStatement(fixedStatement); |
---|
919 | } |
---|
920 | |
---|
921 | CodeObject IAstVisitor<CodeObject>.VisitForeachStatement(ForeachStatement foreachStatement) |
---|
922 | { |
---|
923 | return MakeSnippetStatement(foreachStatement); |
---|
924 | } |
---|
925 | |
---|
926 | CodeObject IAstVisitor<CodeObject>.VisitForStatement(ForStatement forStatement) |
---|
927 | { |
---|
928 | if (forStatement.Initializers.Count != 1 || forStatement.Iterators.Count != 1) |
---|
929 | return MakeSnippetStatement(forStatement); |
---|
930 | return new CodeIterationStatement( |
---|
931 | Convert(forStatement.Initializers.Single()), |
---|
932 | Convert(forStatement.Condition), |
---|
933 | Convert(forStatement.Iterators.Single()), |
---|
934 | ConvertEmbeddedStatement(forStatement.EmbeddedStatement) |
---|
935 | ); |
---|
936 | } |
---|
937 | |
---|
938 | CodeObject IAstVisitor<CodeObject>.VisitGotoCaseStatement(GotoCaseStatement gotoCaseStatement) |
---|
939 | { |
---|
940 | return MakeSnippetStatement(gotoCaseStatement); |
---|
941 | } |
---|
942 | |
---|
943 | CodeObject IAstVisitor<CodeObject>.VisitGotoDefaultStatement(GotoDefaultStatement gotoDefaultStatement) |
---|
944 | { |
---|
945 | return MakeSnippetStatement(gotoDefaultStatement); |
---|
946 | } |
---|
947 | |
---|
948 | CodeObject IAstVisitor<CodeObject>.VisitGotoStatement(GotoStatement gotoStatement) |
---|
949 | { |
---|
950 | return new CodeGotoStatement(gotoStatement.Label); |
---|
951 | } |
---|
952 | |
---|
953 | CodeObject IAstVisitor<CodeObject>.VisitIfElseStatement(IfElseStatement ifElseStatement) |
---|
954 | { |
---|
955 | return new CodeConditionStatement( |
---|
956 | Convert(ifElseStatement.Condition), |
---|
957 | ConvertEmbeddedStatement(ifElseStatement.TrueStatement), |
---|
958 | ConvertEmbeddedStatement(ifElseStatement.FalseStatement)); |
---|
959 | } |
---|
960 | |
---|
961 | CodeObject IAstVisitor<CodeObject>.VisitLabelStatement(LabelStatement labelStatement) |
---|
962 | { |
---|
963 | return new CodeLabeledStatement(labelStatement.Label); |
---|
964 | } |
---|
965 | |
---|
966 | CodeObject IAstVisitor<CodeObject>.VisitLockStatement(LockStatement lockStatement) |
---|
967 | { |
---|
968 | return MakeSnippetStatement(lockStatement); |
---|
969 | } |
---|
970 | |
---|
971 | CodeObject IAstVisitor<CodeObject>.VisitReturnStatement(ReturnStatement returnStatement) |
---|
972 | { |
---|
973 | return new CodeMethodReturnStatement(Convert(returnStatement.Expression)); |
---|
974 | } |
---|
975 | |
---|
976 | CodeObject IAstVisitor<CodeObject>.VisitSwitchStatement(SwitchStatement switchStatement) |
---|
977 | { |
---|
978 | return MakeSnippetStatement(switchStatement); |
---|
979 | } |
---|
980 | |
---|
981 | CodeObject IAstVisitor<CodeObject>.VisitSwitchSection(SwitchSection switchSection) |
---|
982 | { |
---|
983 | throw new NotSupportedException(); |
---|
984 | } |
---|
985 | |
---|
986 | CodeObject IAstVisitor<CodeObject>.VisitCaseLabel(CaseLabel caseLabel) |
---|
987 | { |
---|
988 | throw new NotSupportedException(); |
---|
989 | } |
---|
990 | |
---|
991 | CodeObject IAstVisitor<CodeObject>.VisitThrowStatement(ThrowStatement throwStatement) |
---|
992 | { |
---|
993 | return new CodeThrowExceptionStatement(Convert(throwStatement.Expression)); |
---|
994 | } |
---|
995 | |
---|
996 | CodeObject IAstVisitor<CodeObject>.VisitTryCatchStatement(TryCatchStatement tryCatchStatement) |
---|
997 | { |
---|
998 | List<CodeCatchClause> catchClauses = new List<CodeCatchClause>(); |
---|
999 | foreach (var catchClause in tryCatchStatement.CatchClauses) { |
---|
1000 | catchClauses.Add(new CodeCatchClause(catchClause.VariableName, Convert(catchClause.Type), ConvertBlock(catchClause.Body))); |
---|
1001 | } |
---|
1002 | return new CodeTryCatchFinallyStatement( |
---|
1003 | ConvertBlock(tryCatchStatement.TryBlock), |
---|
1004 | catchClauses.ToArray(), |
---|
1005 | ConvertBlock(tryCatchStatement.FinallyBlock)); |
---|
1006 | } |
---|
1007 | |
---|
1008 | CodeObject IAstVisitor<CodeObject>.VisitCatchClause(CatchClause catchClause) |
---|
1009 | { |
---|
1010 | throw new NotSupportedException(); |
---|
1011 | } |
---|
1012 | |
---|
1013 | CodeObject IAstVisitor<CodeObject>.VisitUncheckedStatement(UncheckedStatement uncheckedStatement) |
---|
1014 | { |
---|
1015 | return MakeSnippetStatement(uncheckedStatement); |
---|
1016 | } |
---|
1017 | |
---|
1018 | CodeObject IAstVisitor<CodeObject>.VisitUnsafeStatement(UnsafeStatement unsafeStatement) |
---|
1019 | { |
---|
1020 | return MakeSnippetStatement(unsafeStatement); |
---|
1021 | } |
---|
1022 | |
---|
1023 | CodeObject IAstVisitor<CodeObject>.VisitUsingStatement(UsingStatement usingStatement) |
---|
1024 | { |
---|
1025 | return MakeSnippetStatement(usingStatement); |
---|
1026 | } |
---|
1027 | |
---|
1028 | CodeObject IAstVisitor<CodeObject>.VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement) |
---|
1029 | { |
---|
1030 | if (variableDeclarationStatement.Variables.Count != 1) |
---|
1031 | return MakeSnippetStatement(variableDeclarationStatement); |
---|
1032 | VariableInitializer vi = variableDeclarationStatement.Variables.Single(); |
---|
1033 | return new CodeVariableDeclarationStatement( |
---|
1034 | Convert(variableDeclarationStatement.Type), |
---|
1035 | vi.Name, |
---|
1036 | ConvertVariableInitializer(vi.Initializer, variableDeclarationStatement.Type)); |
---|
1037 | } |
---|
1038 | |
---|
1039 | CodeExpression ConvertVariableInitializer(Expression expr, AstType type) |
---|
1040 | { |
---|
1041 | ArrayInitializerExpression aie = expr as ArrayInitializerExpression; |
---|
1042 | if (aie != null) { |
---|
1043 | return new CodeArrayCreateExpression(Convert(type), Convert(aie.Elements)); |
---|
1044 | } else { |
---|
1045 | return Convert(expr); |
---|
1046 | } |
---|
1047 | } |
---|
1048 | |
---|
1049 | CodeObject IAstVisitor<CodeObject>.VisitWhileStatement(WhileStatement whileStatement) |
---|
1050 | { |
---|
1051 | return new CodeIterationStatement(EmptyStatement(), Convert(whileStatement.Condition), EmptyStatement(), ConvertEmbeddedStatement(whileStatement.EmbeddedStatement)); |
---|
1052 | } |
---|
1053 | |
---|
1054 | CodeObject IAstVisitor<CodeObject>.VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement) |
---|
1055 | { |
---|
1056 | return MakeSnippetStatement(yieldBreakStatement); |
---|
1057 | } |
---|
1058 | |
---|
1059 | CodeObject IAstVisitor<CodeObject>.VisitYieldReturnStatement(YieldReturnStatement yieldStatement) |
---|
1060 | { |
---|
1061 | return MakeSnippetStatement(yieldStatement); |
---|
1062 | } |
---|
1063 | |
---|
1064 | CodeObject IAstVisitor<CodeObject>.VisitAccessor(Accessor accessor) |
---|
1065 | { |
---|
1066 | throw new NotSupportedException(); |
---|
1067 | } |
---|
1068 | |
---|
1069 | CodeObject IAstVisitor<CodeObject>.VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration) |
---|
1070 | { |
---|
1071 | CodeConstructor ctor = new CodeConstructor(); |
---|
1072 | ctor.Attributes = ConvertMemberAttributes(constructorDeclaration.Modifiers, SymbolKind.Constructor); |
---|
1073 | ctor.CustomAttributes.AddRange(Convert(constructorDeclaration.Attributes)); |
---|
1074 | if (constructorDeclaration.Initializer.ConstructorInitializerType == ConstructorInitializerType.This) { |
---|
1075 | ctor.ChainedConstructorArgs.AddRange(Convert(constructorDeclaration.Initializer.Arguments)); |
---|
1076 | } else { |
---|
1077 | ctor.BaseConstructorArgs.AddRange(Convert(constructorDeclaration.Initializer.Arguments)); |
---|
1078 | } |
---|
1079 | ctor.Parameters.AddRange(Convert(constructorDeclaration.Parameters)); |
---|
1080 | |
---|
1081 | ctor.Statements.AddRange(ConvertBlock(constructorDeclaration.Body)); |
---|
1082 | return ctor; |
---|
1083 | } |
---|
1084 | |
---|
1085 | CodeObject IAstVisitor<CodeObject>.VisitConstructorInitializer(ConstructorInitializer constructorInitializer) |
---|
1086 | { |
---|
1087 | throw new NotSupportedException(); |
---|
1088 | } |
---|
1089 | |
---|
1090 | CodeObject IAstVisitor<CodeObject>.VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration) |
---|
1091 | { |
---|
1092 | return new CodeSnippetTypeMember(MakeSnippet(destructorDeclaration)); |
---|
1093 | } |
---|
1094 | |
---|
1095 | CodeObject IAstVisitor<CodeObject>.VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration) |
---|
1096 | { |
---|
1097 | TypeDeclaration td = enumMemberDeclaration.Parent as TypeDeclaration; |
---|
1098 | CodeMemberField f = new CodeMemberField(td != null ? td.Name : "Enum", enumMemberDeclaration.Name); |
---|
1099 | f.Attributes = MemberAttributes.Public | MemberAttributes.Static; |
---|
1100 | f.CustomAttributes.AddRange(Convert(enumMemberDeclaration.Attributes)); |
---|
1101 | f.InitExpression = Convert(enumMemberDeclaration.Initializer); |
---|
1102 | return f; |
---|
1103 | } |
---|
1104 | |
---|
1105 | CodeObject IAstVisitor<CodeObject>.VisitEventDeclaration(EventDeclaration eventDeclaration) |
---|
1106 | { |
---|
1107 | foreach (VariableInitializer vi in eventDeclaration.Variables) { |
---|
1108 | if (!vi.Initializer.IsNull) { |
---|
1109 | AddTypeMember(new CodeSnippetTypeMember(MakeSnippet(eventDeclaration))); |
---|
1110 | continue; |
---|
1111 | } |
---|
1112 | |
---|
1113 | CodeMemberEvent e = new CodeMemberEvent(); |
---|
1114 | e.Attributes = ConvertMemberAttributes(eventDeclaration.Modifiers, SymbolKind.Event); |
---|
1115 | e.CustomAttributes.AddRange(Convert(eventDeclaration.Attributes)); |
---|
1116 | e.Name = vi.Name; |
---|
1117 | e.Type = Convert(eventDeclaration.ReturnType); |
---|
1118 | AddTypeMember(e); |
---|
1119 | } |
---|
1120 | return null; |
---|
1121 | } |
---|
1122 | |
---|
1123 | CodeObject IAstVisitor<CodeObject>.VisitCustomEventDeclaration(CustomEventDeclaration customEventDeclaration) |
---|
1124 | { |
---|
1125 | return new CodeSnippetTypeMember(MakeSnippet(customEventDeclaration)); |
---|
1126 | } |
---|
1127 | |
---|
1128 | CodeObject IAstVisitor<CodeObject>.VisitFieldDeclaration(FieldDeclaration fieldDeclaration) |
---|
1129 | { |
---|
1130 | foreach (VariableInitializer vi in fieldDeclaration.Variables) { |
---|
1131 | CodeMemberField f = new CodeMemberField(Convert(fieldDeclaration.ReturnType), vi.Name); |
---|
1132 | f.Attributes = ConvertMemberAttributes(fieldDeclaration.Modifiers, SymbolKind.Field); |
---|
1133 | f.CustomAttributes.AddRange(Convert(fieldDeclaration.Attributes)); |
---|
1134 | f.InitExpression = ConvertVariableInitializer(vi.Initializer, fieldDeclaration.ReturnType); |
---|
1135 | AddTypeMember(f); |
---|
1136 | } |
---|
1137 | return null; |
---|
1138 | } |
---|
1139 | |
---|
1140 | CodeObject IAstVisitor<CodeObject>.VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration) |
---|
1141 | { |
---|
1142 | CodeMemberProperty p = new CodeMemberProperty(); |
---|
1143 | p.Attributes = ConvertMemberAttributes(indexerDeclaration.Modifiers, SymbolKind.Indexer); |
---|
1144 | p.CustomAttributes.AddRange(Convert(indexerDeclaration.Attributes)); |
---|
1145 | p.Name = "Items"; |
---|
1146 | p.PrivateImplementationType = Convert(indexerDeclaration.PrivateImplementationType); |
---|
1147 | p.Parameters.AddRange(Convert(indexerDeclaration.Parameters)); |
---|
1148 | p.Type = Convert(indexerDeclaration.ReturnType); |
---|
1149 | |
---|
1150 | if (!indexerDeclaration.Getter.IsNull) { |
---|
1151 | p.HasGet = true; |
---|
1152 | p.GetStatements.AddRange(ConvertBlock(indexerDeclaration.Getter.Body)); |
---|
1153 | } |
---|
1154 | if (!indexerDeclaration.Setter.IsNull) { |
---|
1155 | p.HasSet = true; |
---|
1156 | p.SetStatements.AddRange(ConvertBlock(indexerDeclaration.Setter.Body)); |
---|
1157 | } |
---|
1158 | return p; |
---|
1159 | } |
---|
1160 | |
---|
1161 | CodeObject IAstVisitor<CodeObject>.VisitMethodDeclaration(MethodDeclaration methodDeclaration) |
---|
1162 | { |
---|
1163 | CodeMemberMethod m = new CodeMemberMethod(); |
---|
1164 | m.Attributes = ConvertMemberAttributes(methodDeclaration.Modifiers, SymbolKind.Method); |
---|
1165 | |
---|
1166 | m.CustomAttributes.AddRange(Convert(methodDeclaration.Attributes.Where(a => a.AttributeTarget != "return"))); |
---|
1167 | m.ReturnTypeCustomAttributes.AddRange(Convert(methodDeclaration.Attributes.Where(a => a.AttributeTarget == "return"))); |
---|
1168 | |
---|
1169 | m.ReturnType = Convert(methodDeclaration.ReturnType); |
---|
1170 | m.PrivateImplementationType = Convert(methodDeclaration.PrivateImplementationType); |
---|
1171 | m.Name = methodDeclaration.Name; |
---|
1172 | m.TypeParameters.AddRange(ConvertTypeParameters(methodDeclaration.TypeParameters, methodDeclaration.Constraints)); |
---|
1173 | m.Parameters.AddRange(Convert(methodDeclaration.Parameters)); |
---|
1174 | |
---|
1175 | m.Statements.AddRange(ConvertBlock(methodDeclaration.Body)); |
---|
1176 | return m; |
---|
1177 | } |
---|
1178 | |
---|
1179 | CodeObject IAstVisitor<CodeObject>.VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration) |
---|
1180 | { |
---|
1181 | CodeMemberMethod m = new CodeMemberMethod(); |
---|
1182 | m.Attributes = ConvertMemberAttributes(operatorDeclaration.Modifiers, SymbolKind.Method); |
---|
1183 | |
---|
1184 | m.CustomAttributes.AddRange(Convert(operatorDeclaration.Attributes.Where(a => a.AttributeTarget != "return"))); |
---|
1185 | m.ReturnTypeCustomAttributes.AddRange(Convert(operatorDeclaration.Attributes.Where(a => a.AttributeTarget == "return"))); |
---|
1186 | |
---|
1187 | m.ReturnType = Convert(operatorDeclaration.ReturnType); |
---|
1188 | m.Name = operatorDeclaration.Name; |
---|
1189 | m.Parameters.AddRange(Convert(operatorDeclaration.Parameters)); |
---|
1190 | |
---|
1191 | m.Statements.AddRange(ConvertBlock(operatorDeclaration.Body)); |
---|
1192 | return m; |
---|
1193 | } |
---|
1194 | |
---|
1195 | CodeObject IAstVisitor<CodeObject>.VisitParameterDeclaration(ParameterDeclaration parameterDeclaration) |
---|
1196 | { |
---|
1197 | var p = new CodeParameterDeclarationExpression(Convert(parameterDeclaration.Type), parameterDeclaration.Name); |
---|
1198 | p.CustomAttributes.AddRange(Convert(parameterDeclaration.Attributes)); |
---|
1199 | switch (parameterDeclaration.ParameterModifier) { |
---|
1200 | case ParameterModifier.Ref: |
---|
1201 | p.Direction = System.CodeDom.FieldDirection.Ref; |
---|
1202 | break; |
---|
1203 | case ParameterModifier.Out: |
---|
1204 | p.Direction = System.CodeDom.FieldDirection.Out; |
---|
1205 | break; |
---|
1206 | } |
---|
1207 | return p; |
---|
1208 | } |
---|
1209 | |
---|
1210 | CodeParameterDeclarationExpression[] Convert(IEnumerable<ParameterDeclaration> parameters) |
---|
1211 | { |
---|
1212 | List<CodeParameterDeclarationExpression> result = new List<CodeParameterDeclarationExpression>(); |
---|
1213 | foreach (ParameterDeclaration pd in parameters) { |
---|
1214 | CodeParameterDeclarationExpression pde = pd.AcceptVisitor(this) as CodeParameterDeclarationExpression; |
---|
1215 | if (pde != null) |
---|
1216 | result.Add(pde); |
---|
1217 | } |
---|
1218 | return result.ToArray(); |
---|
1219 | } |
---|
1220 | |
---|
1221 | CodeObject IAstVisitor<CodeObject>.VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration) |
---|
1222 | { |
---|
1223 | CodeMemberProperty p = new CodeMemberProperty(); |
---|
1224 | p.Attributes = ConvertMemberAttributes(propertyDeclaration.Modifiers, SymbolKind.Property); |
---|
1225 | p.CustomAttributes.AddRange(Convert(propertyDeclaration.Attributes)); |
---|
1226 | p.Name = propertyDeclaration.Name; |
---|
1227 | p.PrivateImplementationType = Convert(propertyDeclaration.PrivateImplementationType); |
---|
1228 | p.Type = Convert(propertyDeclaration.ReturnType); |
---|
1229 | |
---|
1230 | if (!propertyDeclaration.Getter.IsNull) { |
---|
1231 | p.HasGet = true; |
---|
1232 | p.GetStatements.AddRange(ConvertBlock(propertyDeclaration.Getter.Body)); |
---|
1233 | } |
---|
1234 | if (!propertyDeclaration.Setter.IsNull) { |
---|
1235 | p.HasSet = true; |
---|
1236 | p.SetStatements.AddRange(ConvertBlock(propertyDeclaration.Setter.Body)); |
---|
1237 | } |
---|
1238 | return p; |
---|
1239 | } |
---|
1240 | |
---|
1241 | CodeObject IAstVisitor<CodeObject>.VisitVariableInitializer(VariableInitializer variableInitializer) |
---|
1242 | { |
---|
1243 | throw new NotSupportedException(); // should be handled by the parent node |
---|
1244 | } |
---|
1245 | |
---|
1246 | CodeObject IAstVisitor<CodeObject>.VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration) |
---|
1247 | { |
---|
1248 | return new CodeSnippetTypeMember(MakeSnippet(fixedFieldDeclaration)); |
---|
1249 | } |
---|
1250 | |
---|
1251 | CodeObject IAstVisitor<CodeObject>.VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer) |
---|
1252 | { |
---|
1253 | throw new NotSupportedException(); // should be handled by the parent node |
---|
1254 | } |
---|
1255 | |
---|
1256 | CodeObject IAstVisitor<CodeObject>.VisitSyntaxTree(SyntaxTree syntaxTree) |
---|
1257 | { |
---|
1258 | CodeCompileUnit cu = new CodeCompileUnit(); |
---|
1259 | var globalImports = new List<CodeNamespaceImport> (); |
---|
1260 | foreach (AstNode node in syntaxTree.Children) { |
---|
1261 | CodeObject o = node.AcceptVisitor(this); |
---|
1262 | |
---|
1263 | CodeNamespace ns = o as CodeNamespace; |
---|
1264 | if (ns != null) { |
---|
1265 | cu.Namespaces.Add(ns); |
---|
1266 | } |
---|
1267 | CodeTypeDeclaration td = o as CodeTypeDeclaration; |
---|
1268 | if (td != null) { |
---|
1269 | cu.Namespaces.Add(new CodeNamespace() { Types = { td } }); |
---|
1270 | } |
---|
1271 | |
---|
1272 | var import = o as CodeNamespaceImport; |
---|
1273 | if (import != null) |
---|
1274 | globalImports.Add (import); |
---|
1275 | } |
---|
1276 | foreach (var gi in globalImports) { |
---|
1277 | for (int j = 0; j < cu.Namespaces.Count; j++) { |
---|
1278 | var cn = cu.Namespaces [j]; |
---|
1279 | bool found = cn.Imports |
---|
1280 | .Cast<CodeNamespaceImport> () |
---|
1281 | .Any (ns => ns.Namespace == gi.Namespace); |
---|
1282 | if (!found) |
---|
1283 | cn.Imports.Add (gi); |
---|
1284 | } |
---|
1285 | } |
---|
1286 | return cu; |
---|
1287 | } |
---|
1288 | |
---|
1289 | CodeObject IAstVisitor<CodeObject>.VisitSimpleType(SimpleType simpleType) |
---|
1290 | { |
---|
1291 | if (UseFullyQualifiedTypeNames) { |
---|
1292 | IType type = Resolve(simpleType).Type; |
---|
1293 | if (type.Kind != TypeKind.Unknown) |
---|
1294 | return Convert(type); |
---|
1295 | } |
---|
1296 | var tr = new CodeTypeReference(simpleType.Identifier); |
---|
1297 | tr.TypeArguments.AddRange(Convert(simpleType.TypeArguments)); |
---|
1298 | return tr; |
---|
1299 | } |
---|
1300 | |
---|
1301 | CodeObject IAstVisitor<CodeObject>.VisitMemberType(MemberType memberType) |
---|
1302 | { |
---|
1303 | if (memberType.IsDoubleColon && new SimpleType("global").IsMatch(memberType.Target)) { |
---|
1304 | var tr = new CodeTypeReference(memberType.MemberName, CodeTypeReferenceOptions.GlobalReference); |
---|
1305 | tr.TypeArguments.AddRange(Convert(memberType.TypeArguments)); |
---|
1306 | return tr; |
---|
1307 | } |
---|
1308 | if (UseFullyQualifiedTypeNames || memberType.IsDoubleColon) { |
---|
1309 | IType type = Resolve(memberType).Type; |
---|
1310 | if (type.Kind != TypeKind.Unknown) |
---|
1311 | return Convert(type); |
---|
1312 | } |
---|
1313 | CodeTypeReference target = Convert(memberType.Target); |
---|
1314 | if (target == null) |
---|
1315 | return null; |
---|
1316 | target.BaseType = target.BaseType + "." + memberType.MemberName; |
---|
1317 | target.TypeArguments.AddRange(Convert(memberType.TypeArguments)); |
---|
1318 | return target; |
---|
1319 | } |
---|
1320 | |
---|
1321 | CodeObject IAstVisitor<CodeObject>.VisitComposedType(ComposedType composedType) |
---|
1322 | { |
---|
1323 | CodeTypeReference typeRef = Convert(composedType.BaseType); |
---|
1324 | if (typeRef == null) |
---|
1325 | return null; |
---|
1326 | if (composedType.HasNullableSpecifier) { |
---|
1327 | typeRef = new CodeTypeReference("System.Nullable") { TypeArguments = { typeRef } }; |
---|
1328 | } |
---|
1329 | foreach (ArraySpecifier s in composedType.ArraySpecifiers.Reverse()) { |
---|
1330 | typeRef = new CodeTypeReference(typeRef, s.Dimensions); |
---|
1331 | } |
---|
1332 | return typeRef; |
---|
1333 | } |
---|
1334 | |
---|
1335 | CodeObject IAstVisitor<CodeObject>.VisitArraySpecifier(ArraySpecifier arraySpecifier) |
---|
1336 | { |
---|
1337 | throw new NotSupportedException(); // handled by parent node |
---|
1338 | } |
---|
1339 | |
---|
1340 | CodeObject IAstVisitor<CodeObject>.VisitPrimitiveType(PrimitiveType primitiveType) |
---|
1341 | { |
---|
1342 | KnownTypeCode typeCode = primitiveType.KnownTypeCode; |
---|
1343 | if (typeCode != KnownTypeCode.None) { |
---|
1344 | KnownTypeReference ktr = KnownTypeReference.Get(typeCode); |
---|
1345 | return new CodeTypeReference(ktr.Namespace + "." + ktr.Name); |
---|
1346 | } |
---|
1347 | return new CodeTypeReference(primitiveType.Keyword); |
---|
1348 | } |
---|
1349 | |
---|
1350 | CodeObject IAstVisitor<CodeObject>.VisitComment (Comment comment) |
---|
1351 | { |
---|
1352 | return new CodeComment (comment.Content, comment.CommentType == CommentType.Documentation); |
---|
1353 | } |
---|
1354 | |
---|
1355 | CodeObject IAstVisitor<CodeObject>.VisitNewLine(NewLineNode newLineNode) |
---|
1356 | { |
---|
1357 | return null; |
---|
1358 | } |
---|
1359 | |
---|
1360 | CodeObject IAstVisitor<CodeObject>.VisitWhitespace(WhitespaceNode whitespaceNode) |
---|
1361 | { |
---|
1362 | return null; |
---|
1363 | } |
---|
1364 | |
---|
1365 | CodeObject IAstVisitor<CodeObject>.VisitText(TextNode textNode) |
---|
1366 | { |
---|
1367 | throw new NotSupportedException(); |
---|
1368 | } |
---|
1369 | |
---|
1370 | CodeObject IAstVisitor<CodeObject>.VisitPreProcessorDirective (PreProcessorDirective preProcessorDirective) |
---|
1371 | { |
---|
1372 | return new CodeComment ("#" + preProcessorDirective.Type.ToString ().ToLowerInvariant ()); |
---|
1373 | } |
---|
1374 | |
---|
1375 | CodeObject IAstVisitor<CodeObject>.VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration) |
---|
1376 | { |
---|
1377 | throw new NotSupportedException(); // type parameters and constraints are handled together |
---|
1378 | } |
---|
1379 | |
---|
1380 | CodeObject IAstVisitor<CodeObject>.VisitConstraint(Constraint constraint) |
---|
1381 | { |
---|
1382 | throw new NotSupportedException(); |
---|
1383 | } |
---|
1384 | |
---|
1385 | CodeTypeParameter[] ConvertTypeParameters(IEnumerable<TypeParameterDeclaration> typeParameters, IEnumerable<Constraint> constraints) |
---|
1386 | { |
---|
1387 | List<CodeTypeParameter> result = new List<CodeTypeParameter>(); |
---|
1388 | foreach (TypeParameterDeclaration tpDecl in typeParameters) { |
---|
1389 | CodeTypeParameter tp = new CodeTypeParameter(tpDecl.Name); |
---|
1390 | tp.CustomAttributes.AddRange(Convert(tpDecl.Attributes)); |
---|
1391 | foreach (Constraint constraint in constraints) { |
---|
1392 | if (constraint.TypeParameter.Identifier == tp.Name) { |
---|
1393 | foreach (AstType baseType in constraint.BaseTypes) { |
---|
1394 | if (baseType is PrimitiveType && ((PrimitiveType)baseType).Keyword == "new") { |
---|
1395 | tp.HasConstructorConstraint = true; |
---|
1396 | } else { |
---|
1397 | CodeTypeReference tr = Convert(baseType); |
---|
1398 | if (tr != null) |
---|
1399 | tp.Constraints.Add(tr); |
---|
1400 | } |
---|
1401 | } |
---|
1402 | } |
---|
1403 | } |
---|
1404 | result.Add(tp); |
---|
1405 | } |
---|
1406 | return result.ToArray(); |
---|
1407 | } |
---|
1408 | |
---|
1409 | CodeObject IAstVisitor<CodeObject>.VisitCSharpTokenNode(CSharpTokenNode cSharpTokenNode) |
---|
1410 | { |
---|
1411 | return null; |
---|
1412 | } |
---|
1413 | |
---|
1414 | CodeObject IAstVisitor<CodeObject>.VisitIdentifier(Identifier identifier) |
---|
1415 | { |
---|
1416 | return null; |
---|
1417 | } |
---|
1418 | |
---|
1419 | CodeObject IAstVisitor<CodeObject>.VisitPatternPlaceholder(AstNode placeholder, Pattern pattern) |
---|
1420 | { |
---|
1421 | return null; |
---|
1422 | } |
---|
1423 | |
---|
1424 | CodeObject IAstVisitor<CodeObject>.VisitDocumentationReference(DocumentationReference documentationReference) |
---|
1425 | { |
---|
1426 | return null; |
---|
1427 | } |
---|
1428 | } |
---|
1429 | } |
---|