~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric-updates

« back to all changes in this revision

Viewing changes to src/core/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2009-02-18 08:40:51 UTC
  • mfrom: (1.2.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090218084051-gh8m6ukvokbwj7cf
Tags: 1.9.2+dfsg-1ubuntu1
* Merge from Debian Experimental (LP: #330519), remaining Ubuntu changes:
  + debian/control:
    - Update for Gnome# 2.24
    - Add libmono-cairo1.0-cil to build-deps to fool pkg-config check

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
//     <copyright see="prj:///doc/copyright.txt"/>
3
3
//     <license see="prj:///doc/license.txt"/>
4
4
//     <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
5
 
//     <version>$Revision: 2200 $</version>
 
5
//     <version>$Revision: 2819 $</version>
6
6
// </file>
7
7
 
8
8
using System;
17
17
        /// <summary>
18
18
        /// Converts special VB constructs to use more general AST classes.
19
19
        /// </summary>
20
 
        public class VBNetConstructsConvertVisitor : AbstractAstTransformer
 
20
        public class VBNetConstructsConvertVisitor : ConvertVisitorBase
21
21
        {
22
22
                // The following conversions are implemented:
23
23
                //   MyBase.New() and MyClass.New() calls inside the constructor are converted to :base() and :this()
27
27
                //   Built-in methods => Prefix with class name
28
28
                //   Function A() \n A = SomeValue \n End Function -> convert to return statement
29
29
                //   Array creation => add 1 to upper bound to get array length
 
30
                //   Comparison with empty string literal -> string.IsNullOrEmpty
 
31
                //   Add default value to local variable declarations without initializer
 
32
                
 
33
                /// <summary>
 
34
                /// Specifies whether the "Add default value to local variable declarations without initializer"
 
35
                /// operation is executed by this convert visitor.
 
36
                /// </summary>
 
37
                public bool AddDefaultValueInitializerToLocalVariableDeclarations = true;
30
38
                
31
39
                Dictionary<string, string> usings;
32
40
                List<UsingDeclaration> addedUsings;
100
108
                                if (se != null) {
101
109
                                        InvocationExpression ie = se.Expression as InvocationExpression;
102
110
                                        if (ie != null) {
103
 
                                                FieldReferenceExpression fre = ie.TargetObject as FieldReferenceExpression;
104
 
                                                if (fre != null && "New".Equals(fre.FieldName, StringComparison.InvariantCultureIgnoreCase)) {
 
111
                                                MemberReferenceExpression fre = ie.TargetObject as MemberReferenceExpression;
 
112
                                                if (fre != null && "New".Equals(fre.MemberName, StringComparison.InvariantCultureIgnoreCase)) {
105
113
                                                        if (fre.TargetObject is BaseReferenceExpression || fre.TargetObject is ClassReferenceExpression || fre.TargetObject is ThisReferenceExpression) {
106
114
                                                                body.Children.RemoveAt(0);
107
115
                                                                ConstructorInitializer ci = new ConstructorInitializer();
127
135
                                base.VisitUsingDeclaration(@using, data);
128
136
                        }
129
137
                        
130
 
                        MethodDeclaration method = new MethodDeclaration(declareDeclaration.Name, declareDeclaration.Modifier,
131
 
                                                                         declareDeclaration.TypeReference, declareDeclaration.Parameters,
132
 
                                                                         declareDeclaration.Attributes);
 
138
                        MethodDeclaration method = new MethodDeclaration {
 
139
                                Name = declareDeclaration.Name,
 
140
                                Modifier = declareDeclaration.Modifier,
 
141
                                TypeReference = declareDeclaration.TypeReference,
 
142
                                Parameters = declareDeclaration.Parameters,
 
143
                                Attributes = declareDeclaration.Attributes
 
144
                        };
 
145
                        
133
146
                        if ((method.Modifier & Modifiers.Visibility) == 0)
134
147
                                method.Modifier |= Modifiers.Public;
135
148
                        method.Modifier |= Modifiers.Extern | Modifiers.Static;
146
159
                        switch (declareDeclaration.Charset) {
147
160
                                case CharsetModifier.Auto:
148
161
                                        att.NamedArguments.Add(new NamedArgumentExpression("CharSet",
149
 
                                                                                           new FieldReferenceExpression(new IdentifierExpression("CharSet"),
150
 
                                                                                                                        "Auto")));
 
162
                                                                                           new MemberReferenceExpression(new IdentifierExpression("CharSet"),
 
163
                                                                                                                         "Auto")));
151
164
                                        break;
152
165
                                case CharsetModifier.Unicode:
153
166
                                        att.NamedArguments.Add(new NamedArgumentExpression("CharSet",
154
 
                                                                                           new FieldReferenceExpression(new IdentifierExpression("CharSet"),
155
 
                                                                                                                        "Unicode")));
 
167
                                                                                           new MemberReferenceExpression(new IdentifierExpression("CharSet"),
 
168
                                                                                                                         "Unicode")));
156
169
                                        break;
157
170
                                default:
158
171
                                        att.NamedArguments.Add(new NamedArgumentExpression("CharSet",
159
 
                                                                                           new FieldReferenceExpression(new IdentifierExpression("CharSet"),
160
 
                                                                                                                        "Ansi")));
 
172
                                                                                           new MemberReferenceExpression(new IdentifierExpression("CharSet"),
 
173
                                                                                                                         "Ansi")));
161
174
                                        break;
162
175
                        }
163
176
                        att.NamedArguments.Add(new NamedArgumentExpression("SetLastError", new PrimitiveExpression(true, true.ToString())));
164
177
                        att.NamedArguments.Add(new NamedArgumentExpression("ExactSpelling", new PrimitiveExpression(true, true.ToString())));
165
 
                        AttributeSection sec = new AttributeSection(null, null);
166
 
                        sec.Attributes.Add(att);
167
 
                        method.Attributes.Add(sec);
 
178
                        method.Attributes.Add(new AttributeSection { Attributes = { att } });
168
179
                        ReplaceCurrentNode(method);
169
180
                        return base.VisitMethodDeclaration(method, data);
170
181
                }
