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

« back to all changes in this revision

Viewing changes to src/core/MonoDevelop.Projects/MonoDevelop.Projects.CodeGeneration/BaseRefactorer.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:
30
30
using System.IO;
31
31
using System.CodeDom;
32
32
using System.CodeDom.Compiler;
 
33
using System.Collections.Generic;
 
34
using System.Linq;
33
35
using Microsoft.CSharp;
34
36
 
35
 
using MonoDevelop.Projects.Parser;
 
37
using MonoDevelop.Projects.Dom;
 
38
using MonoDevelop.Projects.Dom.Parser;
36
39
using MonoDevelop.Projects.Text;
37
40
using MonoDevelop.Projects.CodeGeneration;
38
41
 
41
44
        public abstract class BaseRefactorer: IRefactorer
42
45
        {
43
46
                public virtual RefactorOperations SupportedOperations {
44
 
                        get { return RefactorOperations.All; }
 
47
                        get { return RefactorOperations.All ^ RefactorOperations.AddFoldingRegion; }
45
48
                }
46
49
                
47
50
                protected abstract CodeDomProvider GetCodeDomProvider ();
48
51
                
49
 
                public IClass CreateClass (RefactorerContext ctx, string directory, string namspace, CodeTypeDeclaration type)
 
52
                public virtual void AddAttribute (RefactorerContext ctx, IType cls, CodeAttributeDeclaration attr)
 
53
                {
 
54
                        IEditableTextFile buffer = ctx.GetFile (cls.CompilationUnit.FileName);
 
55
 
 
56
                        CodeTypeDeclaration type = new CodeTypeDeclaration ("temp");
 
57
                        type.CustomAttributes.Add (attr);
 
58
                        CodeDomProvider provider = GetCodeDomProvider ();
 
59
                        StringWriter sw = new StringWriter ();
 
60
                        provider.GenerateCodeFromType (type, sw, GetOptions (false));
 
61
                        string code = sw.ToString ();
 
62
                        int start = code.IndexOf ('[');
 
63
                        int end = code.LastIndexOf (']');
 
64
                        code = code.Substring (start, end-start+1) + Environment.NewLine;
 
65
 
 
66
                        int line = cls.Location.Line;
 
67
                        int col = cls.Location.Column;
 
68
                        int pos = buffer.GetPositionFromLineColumn (line, col);
 
69
 
 
70
                        code = Indent (code, GetLineIndent (buffer, line), false);
 
71
                        buffer.InsertText (pos, code);
 
72
                }
 
73
 
 
74
                public IType CreateClass (RefactorerContext ctx, string directory, string namspace, CodeTypeDeclaration type)
50
75
                {
51
76
                        CodeCompileUnit unit = new CodeCompileUnit ();
52
77
                        CodeNamespace ns = new CodeNamespace (namspace);
61
86
                        
62
87
                        sw.Close ();
63
88
                        
64
 
                        IParseInformation pi = ctx.ParserContext.ParseFile (file);
65
 
                        ClassCollection clss = ((ICompilationUnit)pi.BestCompilationUnit).Classes;
 
89
                        
 
90
                        ICompilationUnit pi = ProjectDomService.Parse (ctx.ParserContext.Project, file, null).CompilationUnit;
 
91
                        IList<IType> clss = pi.Types;
66
92
                        if (clss.Count > 0)
67
93
                                return clss [0];
68
94
                        else
69
95
                                throw new Exception ("Class creation failed. The parser did not find the created class.");
70
96
                }
71
97
                
72
 
                public virtual IClass RenameClass (RefactorerContext ctx, IClass cls, string newName)
73
 
                {
74
 
                        return null;
75
 
                }
76
 
                
77
 
                public virtual MemberReferenceCollection FindClassReferences (RefactorerContext ctx, string file, IClass cls)
78
 
                {
79
 
                        return null;
80
 
                }
81
 
                
82
 
                public virtual IMember AddMember (RefactorerContext ctx, IClass cls, CodeTypeMember member)
83
 
                {
84
 
                        IEditableTextFile buffer = ctx.GetFile (cls.Region.FileName);
 
98
                public virtual IType RenameClass (RefactorerContext ctx, IType cls, string newName)
 
99
                {
 
100
                        return null;
 
101
                }
 
102
                
 
103
                public virtual IEnumerable<MemberReference> FindClassReferences (RefactorerContext ctx, string file, IType cls)
 
104
                {
 
105
                        return null;
 
106
                }
 
107
                
 
108
                public virtual IMember AddMember (RefactorerContext ctx, IType cls, CodeTypeMember member)
 
109
                {
 
110
                        IEditableTextFile buffer = ctx.GetFile (cls.CompilationUnit.FileName);
85
111
                        
86
112
                        int pos = GetNewMemberPosition (buffer, cls, member);
87
113
                        
97
123
                        
98
124
                        return FindGeneratedMember (ctx, buffer, cls, member, line);
99
125
                }
 
126
                
 
127
                public virtual void AddMembers (RefactorerContext ctx, IType cls, IEnumerable<CodeTypeMember> members)
 
128
                {
 
129
                        foreach (CodeTypeMember member in members)
 
130
                                AddMember (ctx, cls, member);
 
131
                }
 
132
                
 
133
                public virtual void AddMembers (RefactorerContext ctx, IType cls, 
 
134
                                                                IEnumerable<CodeTypeMember> members, string foldingRegionName)
 
135
                {
 
136
                        //no region name, so distribute them with like members
 
137
                        if (string.IsNullOrEmpty (foldingRegionName)) {
 
138
                                AddMembers (ctx, cls, members);
 
139
                                return;
 
140
                        }
 
141
                        
 
142
                        if (!members.Any ())
 
143
                                return;
 
144
                        
 
145
                        IEditableTextFile buffer = ctx.GetFile (cls.CompilationUnit.FileName);
 
146
                        int pos;
 
147
                        
 
148
                        // create/find the folding region, or if creation of regions isn't supported, put all the added
 
149
                        // members in one place anyway
 
150
                        if ((SupportedOperations & RefactorOperations.AddFoldingRegion) == 0) {
 
151
                                pos = GetNewMethodPosition (buffer, cls);
 
152
                        } else {
 
153
                                pos = AddFoldingRegion (ctx, cls, foldingRegionName);
 
154
                        }
 
155
                        
 
156
                        AddMembersAtPosition (ctx, cls, members, buffer, pos);
 
157
                }
 
158
                
 
159
                protected void AddMembersAtPosition (RefactorerContext ctx, IType cls, IEnumerable<CodeTypeMember> members, 
 
160
                                                     IEditableTextFile buffer, int pos)
 
161
                {
 
162
                        int line, col;
 
163
                        buffer.GetLineColumnFromPosition (pos, out line, out col);
 
164
                        
 
165
                        string indent = GetLineIndent (buffer, line);
 
166
                        List<int> positions = new List<int> ();
 
167
                        
 
168
                        bool first = true;
 
169
                        foreach (CodeTypeMember member in members) {
 
170
                                positions.Add (pos);
 
171
                                string code = GenerateCodeFromMember (member);
 
172
                                        //spacing between inserted members
 
173
                                if (first)
 
174
                                        first = false;
 
175
                                else
 
176
                                        code = "\n\n" + code;
 
177
                                
 
178
                                code = Indent (code, indent, false);
 
179
                                buffer.InsertText (pos, code);
 
180
                                pos += code.Length;
 
181
                        }
 
182
                }
 
183
                
 
184
                public virtual int AddFoldingRegion (RefactorerContext ctx, IType cls, string regionName)
 
185
                {
 
186
                        IEditableTextFile buffer = ctx.GetFile (cls.CompilationUnit.FileName);
 
187
                        return GetNewMethodPosition (buffer, cls);
 
188
                }
 
189
                
100
190
                /*
101
 
                IReturnType GetGenericArgument (IClass type, IReturnType rtype, IReturnType hintType)
 
191
                IReturnType GetGenericArgument (IType type, IReturnType rtype, IReturnType hintType)
102
192
                {
103
193
                        if (hintType != null && type != null && rtype != null && type.GenericParameters != null)  {
104
194
                                for (int i = 0; i < type.GenericParameters.Count; i++) {
105
 
                                        if (type.GenericParameters[i].Name == rtype.FullyQualifiedName) {
 
195
                                        if (type.GenericParameters[i].Name == rtype.FullName) {
106
196
                                                return hintType.GenericArguments[i];
107
197
                                        }
108
198
                                }
126
216
                        return false;
127
217
                }
128
218
                
129
 
                protected CodeTypeReference ReturnTypeToDom (RefactorerContext ctx, IReturnType declaredType)
 
219
                protected CodeTypeReference ReturnTypeToDom (RefactorerContext ctx, ICompilationUnit unit, IReturnType declaredType)
130
220
                {
131
221
                        CodeTypeReference [] argTypes = null;
132
222
                        IReturnType rtype = declaredType;
133
223
                        if (rtype == null)
134
224
                                return null;
135
 
                        ReturnTypeList genericArgs = rtype.GenericArguments;
 
225
                        IList<IReturnType> genericArgs = rtype.GenericArguments;
136
226
                        if (genericArgs != null && genericArgs.Count > 0) {
137
227
                                argTypes = new CodeTypeReference [genericArgs.Count];
138
228
                                for (int i = 0; i < genericArgs.Count; i++) {
139
 
                                        argTypes[i] = ReturnTypeToDom (ctx, genericArgs[i]);
 
229
                                        argTypes[i] = ReturnTypeToDom (ctx, unit, genericArgs[i]);
140
230
                                }
141
231
                        }
142
 
                        string name = IsBaseType (rtype.FullyQualifiedName) ? rtype.FullyQualifiedName : ctx.TypeNameResolver.ResolveName (rtype.FullyQualifiedName);
 
232
                        string name = IsBaseType (rtype.FullName) ? rtype.FullName : ctx.TypeNameResolver.ResolveName (rtype.FullName);
143
233
                        CodeTypeReference typeRef = argTypes != null ? new CodeTypeReference (name, argTypes) : new CodeTypeReference (name);
144
 
                        
145
 
                        if (rtype.ArrayCount == 0)
146
 
                                return typeRef;
147
 
                        int [] dim = rtype.ArrayDimensions;
148
 
                        for (int i = 0; i < dim.Length; i++)
149
 
                                typeRef = new CodeTypeReference (typeRef, dim[i]);
 
234
                        for (int i = 0; i < rtype.ArrayDimensions; i++) {
 
235
                                typeRef = new CodeTypeReference (typeRef, rtype.GetDimension (i) + 1);
 
236
                        }
150
237
                        return typeRef;
151
238
                }
152
239
                
154
241
                {
155
242
                        if (IsBaseType (type.FullName))
156
243
                                return new CodeTypeReference (type);
157
 
                        return new CodeTypeReference (ctx.TypeNameResolver.ResolveName (type.FullName));
158
 
                }
159
 
                
160
 
                public virtual IMember ImplementMember (RefactorerContext ctx, IClass cls, IMember member, IReturnType privateImplementationType)
 
244
// TODO:
 
245
//                      return new CodeTypeReference (ctx.TypeNameResolver.ResolveName (type.FullName));
 
246
                        return new CodeTypeReference (type.FullName);
 
247
                }
 
248
                
 
249
                public virtual IMember ImplementMember (RefactorerContext ctx, IType cls, IMember member, IReturnType privateImplementationType)
 
250
                {
 
251
                        CodeTypeMember m = CreateImplementation (ctx, cls, member, privateImplementationType);
 
252
                        return AddMember (ctx, cls, m);
 
253
                }
 
254
                
 
255
                public virtual void ImplementMembers (RefactorerContext ctx, IType cls, 
 
256
                                                                      IEnumerable<KeyValuePair<IMember,IReturnType>> members,
 
257
                                                                      string foldingRegionName)
 
258
                {
 
259
                        AddMembers (ctx, cls, YieldImpls (ctx, cls, members), foldingRegionName);
 
260
                }
 
261
                
 
262
                //FIXME: this is a workaround for not being able to use LINQ, i.e.
 
263
                // from mem in members select CreateImplementation (ctx, cls, mem.Key, mem.Value)
 
264
                IEnumerable<CodeTypeMember> YieldImpls (RefactorerContext ctx, IType cls, 
 
265
                                                        IEnumerable<KeyValuePair<IMember,IReturnType>> members)
 
266
                {
 
267
                        foreach (KeyValuePair<IMember,IReturnType> mem in members)
 
268
                                yield return CreateImplementation (ctx, cls, mem.Key, mem.Value);
 
269
                }
 
270
                
 
271
                protected CodeTypeMember CreateImplementation (RefactorerContext ctx, IType cls, IMember member, 
 
272
                                                               IReturnType privateImplementationType)
161
273
                {
162
274
                        CodeTypeMember m;
163
275
                        
 
276
                        bool is_interface_method = member.DeclaringType.ClassType == ClassType.Interface;
 
277
                        bool isIndexer = false;
164
278
                        if (member is IEvent) {
165
279
                                CodeMemberEvent mEvent = new CodeMemberEvent ();
166
 
                                m = (CodeTypeMember) mEvent;
167
 
                                mEvent.Type = ReturnTypeToDom (ctx, member.ReturnType);
 
280
                                m = mEvent;
 
281
                                mEvent.Type = ReturnTypeToDom (ctx, cls.CompilationUnit, member.ReturnType);
 
282
                                if (!is_interface_method)
 
283
                                        mEvent.Attributes = MemberAttributes.Override;
 
284
 
168
285
                                if (privateImplementationType != null)
169
 
                                        mEvent.PrivateImplementationType = ReturnTypeToDom (ctx, privateImplementationType);
 
286
                                        mEvent.PrivateImplementationType = ReturnTypeToDom (ctx, cls.CompilationUnit, privateImplementationType);
170
287
                        } else if (member is IMethod) {
171
288
                                CodeMemberMethod mMethod = new CodeMemberMethod ();
172
289
                                IMethod method = (IMethod) member;
173
 
                                m = (CodeMemberMethod) mMethod;
 
290
                                m = mMethod;
 
291
 
 
292
                                foreach (ITypeParameter param in method.TypeParameters)
 
293
                                        mMethod.TypeParameters.Add (param.Name);
 
294
 
 
295
                                if (!is_interface_method)
 
296
                                        mMethod.Attributes = MemberAttributes.Override;
174
297
                                
175
 
                                mMethod.ReturnType = ReturnTypeToDom (ctx, member.ReturnType);
176
 
                                CodeExpression nieReference = new CodeObjectCreateExpression (TypeToDom (ctx, typeof (NotImplementedException)));
177
 
                                CodeStatement throwExpression = new CodeThrowExceptionStatement (nieReference);
178
 
                                mMethod.Statements.Add (throwExpression);
 
298
                                mMethod.ReturnType = ReturnTypeToDom (ctx, cls.CompilationUnit, member.ReturnType);
 
299
                                if (member.IsAbstract || member.DeclaringType.ClassType == ClassType.Interface) {
 
300
                                        CodeExpression nieReference = new CodeObjectCreateExpression (TypeToDom (ctx, typeof (NotImplementedException)));
 
301
                                        CodeStatement throwExpression = new CodeThrowExceptionStatement (nieReference);
 
302
                                        mMethod.Statements.Add (throwExpression);
 
303
                                } else {
 
304
                                        List<CodeExpression> parameters = new List<CodeExpression> ();
 
305
                                        foreach (IParameter parameter in method.Parameters) {
 
306
                                                parameters.Add (new CodeVariableReferenceExpression (parameter.Name));
 
307
                                        }
 
308
                                        mMethod.Statements.Add (new CodeMethodInvokeExpression (new CodeBaseReferenceExpression (), member.Name, parameters.ToArray ()));
 
309
                                }
179
310
                                
180
311
                                foreach (IParameter param in method.Parameters) {
181
312
                                        CodeParameterDeclarationExpression par;
182
 
                                        par = new CodeParameterDeclarationExpression (ReturnTypeToDom (ctx, param.ReturnType), param.Name);
 
313
                                        par = new CodeParameterDeclarationExpression (ReturnTypeToDom (ctx, cls.CompilationUnit, param.ReturnType), param.Name);
 
314
                                        if (param.IsOut)
 
315
                                                par.Direction = FieldDirection.Out;
 
316
                                        else if (param.IsRef)
 
317
                                                par.Direction = FieldDirection.Ref;
 
318
                                        if (param.IsParams)
 
319
                                                par.CustomAttributes.Add (new CodeAttributeDeclaration ("System.ParamArrayAttribute"));
183
320
                                        mMethod.Parameters.Add (par);
184
321
                                }
185
322
                                if (privateImplementationType != null)
186
 
                                        mMethod.PrivateImplementationType = ReturnTypeToDom (ctx, privateImplementationType);
 
323
                                        mMethod.PrivateImplementationType = ReturnTypeToDom (ctx, cls.CompilationUnit, privateImplementationType);
187
324
                        } else if (member is IProperty) {
188
 
                                CodeMemberProperty mProperty = new CodeMemberProperty ();
189
325
                                IProperty property = (IProperty) member;
190
 
                                m = (CodeMemberProperty) mProperty;
191
 
                                
192
 
                                CodeExpression nieReference = new CodeObjectCreateExpression (TypeToDom (ctx, typeof (NotImplementedException)));
193
 
                                CodeStatement throwExpression = new CodeThrowExceptionStatement (nieReference);
194
 
                                mProperty.HasGet = property.CanGet;
195
 
                                mProperty.HasSet = property.CanSet;
196
 
                                if (property.CanGet)
197
 
                                        mProperty.GetStatements.Add (throwExpression);
198
 
                                if (property.CanSet)
199
 
                                        mProperty.SetStatements.Add (throwExpression);
200
 
                                
201
 
                                mProperty.Type = ReturnTypeToDom (ctx, member.ReturnType);
202
 
                                if (privateImplementationType != null)
203
 
                                        mProperty.PrivateImplementationType = ReturnTypeToDom (ctx, privateImplementationType);
204
 
                        } else if (member is IIndexer) {
205
 
                                CodeMemberProperty mProperty = new CodeMemberProperty ();
206
 
                                IIndexer property = (IIndexer) member;
207
 
                                m = (CodeMemberProperty) mProperty;
208
 
                                
209
 
                                CodeExpression nieReference = new CodeObjectCreateExpression (TypeToDom (ctx, typeof (NotImplementedException)));
210
 
                                CodeStatement throwExpression = new CodeThrowExceptionStatement (nieReference);
211
 
                                mProperty.HasGet = true;
212
 
                                mProperty.HasSet = true;
213
 
                                if (mProperty.HasGet)
214
 
                                        mProperty.GetStatements.Add (throwExpression);
215
 
                                if (mProperty.HasSet)
216
 
                                        mProperty.SetStatements.Add (throwExpression);
217
 
                                
218
 
                                foreach (IParameter param in property.Parameters) {
219
 
                                        CodeParameterDeclarationExpression par;
220
 
                                        par = new CodeParameterDeclarationExpression (ReturnTypeToDom (ctx, param.ReturnType), param.Name);
221
 
                                        mProperty.Parameters.Add (par);
 
326
                                if (!property.IsIndexer) {
 
327
                                        CodeMemberProperty mProperty = new CodeMemberProperty ();
 
328
                                        m = mProperty;
 
329
                                        if (!is_interface_method)
 
330
                                                mProperty.Attributes = MemberAttributes.Override;
 
331
                                
 
332
                                        CodeExpression nieReference = new CodeObjectCreateExpression (TypeToDom (ctx, typeof (NotImplementedException)));
 
333
                                        CodeStatement throwExpression = new CodeThrowExceptionStatement (nieReference);
 
334
                                        mProperty.HasGet = property.HasGet;
 
335
                                        mProperty.HasSet = property.HasSet;
 
336
                                        if (property.HasGet) {
 
337
                                                if (member.IsAbstract || member.DeclaringType.ClassType == ClassType.Interface) {
 
338
                                                        mProperty.GetStatements.Add (throwExpression);
 
339
                                                } else {
 
340
                                                        mProperty.GetStatements.Add (new CodeMethodReturnStatement (new CodePropertyReferenceExpression(new CodeBaseReferenceExpression(), property.Name)));
 
341
                                                }
 
342
                                        }
 
343
                                        if (property.HasSet) {
 
344
                                                if (member.IsAbstract || member.DeclaringType.ClassType == ClassType.Interface) {
 
345
                                                        mProperty.SetStatements.Add (throwExpression);
 
346
                                                } else {
 
347
                                                        mProperty.SetStatements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression(new CodeBaseReferenceExpression(), property.Name), new CodePropertySetValueReferenceExpression ()));
 
348
                                                }
 
349
                                        }
 
350
                                
 
351
                                        mProperty.Type = ReturnTypeToDom (ctx, cls.CompilationUnit, member.ReturnType);
 
352
                                        if (privateImplementationType != null)
 
353
                                                mProperty.PrivateImplementationType = ReturnTypeToDom (ctx, cls.CompilationUnit, privateImplementationType);
 
354
                                } else {
 
355
                                        isIndexer = true;
 
356
                                        CodeMemberProperty mProperty = new CodeMemberProperty ();
 
357
                                        m = mProperty;
 
358
                                        if (!is_interface_method)
 
359
                                                mProperty.Attributes = MemberAttributes.Override;
 
360
                                
 
361
                                        CodeExpression nieReference = new CodeObjectCreateExpression (TypeToDom (ctx, typeof (NotImplementedException)));
 
362
                                        CodeStatement throwExpression = new CodeThrowExceptionStatement (nieReference);
 
363
                                        mProperty.HasGet = property.HasGet;
 
364
                                        mProperty.HasSet = property.HasSet;
 
365
 
 
366
                                        List<CodeExpression> parameters = new List<CodeExpression> ();
 
367
                                        foreach (IParameter parameter in property.Parameters) {
 
368
                                                parameters.Add (new CodeVariableReferenceExpression (parameter.Name));
 
369
                                        }
 
370
 
 
371
                                        if (mProperty.HasGet) {
 
372
                                                if (member.IsAbstract || member.DeclaringType.ClassType == ClassType.Interface) {
 
373
                                                        mProperty.GetStatements.Add (throwExpression);
 
374
                                                } else {
 
375
                                                        mProperty.GetStatements.Add (new CodeMethodReturnStatement (new CodeIndexerExpression (new CodeBaseReferenceExpression(), parameters.ToArray ())));
 
376
                                                }
 
377
                                        }
 
378
                                        if (mProperty.HasSet) {
 
379
                                                if (member.IsAbstract || member.DeclaringType.ClassType == ClassType.Interface) {
 
380
                                                        mProperty.SetStatements.Add (throwExpression);
 
381
                                                } else {
 
382
                                                        mProperty.SetStatements.Add (new CodeAssignStatement (new CodeIndexerExpression (new CodeBaseReferenceExpression(), parameters.ToArray ()), new CodePropertySetValueReferenceExpression ()));
 
383
                                                }
 
384
                                        }
 
385
                                
 
386
                                        foreach (IParameter param in property.Parameters) {
 
387
                                                CodeParameterDeclarationExpression par;
 
388
                                                par = new CodeParameterDeclarationExpression (ReturnTypeToDom (ctx, cls.CompilationUnit, param.ReturnType), param.Name);
 
389
                                                mProperty.Parameters.Add (par);
 
390
                                        }
 
391
                                
 
392
                                        mProperty.Type = ReturnTypeToDom (ctx, cls.CompilationUnit, member.ReturnType);
 
393
                                        if (privateImplementationType != null)
 
394
                                                mProperty.PrivateImplementationType = ReturnTypeToDom (ctx, cls.CompilationUnit, privateImplementationType);
 
395
                                } 
 
396
                        } else {
 
397
                                return null;
 
398
                        }
 
399
                        m.Name = isIndexer ? "Item" : member.Name;
 
400
                        if ((m.Attributes & MemberAttributes.ScopeMask) != MemberAttributes.Override)
 
401
                                // Mark final if not overriding
 
402
                                m.Attributes = (m.Attributes & ~MemberAttributes.ScopeMask) | MemberAttributes.Final;
 
403
                        
 
404
                        if (member.DeclaringType != null && member.DeclaringType.ClassType == ClassType.Interface) {
 
405
                                m.Attributes = (m.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
 
406
                        } else {
 
407
                                if (member.IsPublic) {
 
408
                                        m.Attributes = (m.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
 
409
                                } else if (member.IsPrivate) {
 
410
                                        m.Attributes = (m.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Private;
 
411
                                } else if (member.IsProtectedOrInternal) {
 
412
                                        m.Attributes = (m.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.FamilyOrAssembly;
 
413
                                } else if (member.IsProtectedAndInternal) {
 
414
                                        m.Attributes = (m.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.FamilyOrAssembly;
 
415
                                } else if (member.IsInternal) {
 
416
                                        m.Attributes = (m.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Assembly;
 
417
                                } else if (member.IsProtected) {
 
418
                                        m.Attributes = (m.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Family;
222
419
                                }
223
 
                                
224
 
                                mProperty.Type = ReturnTypeToDom (ctx, member.ReturnType);
225
 
                                if (privateImplementationType != null)
226
 
                                        mProperty.PrivateImplementationType = ReturnTypeToDom (ctx, privateImplementationType);
227
 
                        } else {
228
 
                                return null;
229
420
                        }
230
 
                        
231
 
                        if (member is IIndexer)
232
 
                                m.Name = "Item";
233
 
                        else
234
 
                                m.Name = member.Name;
235
 
                        
236
 
                        m.Attributes = MemberAttributes.Final;
237
 
                        
238
 
                        if (privateImplementationType == null)
239
 
                                m.Attributes |= MemberAttributes.Public;
240
 
                        
241
 
                        return AddMember (ctx, cls, m);
 
421
                        return m;
242
422
                }
243
423
                
244
 
                public virtual void RemoveMember (RefactorerContext ctx, IClass cls, IMember member)
 
424
                public virtual void RemoveMember (RefactorerContext ctx, IType cls, IMember member)
245
425
                {
246
426
                        IEditableTextFile buffer = null;
247
427
                        int pos = -1;
248
 
                        
249
 
                        for (int i = 0; i < cls.Parts.Length; i++) {
250
 
                                if ((buffer = ctx.GetFile (cls.Parts[i].Region.FileName)) == null)
 
428
                        foreach (IType part in cls.Parts) {
 
429
                                if ((buffer = ctx.GetFile (part.CompilationUnit.FileName)) == null)
251
430
                                        continue;
252
431
                                
253
432
                                if ((pos = GetMemberNamePosition (buffer, member)) != -1)
257
436
                        if (pos == -1)
258
437
                                return;
259
438
                        
260
 
                        IRegion reg = GetMemberBounds (buffer, member);
261
 
                        int sp = buffer.GetPositionFromLineColumn (reg.BeginLine, reg.BeginColumn);
262
 
                        int ep = buffer.GetPositionFromLineColumn (reg.EndLine, reg.EndColumn);
 
439
                        DomRegion reg = GetMemberBounds (buffer, member);
 
440
                        int sp = buffer.GetPositionFromLineColumn (reg.Start.Line, reg.Start.Column);
 
441
                        int ep = buffer.GetPositionFromLineColumn (reg.End.Line, reg.End.Column);
263
442
                        buffer.DeleteText (sp, ep - sp);
264
443
                }
265
444
                
266
 
                public virtual IMember ReplaceMember (RefactorerContext ctx, IClass cls, IMember oldMember, CodeTypeMember memberInfo)
 
445
                public virtual IMember ReplaceMember (RefactorerContext ctx, IType cls, IMember oldMember, CodeTypeMember memberInfo)
267
446
                {
268
447
                        IEditableTextFile buffer = null;
269
448
                        int pos = -1;
270
449
                        
271
 
                        for (int i = 0; i < cls.Parts.Length; i++) {
272
 
                                if ((buffer = ctx.GetFile (cls.Parts[i].Region.FileName)) == null)
 
450
                        foreach (IType part in cls.Parts) {
 
451
                                if ((buffer = ctx.GetFile (part.CompilationUnit.FileName)) == null)
273
452
                                        continue;
274
453
                                
275
454
                                if ((pos = GetMemberNamePosition (buffer, oldMember)) != -1)
279
458
                        if (pos == -1)
280
459
                                return null;
281
460
                        
282
 
                        IRegion reg = GetMemberBounds (buffer, oldMember);
283
 
                        int sp = buffer.GetPositionFromLineColumn (reg.BeginLine, reg.BeginColumn);
284
 
                        int ep = buffer.GetPositionFromLineColumn (reg.EndLine, reg.EndColumn);
 
461
                        DomRegion reg = GetMemberBounds (buffer, oldMember);
 
462
                        int sp = buffer.GetPositionFromLineColumn (reg.Start.Line, reg.Start.Column);
 
463
                        int ep = buffer.GetPositionFromLineColumn (reg.End.Line, reg.End.Column);
285
464
                        buffer.DeleteText (sp, ep - sp);
286
465
                        
287
466
                        string code = GenerateCodeFromMember (memberInfo);
288
 
                        string indent = GetLineIndent (buffer, reg.BeginLine);
 
467
                        string indent = GetLineIndent (buffer, reg.Start.Line);
289
468
                        code = Indent (code, indent, false);
290
469
                        
291
470
                        buffer.InsertText (sp, code);
292
471
                        
293
 
                        return FindGeneratedMember (ctx, buffer, cls, memberInfo, reg.BeginLine);
 
472
                        return FindGeneratedMember (ctx, buffer, cls, memberInfo, reg.Start.Line);
294
473
                }
295
474
 
296
475
                public virtual string ConvertToLanguageTypeName (string netTypeName)
298
477
                        return netTypeName;
299
478
                }
300
479
                
301
 
                public virtual IMember RenameMember (RefactorerContext ctx, IClass cls, IMember member, string newName)
 
480
                public virtual IMember RenameMember (RefactorerContext ctx, IType cls, IMember member, string newName)
302
481
                {
303
482
                        IEditableTextFile file = null;
304
483
                        int pos = -1;
305
484
                        
306
 
                        for (int i = 0; i < cls.Parts.Length; i++) {
307
 
                                if ((file = ctx.GetFile (cls.Parts[i].Region.FileName)) == null)
 
485
                        foreach (IType part in cls.Parts) {
 
486
                                if ((file = ctx.GetFile (part.CompilationUnit.FileName)) == null)
308
487
                                        continue;
309
488
                                
310
489
                                if ((pos = GetMemberNamePosition (file, member)) != -1)
340
519
                                return null;
341
520
                        
342
521
                        memberInfo.Name = newName;
343
 
                        return FindGeneratedMember (ctx, file, cls, memberInfo, member.Region.BeginLine);
 
522
                        return FindGeneratedMember (ctx, file, cls, memberInfo, member.Location.Line);
344
523
                }
345
524
                
346
 
                public virtual MemberReferenceCollection FindMemberReferences (RefactorerContext ctx, string fileName, IClass cls, IMember member)
 
525
                public virtual IEnumerable<MemberReference> FindMemberReferences (RefactorerContext ctx, string fileName, IType cls, IMember member)
347
526
                {
348
527
                        if (member is IField)
349
528
                                return FindFieldReferences (ctx, fileName, cls, (IField) member);
362
541
                ///
363
542
                /// Override this method for each language to fill-in the Get/SetStatements
364
543
                ///
365
 
                protected virtual void EncapsulateFieldImpGetSet (RefactorerContext ctx, IClass cls, IField field, CodeMemberProperty  prop)
 
544
                protected virtual void EncapsulateFieldImpGetSet (RefactorerContext ctx, IType cls, IField field, CodeMemberProperty  prop)
366
545
                {
367
546
                        
368
547
                }
369
548
                
370
 
                public virtual IMember EncapsulateField (RefactorerContext ctx, IClass cls, IField field, string propName)
 
549
                public virtual IMember EncapsulateField (RefactorerContext ctx, IType cls, IField field, string propName, MemberAttributes attr, bool generateSetter)
371
550
                {
372
551
                        // If the field isn't already private/protected/internal, we'll need to fix it to be
373
 
                        if (true || field.IsPublic || (!field.IsPrivate && !field.IsProtectedOrInternal)) {
 
552
                        if (field.IsPublic || (!field.IsPrivate && !field.IsProtectedOrInternal) || true) {
374
553
                                IEditableTextFile file = null;
375
554
                                int pos = -1;
376
555
                                
377
556
                                // Find the file the field is contained in
378
 
                                for (int i = 0; i < cls.Parts.Length; i++) {
379
 
                                        if ((file = ctx.GetFile (cls.Parts[i].Region.FileName)) == null)
 
557
                                foreach (IType part in cls.Parts) {
 
558
                                        if ((file = ctx.GetFile (part.CompilationUnit.FileName)) == null)
380
559
                                                continue;
381
560
                                        
382
561
                                        if ((pos = GetMemberNamePosition (file, field)) != -1)
394
573
//                                      RemoveMember (ctx, cls, field);
395
574
//                                      AddMember (ctx, cls, fieldInfo);
396
575
                                        
397
 
                                        //int begin = file.GetPositionFromLineColumn (field.Region.BeginLine, field.Region.BeginColumn);
398
 
                                        //int end = file.GetPositionFromLineColumn (field.Region.EndLine, field.Region.EndColumn);
 
576
                                        //int begin = file.GetPositionFromLineColumn (field.Region.Start.Line, field.Region.Start.Column);
 
577
                                        //int end = file.GetPositionFromLineColumn (field.Region.End.Line, field.Region.End.Column);
399
578
                                        //
400
579
                                        //string snippet = file.GetText (begin, end);
401
580
                                        //
402
581
                                        //Console.WriteLine ("field declaration: {0}", snippet);
403
582
                                        //
404
 
                                        //IRegion region = GetMemberBounds (file, field);
 
583
                                        //DomRegion region = GetMemberBounds (file, field);
405
584
                                        //
406
 
                                        //begin = file.GetPositionFromLineColumn (region.BeginLine, region.BeginColumn);
407
 
                                        //end = file.GetPositionFromLineColumn (region.EndLine, region.EndColumn);
 
585
                                        //begin = file.GetPositionFromLineColumn (region.Start.Line, region.Start.Column);
 
586
                                        //end = file.GetPositionFromLineColumn (region.End.Line, region.End.Column);
408
587
                                        //
409
588
                                        //snippet = file.GetText (begin, end);
410
589
                                        //
415
594
                        CodeMemberProperty prop = new CodeMemberProperty ();
416
595
                        prop.Name = propName;
417
596
                        
418
 
                        prop.Type = ReturnTypeToDom (ctx, field.ReturnType);
419
 
                        prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
 
597
                        prop.Type = ReturnTypeToDom (ctx, cls.CompilationUnit, field.ReturnType);
 
598
                        prop.Attributes = attr | MemberAttributes.Final;
420
599
                        if (field.IsStatic)
421
600
                                prop.Attributes |= MemberAttributes.Static;
422
601
                        
423
602
                        prop.HasGet = true;
424
 
                        
425
 
                        // if the field was public before, then we provide a 'set', else we don't
426
 
                        prop.HasSet = (field.IsPublic || (!field.IsPrivate && !field.IsProtectedOrInternal));
 
603
                        prop.HasSet = generateSetter;
427
604
                        
428
605
                        EncapsulateFieldImpGetSet (ctx, cls, field, prop);
429
606
                        
433
610
 
434
611
                /// Method overridables ////////////////////////////
435
612
                
436
 
                protected virtual IMethod RenameMethod (RefactorerContext ctx, IClass cls, IMethod method, string newName)
 
613
                protected virtual IMethod RenameMethod (RefactorerContext ctx, IType cls, IMethod method, string newName)
437
614
                {
438
615
                        return null;
439
616
                }
440
617
                
441
 
                protected virtual MemberReferenceCollection FindMethodReferences (RefactorerContext ctx, string fileName, IClass cls, IMethod method)
 
618
                protected virtual IEnumerable<MemberReference> FindMethodReferences (RefactorerContext ctx, string fileName, IType cls, IMethod method)
442
619
                {
443
620
                        return null;
444
621
                }
446
623
 
447
624
                /// Field overridables ////////////////////////////
448
625
                
449
 
                protected virtual IField RenameField (RefactorerContext ctx, IClass cls, IField field, string newName)
 
626
                protected virtual IField RenameField (RefactorerContext ctx, IType cls, IField field, string newName)
450
627
                {
451
628
                        return null;
452
629
                }
453
630
                
454
 
                protected virtual MemberReferenceCollection FindFieldReferences (RefactorerContext ctx, string fileName, IClass cls, IField field)
 
631
                protected virtual IEnumerable<MemberReference> FindFieldReferences (RefactorerContext ctx, string fileName, IType cls, IField field)
455
632
                {
456
633
                        return null;
457
634
                }
459
636
 
460
637
                /// Property overridables ////////////////////////////
461
638
                
462
 
                protected virtual IProperty RenameProperty (RefactorerContext ctx, IClass cls, IProperty property, string newName)
 
639
                protected virtual IProperty RenameProperty (RefactorerContext ctx, IType cls, IProperty property, string newName)
463
640
                {
464
641
                        return null;
465
642
                }
466
643
                
467
 
                protected virtual MemberReferenceCollection FindPropertyReferences (RefactorerContext ctx, string fileName, IClass cls, IProperty property)
 
644
                protected virtual IEnumerable<MemberReference> FindPropertyReferences (RefactorerContext ctx, string fileName, IType cls, IProperty property)
468
645
                {
469
646
                        return null;
470
647
                }
471
648
 
472
649
                /// Event overridables ////////////////////////////             
473
650
                
474
 
                protected virtual IEvent RenameEvent (RefactorerContext ctx, IClass cls, IEvent evnt, string newName)
 
651
                protected virtual IEvent RenameEvent (RefactorerContext ctx, IType cls, IEvent evnt, string newName)
475
652
                {
476
653
                        return null;
477
654
                }
478
655
                
479
 
                protected virtual MemberReferenceCollection FindEventReferences (RefactorerContext ctx, string fileName, IClass cls, IEvent evnt)
 
656
                protected virtual IEnumerable<MemberReference> FindEventReferences (RefactorerContext ctx, string fileName, IType cls, IEvent evnt)
480
657
                {
481
658
                        return null;
482
659
                }
486
663
                
487
664
                public virtual bool RenameVariable (RefactorerContext ctx, LocalVariable var, string newName)
488
665
                {
489
 
                        IEditableTextFile file = ctx.GetFile (var.Region.FileName);
 
666
                        IEditableTextFile file = ctx.GetFile (var.FileName);
490
667
                        if (file == null)
491
668
                                return false;
492
669
                        
501
678
                        file.DeleteText (pos, txt.Length);
502
679
                        file.InsertText (pos, newName);
503
680
                        
504
 
                        ctx.ParserContext.ParserDatabase.UpdateFile (file.Name, file.Text);
 
681
                        ProjectDomService.Parse (ctx.ParserContext.Project, file.Name, null, delegate () { return file.Text; });
505
682
                        
506
683
                        return true;
507
684
                }
508
685
 
509
 
                public virtual MemberReferenceCollection FindVariableReferences (RefactorerContext ctx, string fileName, LocalVariable var)
 
686
                public virtual IEnumerable<MemberReference> FindVariableReferences (RefactorerContext ctx, string fileName, LocalVariable var)
510
687
                {
511
688
                        return null;
512
689
                }
521
698
                        int pos = -1;
522
699
                        
523
700
                        // It'd be nice if we didn't have to worry about this being null
524
 
                        if (member.Region.FileName != null) {
525
 
                                if ((file = ctx.GetFile (member.Region.FileName)) != null)
 
701
                        if (member.DeclaringType.CompilationUnit.FileName != null) {
 
702
                                if ((file = ctx.GetFile (member.DeclaringType.CompilationUnit.FileName)) != null)
526
703
                                        pos = GetParameterNamePosition (file, param);
527
704
                        }
528
705
                        
529
706
                        // Plan B. - fallback to searching all partial class files for this parameter's parent member
530
707
                        if (pos == -1) {
531
 
                                IClass cls = member.DeclaringType;
 
708
                                IType cls = member.DeclaringType;
532
709
                                
533
 
                                for (int i = 0; i < cls.Parts.Length; i++) {
534
 
                                        if ((file = ctx.GetFile (cls.Parts[i].Region.FileName)) == null)
 
710
                                foreach (IType part in cls.Parts) {
 
711
                                        if ((file = ctx.GetFile (part.CompilationUnit.FileName)) == null)
535
712
                                                continue;
536
713
                                        
537
714
                                        // sanity check, if the parent member isn't here then neither is the param
553
730
                        file.DeleteText (pos, txt.Length);
554
731
                        file.InsertText (pos, newName);
555
732
                        
556
 
                        ctx.ParserContext.ParserDatabase.UpdateFile (file.Name, file.Text);
 
733
                        ProjectDomService.Parse (ctx.ParserContext.Project, file.Name, null, delegate () { return file.Text; });
557
734
                        
558
735
                        return true;
559
736
                }
560
737
 
561
 
                public virtual MemberReferenceCollection FindParameterReferences (RefactorerContext ctx, string fileName, IParameter param)
 
738
                public virtual IEnumerable<MemberReference> FindParameterReferences (RefactorerContext ctx, string fileName, IParameter param)
562
739
                {
563
740
                        return null;
564
741
                }
580
757
                        return -1;
581
758
                }
582
759
 
583
 
                protected virtual IRegion GetMemberBounds (IEditableTextFile file, IMember member)
 
760
                protected virtual DomRegion GetMemberBounds (IEditableTextFile file, IMember member)
584
761
                {
585
 
                        int minLin = member.Region.BeginLine;
586
 
                        int minCol = member.Region.BeginColumn;
587
 
                        int maxLin = member.Region.EndLine;
588
 
                        int maxCol = member.Region.EndColumn;
 
762
                        int minLin = member.Location.Line;
 
763
                        int minCol = member.Location.Column;
 
764
                        int maxLin = member.BodyRegion.End.Line;
 
765
                        int maxCol = member.BodyRegion.End.Column;
589
766
                        
590
 
                        foreach (IAttributeSection att in member.Attributes) {
591
 
                                if (att.Region.BeginLine < minLin) {
592
 
                                        minLin = att.Region.BeginLine;
593
 
                                        minCol = att.Region.BeginColumn;
594
 
                                } else if (att.Region.BeginLine == minLin && att.Region.BeginColumn < minCol) {
595
 
                                        minCol = att.Region.BeginColumn;
 
767
                
 
768
                        foreach (IAttribute att in member.Attributes) {
 
769
                                if (att.Region.Start.Line < minLin) {
 
770
                                        minLin = att.Region.Start.Line;
 
771
                                        minCol = att.Region.Start.Column;
 
772
                                } else if (att.Region.Start.Line == minLin && att.Region.Start.Column < minCol) {
 
773
                                        minCol = att.Region.Start.Column;
596
774
                                }
597
775
                                
598
 
                                if (att.Region.EndLine > maxLin) {
599
 
                                        maxLin = att.Region.EndLine;
600
 
                                        maxCol = att.Region.EndColumn;
601
 
                                } else if (att.Region.EndLine == maxLin && att.Region.EndColumn > maxCol) {
602
 
                                        maxCol = att.Region.EndColumn;
 
776
                                if (att.Region.End.Line > maxLin) {
 
777
                                        maxLin = att.Region.End.Line;
 
778
                                        maxCol = att.Region.End.Column;
 
779
                                } else if (att.Region.End.Line == maxLin && att.Region.End.Column > maxCol) {
 
780
                                        maxCol = att.Region.End.Column;
603
781
                                }
604
782
                        }
605
 
                        return new DefaultRegion (minLin, minCol, maxLin, maxCol);
 
783
                        return new DomRegion (minLin, minCol, maxLin, maxCol);
606
784
                }
607
785
                
608
786
                protected virtual string GenerateCodeFromMember (CodeTypeMember member)
625
803
 
626
804
                /// Helper methods ////////////////////////////
627
805
 
628
 
                // Returns a reparsed IClass instance that contains the generated code.
629
 
                protected IClass GetGeneratedClass (RefactorerContext ctx, IEditableTextFile buffer, IClass cls)
 
806
                // Returns a reparsed IType instance that contains the generated code.
 
807
                protected IType GetGeneratedClass (RefactorerContext ctx, IEditableTextFile buffer, IType cls)
630
808
                {
631
809
                        // Don't get the class from the parse results because in that class the types are not resolved.
632
810
                        // Get the class from the database instead.
633
 
                        ctx.ParserContext.ParserDatabase.UpdateFile (buffer.Name, buffer.Text);
634
 
                        return ctx.ParserContext.GetClass (cls.FullyQualifiedName);
 
811
                        ProjectDomService.Parse (ctx.ParserContext.Project, buffer.Name, null, delegate () { return buffer.Text; });
 
812
                        return ctx.ParserContext.GetType (cls.FullName, null, true, true);
635
813
                }
636
814
                
637
 
                protected IMember FindGeneratedMember (RefactorerContext ctx, IEditableTextFile buffer, IClass cls, CodeTypeMember member, int line)
 
815
                protected IMember FindGeneratedMember (RefactorerContext ctx, IEditableTextFile buffer, IType cls, CodeTypeMember member, int line)
638
816
                {
639
 
                        IClass rclass = GetGeneratedClass (ctx, buffer, cls);
 
817
                        IType rclass = GetGeneratedClass (ctx, buffer, cls);
640
818
                        
641
819
                        if (rclass != null) {
642
820
                                if (member is CodeMemberField) {
643
821
                                        foreach (IField m in rclass.Fields)
644
 
                                                if (m.Name == member.Name && line == m.Region.BeginLine)
 
822
                                                if (m.Name == member.Name && line == m.Location.Line)
645
823
                                                        return m;
646
824
                                } else if (member is CodeMemberProperty) {
647
825
                                        foreach (IProperty m in rclass.Properties)
648
 
                                                if (m.Name == member.Name && line == m.Region.BeginLine)
 
826
                                                if (m.Name == member.Name && line == m.Location.Line)
649
827
                                                        return m;
650
828
                                } else if (member is CodeMemberEvent) {
651
829
                                        foreach (IEvent m in rclass.Events)
652
 
                                                if (m.Name == member.Name && line == m.Region.BeginLine)
 
830
                                                if (m.Name == member.Name && line == m.Location.Line)
653
831
                                                        return m;
654
832
                                } else if (member is CodeMemberMethod) {
655
833
                                        foreach (IMethod m in rclass.Methods) {
656
 
                                                if (m.Name == member.Name && line == m.Region.BeginLine)
 
834
                                                if (m.Name == member.Name && line == m.Location.Line)
657
835
                                                        return m;
658
836
                                        }
659
837
                                }
711
889
                                return code;
712
890
                }
713
891
                
714
 
                protected virtual int GetNewMemberPosition (IEditableTextFile buffer, IClass cls, CodeTypeMember member)
 
892
                protected virtual int GetNewMemberPosition (IEditableTextFile buffer, IType cls, CodeTypeMember member)
715
893
                {
716
894
                        if (member is CodeMemberField)
717
895
                                return GetNewFieldPosition (buffer, cls);
725
903
                                throw new InvalidOperationException ("Invalid member type: " + member);
726
904
                }
727
905
                
728
 
                protected virtual int GetNewFieldPosition (IEditableTextFile buffer, IClass cls)
 
906
                protected virtual int GetNewFieldPosition (IEditableTextFile buffer, IType cls)
729
907
                {
730
 
                        if (cls.Fields.Count == 0) {
731
 
                                int sp = buffer.GetPositionFromLineColumn (cls.BodyRegion.BeginLine, cls.BodyRegion.BeginColumn);
732
 
                                int ep = buffer.GetPositionFromLineColumn (cls.BodyRegion.EndLine, cls.BodyRegion.EndColumn);
 
908
                        if (cls.FieldCount == 0) {
 
909
                                int sp = buffer.GetPositionFromLineColumn (cls.BodyRegion.Start.Line, cls.BodyRegion.Start.Column);
 
910
                                int ep = buffer.GetPositionFromLineColumn (cls.BodyRegion.End.Line, cls.BodyRegion.End.Column);
733
911
                                string s = buffer.GetText (sp, ep);
734
912
                                int i = s.IndexOf ('{');
735
913
                                if (i == -1) return -1;
736
914
                                i++;
737
915
                                int pos = GetNextLine (buffer, sp + i);
738
 
                                string ind = GetLineIndent (buffer, cls.BodyRegion.BeginLine);
 
916
                                string ind = GetLineIndent (buffer, cls.BodyRegion.Start.Line);
739
917
                                buffer.InsertText (pos, ind + "\t\n");
740
918
                                return pos + ind.Length + 1;
741
919
                        } else {
742
 
                                IField f = cls.Fields [cls.Fields.Count - 1];
743
 
                                int pos = buffer.GetPositionFromLineColumn (f.Region.EndLine, f.Region.EndColumn);
 
920
                                IField f = null;
 
921
                                foreach (IField field in cls.Fields) {
 
922
                                        f = field;
 
923
                                }
 
924
                                int pos = buffer.GetPositionFromLineColumn (f.Location.Line, f.Location.Column);
744
925
                                pos = GetNextLine (buffer, pos);
745
 
                                string ind = GetLineIndent (buffer, f.Region.EndLine);
 
926
                                string ind = GetLineIndent (buffer, f.Location.Line);
746
927
                                buffer.InsertText (pos, ind);
747
928
                                return pos + ind.Length;
748
929
                        }
749
930
                }
750
931
                
751
 
                protected virtual int GetNewMethodPosition (IEditableTextFile buffer, IClass cls)
 
932
                protected virtual int GetNewMethodPosition (IEditableTextFile buffer, IType cls)
752
933
                {
753
 
                        if (cls.Methods.Count == 0) {
 
934
                        if (cls.MethodCount == 0) {
754
935
                                int pos = GetNewPropertyPosition (buffer, cls);
755
936
                                int line, col;
756
937
                                buffer.GetLineColumnFromPosition (pos, out line, out col);
759
940
                                buffer.InsertText (pos, ind);
760
941
                                return pos + ind.Length;
761
942
                        } else {
762
 
                                IMethod m = cls.Methods [cls.Methods.Count - 1];
 
943
                                IMethod m = null;
 
944
                                foreach (IMethod method in cls.Methods) {
 
945
                                        m = method;
 
946
                                }
763
947
                                
764
948
                                int pos;
765
 
                                if (m.BodyRegion != null && m.BodyRegion.EndLine > 0) {
766
 
                                        pos = buffer.GetPositionFromLineColumn (m.BodyRegion.EndLine, m.BodyRegion.EndColumn);
 
949
                                if (!m.BodyRegion.IsEmpty && m.BodyRegion.End.Line > 0) {
 
950
                                        pos = buffer.GetPositionFromLineColumn (m.BodyRegion.End.Line, m.BodyRegion.End.Column);
767
951
                                } else {
768
952
                                        // Abstract or P/Inboke methods don't have a body
769
 
                                        pos = buffer.GetPositionFromLineColumn (m.Region.EndLine, m.Region.EndColumn);
 
953
                                        pos = buffer.GetPositionFromLineColumn (m.Location.Line, m.Location.Column);
770
954
                                }
771
955
                                
772
956
                                pos = GetNextLine (buffer, pos);
773
957
                                pos = GetNextLine (buffer, pos);
774
 
                                string ind = GetLineIndent (buffer, m.Region.EndLine);
 
958
                                string ind = GetLineIndent (buffer, m.Location.Line);
775
959
                                buffer.InsertText (pos, ind);
776
960
                                return pos + ind.Length;
777
961
                        }
778
962
                }
779
963
                
780
 
                protected virtual int GetNewPropertyPosition (IEditableTextFile buffer, IClass cls)
 
964
                protected virtual int GetNewPropertyPosition (IEditableTextFile buffer, IType cls)
781
965
                {
782
 
                        if (cls.Properties.Count == 0) {
 
966
                        if (cls.PropertyCount == 0) {
783
967
                                int pos = GetNewFieldPosition (buffer, cls);
784
968
                                int line, col;
785
969
                                buffer.GetLineColumnFromPosition (pos, out line, out col);
788
972
                                buffer.InsertText (pos, indent);
789
973
                                return pos + indent.Length;
790
974
                        } else {
791
 
                                IProperty m = cls.Properties [cls.Properties.Count - 1];
792
 
                                int pos = buffer.GetPositionFromLineColumn (m.BodyRegion.EndLine, m.BodyRegion.EndColumn);
793
 
                                pos = GetNextLine (buffer, pos);
794
 
                                pos = GetNextLine (buffer, pos);
795
 
                                string indent = GetLineIndent (buffer, m.Region.EndLine);
 
975
                                IProperty m = null;
 
976
                                foreach (IProperty property in cls.Properties) {
 
977
                                        m = property;
 
978
                                }
 
979
 
 
980
                                int pos = buffer.GetPositionFromLineColumn (m.BodyRegion.End.Line, m.BodyRegion.End.Column);
 
981
                                pos = GetNextLine (buffer, pos);
 
982
                                pos = GetNextLine (buffer, pos);
 
983
                                string indent = GetLineIndent (buffer, m.Location.Line);
796
984
                                buffer.InsertText (pos, indent);
797
985
                                return pos + indent.Length;
798
986
                        }
799
987
                }
800
988
                
801
 
                protected virtual int GetNewEventPosition (IEditableTextFile buffer, IClass cls)
 
989
                protected virtual int GetNewEventPosition (IEditableTextFile buffer, IType cls)
802
990
                {
803
 
                        if (cls.Events.Count == 0) {
 
991
                        if (cls.EventCount == 0) {
804
992
                                int pos = GetNewMethodPosition (buffer, cls);
805
993
                                int line, col;
806
994
                                buffer.GetLineColumnFromPosition (pos, out line, out col);
809
997
                                buffer.InsertText (pos, ind);
810
998
                                return pos + ind.Length;
811
999
                        } else {
812
 
                                IEvent m = cls.Events [cls.Events.Count - 1];
813
 
                                int pos = buffer.GetPositionFromLineColumn (m.Region.EndLine, m.Region.EndColumn);
814
 
                                pos = GetNextLine (buffer, pos);
815
 
                                pos = GetNextLine (buffer, pos);
816
 
                                string ind = GetLineIndent (buffer, m.Region.EndLine);
 
1000
                                IEvent m = null;
 
1001
                                foreach (IEvent evt in cls.Events) {
 
1002
                                        m = evt;
 
1003
                                }
 
1004
 
 
1005
                                int pos = buffer.GetPositionFromLineColumn (m.Location.Line, m.Location.Column);
 
1006
                                pos = GetNextLine (buffer, pos);
 
1007
                                pos = GetNextLine (buffer, pos);
 
1008
                                string ind = GetLineIndent (buffer, m.Location.Line);
817
1009
                                buffer.InsertText (pos, ind);
818
1010
                                return pos + ind.Length;
819
1011
                        }
856
1048
                                ops.BracingStyle = "C";
857
1049
                        return ops;
858
1050
                }
 
1051
 
859
1052
        }
860
1053
}