98
124
return FindGeneratedMember (ctx, buffer, cls, member, line);
127
public virtual void AddMembers (RefactorerContext ctx, IType cls, IEnumerable<CodeTypeMember> members)
129
foreach (CodeTypeMember member in members)
130
AddMember (ctx, cls, member);
133
public virtual void AddMembers (RefactorerContext ctx, IType cls,
134
IEnumerable<CodeTypeMember> members, string foldingRegionName)
136
//no region name, so distribute them with like members
137
if (string.IsNullOrEmpty (foldingRegionName)) {
138
AddMembers (ctx, cls, members);
145
IEditableTextFile buffer = ctx.GetFile (cls.CompilationUnit.FileName);
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);
153
pos = AddFoldingRegion (ctx, cls, foldingRegionName);
156
AddMembersAtPosition (ctx, cls, members, buffer, pos);
159
protected void AddMembersAtPosition (RefactorerContext ctx, IType cls, IEnumerable<CodeTypeMember> members,
160
IEditableTextFile buffer, int pos)
163
buffer.GetLineColumnFromPosition (pos, out line, out col);
165
string indent = GetLineIndent (buffer, line);
166
List<int> positions = new List<int> ();
169
foreach (CodeTypeMember member in members) {
171
string code = GenerateCodeFromMember (member);
172
//spacing between inserted members
176
code = "\n\n" + code;
178
code = Indent (code, indent, false);
179
buffer.InsertText (pos, code);
184
public virtual int AddFoldingRegion (RefactorerContext ctx, IType cls, string regionName)
186
IEditableTextFile buffer = ctx.GetFile (cls.CompilationUnit.FileName);
187
return GetNewMethodPosition (buffer, cls);
101
IReturnType GetGenericArgument (IClass type, IReturnType rtype, IReturnType hintType)
191
IReturnType GetGenericArgument (IType type, IReturnType rtype, IReturnType hintType)
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];
155
242
if (IsBaseType (type.FullName))
156
243
return new CodeTypeReference (type);
157
return new CodeTypeReference (ctx.TypeNameResolver.ResolveName (type.FullName));
160
public virtual IMember ImplementMember (RefactorerContext ctx, IClass cls, IMember member, IReturnType privateImplementationType)
245
// return new CodeTypeReference (ctx.TypeNameResolver.ResolveName (type.FullName));
246
return new CodeTypeReference (type.FullName);
249
public virtual IMember ImplementMember (RefactorerContext ctx, IType cls, IMember member, IReturnType privateImplementationType)
251
CodeTypeMember m = CreateImplementation (ctx, cls, member, privateImplementationType);
252
return AddMember (ctx, cls, m);
255
public virtual void ImplementMembers (RefactorerContext ctx, IType cls,
256
IEnumerable<KeyValuePair<IMember,IReturnType>> members,
257
string foldingRegionName)
259
AddMembers (ctx, cls, YieldImpls (ctx, cls, members), foldingRegionName);
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)
267
foreach (KeyValuePair<IMember,IReturnType> mem in members)
268
yield return CreateImplementation (ctx, cls, mem.Key, mem.Value);
271
protected CodeTypeMember CreateImplementation (RefactorerContext ctx, IType cls, IMember member,
272
IReturnType privateImplementationType)
162
274
CodeTypeMember m;
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);
281
mEvent.Type = ReturnTypeToDom (ctx, cls.CompilationUnit, member.ReturnType);
282
if (!is_interface_method)
283
mEvent.Attributes = MemberAttributes.Override;
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;
292
foreach (ITypeParameter param in method.TypeParameters)
293
mMethod.TypeParameters.Add (param.Name);
295
if (!is_interface_method)
296
mMethod.Attributes = MemberAttributes.Override;
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);
304
List<CodeExpression> parameters = new List<CodeExpression> ();
305
foreach (IParameter parameter in method.Parameters) {
306
parameters.Add (new CodeVariableReferenceExpression (parameter.Name));
308
mMethod.Statements.Add (new CodeMethodInvokeExpression (new CodeBaseReferenceExpression (), member.Name, parameters.ToArray ()));
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);
315
par.Direction = FieldDirection.Out;
316
else if (param.IsRef)
317
par.Direction = FieldDirection.Ref;
319
par.CustomAttributes.Add (new CodeAttributeDeclaration ("System.ParamArrayAttribute"));
183
320
mMethod.Parameters.Add (par);
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;
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;
197
mProperty.GetStatements.Add (throwExpression);
199
mProperty.SetStatements.Add (throwExpression);
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;
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);
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 ();
329
if (!is_interface_method)
330
mProperty.Attributes = MemberAttributes.Override;
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);
340
mProperty.GetStatements.Add (new CodeMethodReturnStatement (new CodePropertyReferenceExpression(new CodeBaseReferenceExpression(), property.Name)));
343
if (property.HasSet) {
344
if (member.IsAbstract || member.DeclaringType.ClassType == ClassType.Interface) {
345
mProperty.SetStatements.Add (throwExpression);
347
mProperty.SetStatements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression(new CodeBaseReferenceExpression(), property.Name), new CodePropertySetValueReferenceExpression ()));
351
mProperty.Type = ReturnTypeToDom (ctx, cls.CompilationUnit, member.ReturnType);
352
if (privateImplementationType != null)
353
mProperty.PrivateImplementationType = ReturnTypeToDom (ctx, cls.CompilationUnit, privateImplementationType);
356
CodeMemberProperty mProperty = new CodeMemberProperty ();
358
if (!is_interface_method)
359
mProperty.Attributes = MemberAttributes.Override;
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;
366
List<CodeExpression> parameters = new List<CodeExpression> ();
367
foreach (IParameter parameter in property.Parameters) {
368
parameters.Add (new CodeVariableReferenceExpression (parameter.Name));
371
if (mProperty.HasGet) {
372
if (member.IsAbstract || member.DeclaringType.ClassType == ClassType.Interface) {
373
mProperty.GetStatements.Add (throwExpression);
375
mProperty.GetStatements.Add (new CodeMethodReturnStatement (new CodeIndexerExpression (new CodeBaseReferenceExpression(), parameters.ToArray ())));
378
if (mProperty.HasSet) {
379
if (member.IsAbstract || member.DeclaringType.ClassType == ClassType.Interface) {
380
mProperty.SetStatements.Add (throwExpression);
382
mProperty.SetStatements.Add (new CodeAssignStatement (new CodeIndexerExpression (new CodeBaseReferenceExpression(), parameters.ToArray ()), new CodePropertySetValueReferenceExpression ()));
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);
392
mProperty.Type = ReturnTypeToDom (ctx, cls.CompilationUnit, member.ReturnType);
393
if (privateImplementationType != null)
394
mProperty.PrivateImplementationType = ReturnTypeToDom (ctx, cls.CompilationUnit, privateImplementationType);
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;
404
if (member.DeclaringType != null && member.DeclaringType.ClassType == ClassType.Interface) {
405
m.Attributes = (m.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
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;
224
mProperty.Type = ReturnTypeToDom (ctx, member.ReturnType);
225
if (privateImplementationType != null)
226
mProperty.PrivateImplementationType = ReturnTypeToDom (ctx, privateImplementationType);
231
if (member is IIndexer)
234
m.Name = member.Name;
236
m.Attributes = MemberAttributes.Final;
238
if (privateImplementationType == null)
239
m.Attributes |= MemberAttributes.Public;
241
return AddMember (ctx, cls, m);
244
public virtual void RemoveMember (RefactorerContext ctx, IClass cls, IMember member)
424
public virtual void RemoveMember (RefactorerContext ctx, IType cls, IMember member)
246
426
IEditableTextFile buffer = null;
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)
253
432
if ((pos = GetMemberNamePosition (buffer, member)) != -1)
626
804
/// Helper methods ////////////////////////////
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)
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);
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)
639
IClass rclass = GetGeneratedClass (ctx, buffer, cls);
817
IType rclass = GetGeneratedClass (ctx, buffer, cls);
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)
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)
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)
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)
725
903
throw new InvalidOperationException ("Invalid member type: " + member);
728
protected virtual int GetNewFieldPosition (IEditableTextFile buffer, IClass cls)
906
protected virtual int GetNewFieldPosition (IEditableTextFile buffer, IType cls)
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;
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;
742
IField f = cls.Fields [cls.Fields.Count - 1];
743
int pos = buffer.GetPositionFromLineColumn (f.Region.EndLine, f.Region.EndColumn);
921
foreach (IField field in cls.Fields) {
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;
751
protected virtual int GetNewMethodPosition (IEditableTextFile buffer, IClass cls)
932
protected virtual int GetNewMethodPosition (IEditableTextFile buffer, IType cls)
753
if (cls.Methods.Count == 0) {
934
if (cls.MethodCount == 0) {
754
935
int pos = GetNewPropertyPosition (buffer, cls);
756
937
buffer.GetLineColumnFromPosition (pos, out line, out col);