196
207
                                                InvocationExpression ie = se.Expression as InvocationExpression;
197
208
                                                if (ie != null
198
209
                                                    && ie.Arguments.Count == 0
199
 
                                                    && ie.TargetObject is FieldReferenceExpression
200
 
                                                    && (ie.TargetObject as FieldReferenceExpression).TargetObject is BaseReferenceExpression
201
 
                                                    && "Finalize".Equals((ie.TargetObject as FieldReferenceExpression).FieldName, StringComparison.InvariantCultureIgnoreCase))
 
210
                                                    && ie.TargetObject is MemberReferenceExpression
 
211
                                                    && (ie.TargetObject as MemberReferenceExpression).TargetObject is BaseReferenceExpression
 
212
                                                    && "Finalize".Equals((ie.TargetObject as MemberReferenceExpression).MemberName, StringComparison.InvariantCultureIgnoreCase))
202
213
                                                {
203
214
                                                        DestructorDeclaration des = new DestructorDeclaration("Destructor", Modifiers.None, methodDeclaration.Attributes);
204
215
                                                        ReplaceCurrentNode(des);
233
244
                                        methodDeclaration.Body.AcceptVisitor(visitor, null);
234
245
                                        if (visitor.replacementCount > 0) {
235
246
                                                Expression init;
236
 
                                                switch (methodDeclaration.TypeReference.SystemType) {
237
 
                                                        case "System.Int16":
238
 
                                                        case "System.Int32":
239
 
                                                        case "System.Int64":
240
 
                                                        case "System.Byte":
241
 
                                                        case "System.UInt16":
242
 
                                                        case "System.UInt32":
243
 
                                                        case "System.UInt64":
244
 
                                                                init = new PrimitiveExpression(0, "0");
245
 
                                                                break;
246
 
                                                        case "System.Boolean":
247
 
                                                                init = new PrimitiveExpression(false, "false");
248
 
                                                                break;
249
 
                                                        default:
250
 
                                                                init = new PrimitiveExpression(null, "null");
251
 
                                                                break;
252
 
                                                }
 
247
                                                init = GetDefaultValueForType(methodDeclaration.TypeReference);
253
248
                                                methodDeclaration.Body.Children.Insert(0, new LocalVariableDeclaration(new VariableDeclaration(FunctionReturnValueName, init, methodDeclaration.TypeReference)));
254
249
                                                methodDeclaration.Body.Children[0].Parent = methodDeclaration.Body;
255
250
                                                methodDeclaration.Body.AddChild(new ReturnStatement(new IdentifierExpression(FunctionReturnValueName)));
332
327
                                        from = p.ParameterName;
333
328
                                        p.ParameterName = "Value";
334
329
                                }
335
 
                                propertyDeclaration.SetRegion.AcceptVisitor(new RenameIdentifierVisitor(from, "value"), null);
 
330
                                propertyDeclaration.SetRegion.AcceptVisitor(new RenameIdentifierVisitor(from, "value", StringComparer.InvariantCultureIgnoreCase), null);
336
331
                        }
337
332
                        
338
333
                        return base.VisitPropertyDeclaration(propertyDeclaration, data);
339
334
                }
340
335
                
341
 
                class RenameIdentifierVisitor : AbstractAstVisitor
342
 
                {
343
 
                        string from, to;
344
 
                        
345
 
                        public RenameIdentifierVisitor(string from, string to)
346
 
                        {
347
 
                                this.from = from;
348
 
                                this.to = to;
349
 
                        }
350
 
                        
351
 
                        public override object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data)
352
 
                        {
353
 
                                if (string.Equals(identifierExpression.Identifier, from, StringComparison.InvariantCultureIgnoreCase)) {
354
 
                                        identifierExpression.Identifier = to;
355
 
                                }
356
 
                                return base.VisitIdentifierExpression(identifierExpression, data);
357
 
                        }
358
 
                }
359
 
                
360
336
                static volatile Dictionary<string, Expression> constantTable;
361
337
                static volatile Dictionary<string, Expression> methodTable;
362
338
                
386
362
                        }
387
363
                        Expression expr;
388
364
                        if (constantTable.TryGetValue(identifierExpression.Identifier, out expr)) {
389
 
                                FieldReferenceExpression fre = new FieldReferenceExpression(expr, identifierExpression.Identifier);
 
365
                                MemberReferenceExpression fre = new MemberReferenceExpression(expr, identifierExpression.Identifier);
390
366
                                ReplaceCurrentNode(fre);
391
 
                                return base.VisitFieldReferenceExpression(fre, data);
 
367
                                return base.VisitMemberReferenceExpression(fre, data);
392
368
                        }
393
369
                        return base.VisitIdentifierExpression(identifierExpression, data);
394
370
                }
421
397
                                }
422
398
                                Expression expr;
423
399
                                if (methodTable.TryGetValue(ident.Identifier, out expr)) {
424
 
                                        FieldReferenceExpression fre = new FieldReferenceExpression(expr, ident.Identifier);
 
400
                                        MemberReferenceExpression fre = new MemberReferenceExpression(expr, ident.Identifier);
425
401
                                        invocationExpression.TargetObject = fre;
426
402
                                }
427
403
                        }
473
449
                        }
474
450
                        return base.VisitArrayCreateExpression(arrayCreateExpression, data);
475
451
                }
 
452
                
 
453
                bool IsEmptyStringLiteral(Expression expression)
 
454
                {
 
455
                        PrimitiveExpression pe = expression as PrimitiveExpression;
 
456
                        if (pe != null) {
 
457
                                return (pe.Value as string) == "";
 
458
                        } else {
 
459
                                return false;
 
460
                        }
 
461
                }
 
462
                
 
463
                Expression CallStringIsNullOrEmpty(Expression stringVariable)
 
464
                {
 
465
                        List<Expression> arguments = new List<Expression>();
 
466
                        arguments.Add(stringVariable);
 
467
                        return new InvocationExpression(
 
468
                                new MemberReferenceExpression(new TypeReferenceExpression("System.String"), "IsNullOrEmpty"),
 
469
                                arguments);
 
470
                }
 
471
                
 
472
                public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
 
473
                {
 
474
                        base.VisitBinaryOperatorExpression(binaryOperatorExpression, data);
 
475
                        if (IsEmptyStringLiteral(binaryOperatorExpression.Right)) {
 
476
                                if (binaryOperatorExpression.Op == BinaryOperatorType.Equality) {
 
477
                                        ReplaceCurrentNode(CallStringIsNullOrEmpty(binaryOperatorExpression.Left));
 
478
                                } else if (binaryOperatorExpression.Op == BinaryOperatorType.InEquality) {
 
479
                                        ReplaceCurrentNode(new UnaryOperatorExpression(CallStringIsNullOrEmpty(binaryOperatorExpression.Left),
 
480
                                                                                       UnaryOperatorType.Not));
 
481
                                }
 
482
                        } else if (IsEmptyStringLiteral(binaryOperatorExpression.Left)) {
 
483
                                if (binaryOperatorExpression.Op == BinaryOperatorType.Equality) {
 
484
                                        ReplaceCurrentNode(CallStringIsNullOrEmpty(binaryOperatorExpression.Right));
 
485
                                } else if (binaryOperatorExpression.Op == BinaryOperatorType.InEquality) {
 
486
                                        ReplaceCurrentNode(new UnaryOperatorExpression(CallStringIsNullOrEmpty(binaryOperatorExpression.Right),
 
487
                                                                                       UnaryOperatorType.Not));
 
488
                                }
 
489
                        }
 
490
                        return null;
 
491
                }
 
492
                
 
493
                public override object VisitLocalVariableDeclaration(LocalVariableDeclaration localVariableDeclaration, object data)
 
494
                {
 
495
                        if (AddDefaultValueInitializerToLocalVariableDeclarations) {
 
496
                                for (int i = 0; i < localVariableDeclaration.Variables.Count; i++) {
 
497
                                        VariableDeclaration decl = localVariableDeclaration.Variables[i];
 
498
                                        if (decl.FixedArrayInitialization.IsNull && decl.Initializer.IsNull) {
 
499
                                                TypeReference type = localVariableDeclaration.GetTypeForVariable(i);
 
500
                                                decl.Initializer = GetDefaultValueForType(type);
 
501
                                        }
 
502
                                }
 
503
                        }
 
504
                        return base.VisitLocalVariableDeclaration(localVariableDeclaration, data);
 
505
                }
 
506
                
 
507
                Expression GetDefaultValueForType(TypeReference type)
 
508
                {
 
509
                        if (type != null && !type.IsArrayType) {
 
510
                                switch (type.SystemType) {
 
511
                                        case "System.SByte":
 
512
                                        case "System.Byte":
 
513
                                        case "System.Int16":
 
514
                                        case "System.UInt16":
 
515
                                        case "System.Int32":
 
516
                                        case "System.UInt32":
 
517
                                        case "System.Int64":
 
518
                                        case "System.UInt64":
 
519
                                        case "System.Single":
 
520
                                        case "System.Double":
 
521
                                                return new PrimitiveExpression(0, "0");
 
522
                                        case "System.Char":
 
523
                                                return new PrimitiveExpression('\0', "'\\0'");
 
524
                                        case "System.Object":
 
525
                                        case "System.String":
 
526
                                                return new PrimitiveExpression(null, "null");
 
527
                                        case "System.Boolean":
 
528
                                                return new PrimitiveExpression(false, "false");
 
529
                                        default:
 
530
                                                return new DefaultValueExpression(type);
 
531
                                }
 
532
                        } else {
 
533
                                return new PrimitiveExpression(null, "null");
 
534
                        }
 
535
                }
476
536
        }
477
537
}