159
160
IndentLevel = AutoIndent ? CodeGenerationService.CalculateBodyIndentLevel (implementingType) : 0;
162
public string CreateInterfaceImplementation (ITypeDefinition implementingType, IUnresolvedTypeDefinition implementingPart, IType interfaceType, bool explicitly, bool wrapRegions = true)
164
SetIndentTo (implementingPart);
165
StringBuilder result = new StringBuilder ();
166
List<IMember> implementedMembers = new List<IMember> ();
167
foreach (var def in interfaceType.GetAllBaseTypes ().Where (bt => bt.Kind == TypeKind.Interface)) {
168
if (result.Length > 0) {
172
string implementation = InternalCreateInterfaceImplementation (implementingType, implementingPart, def, explicitly, implementedMembers);
173
if (string.IsNullOrWhiteSpace (implementation))
176
result.Append (WrapInRegions (def.Name + " implementation", implementation));
178
result.Append (implementation);
181
return result.ToString ();
184
163
static bool CompareMethods (IMethod interfaceMethod, IMethod typeMethod)
186
165
if (typeMethod.IsExplicitInterfaceImplementation)
188
167
return SignatureComparer.Ordinal.Equals (interfaceMethod, typeMethod);
191
public static List<KeyValuePair<IMember, bool>> CollectMembersToImplement (ITypeDefinition implementingType, IType interfaceType, bool explicitly)
193
var def = interfaceType.GetDefinition ();
194
List<KeyValuePair<IMember, bool>> toImplement = new List<KeyValuePair<IMember, bool>> ();
195
bool alreadyImplemented;
196
// Stub out non-implemented events defined by @iface
197
foreach (var ev in interfaceType.GetEvents (e => !e.IsSynthetic && e.DeclaringTypeDefinition.ReflectionName == def.ReflectionName)) {
198
bool needsExplicitly = explicitly;
199
alreadyImplemented = implementingType.GetAllBaseTypeDefinitions ().Any (x => x.Kind != TypeKind.Interface && x.Events.Any (y => y.Name == ev.Name));
201
if (!alreadyImplemented)
202
toImplement.Add (new KeyValuePair<IMember, bool> (ev, needsExplicitly));
205
// Stub out non-implemented methods defined by @iface
206
foreach (var method in interfaceType.GetMethods (d => !d.IsSynthetic && d.DeclaringTypeDefinition.ReflectionName == def.ReflectionName)) {
207
bool needsExplicitly = explicitly;
208
alreadyImplemented = false;
210
foreach (var cmet in implementingType.GetMethods ()) {
211
if (CompareMethods (method, cmet)) {
212
if (!needsExplicitly && !cmet.ReturnType.Equals (method.ReturnType))
213
needsExplicitly = true;
215
alreadyImplemented |= !needsExplicitly /*|| cmet.InterfaceImplementations.Any (impl => impl.InterfaceType.Equals (interfaceType))*/;
218
if (!alreadyImplemented)
219
toImplement.Add (new KeyValuePair<IMember, bool> (method, needsExplicitly));
222
// Stub out non-implemented properties defined by @iface
223
foreach (var prop in interfaceType.GetProperties (p => !p.IsSynthetic && p.DeclaringTypeDefinition.ReflectionName == def.ReflectionName)) {
224
bool needsExplicitly = explicitly;
225
alreadyImplemented = false;
226
foreach (var t in implementingType.GetAllBaseTypeDefinitions ()) {
227
if (t.Kind == TypeKind.Interface)
229
foreach (IProperty cprop in t.Properties) {
230
if (cprop.Name == prop.Name) {
231
if (!needsExplicitly && !cprop.ReturnType.Equals (prop.ReturnType))
232
needsExplicitly = true;
234
alreadyImplemented |= !needsExplicitly/* || cprop.InterfaceImplementations.Any (impl => impl.InterfaceType.Resolve (ctx).Equals (interfaceType))*/;
238
if (!alreadyImplemented)
239
toImplement.Add (new KeyValuePair<IMember, bool> (prop, needsExplicitly));
244
protected string InternalCreateInterfaceImplementation (ITypeDefinition implementingType, IUnresolvedTypeDefinition part, IType interfaceType, bool explicitly, List<IMember> implementedMembers)
246
StringBuilder result = new StringBuilder ();
247
var toImplement = CollectMembersToImplement (implementingType, interfaceType, explicitly);
250
foreach (var pair in toImplement) {
257
bool isExplicit = pair.Value;
258
foreach (var member in implementedMembers.Where (m => m.Name == pair.Key.Name && m.EntityType == pair.Key.EntityType)) {
260
if (member is IMethod && pair.Key is IMethod) {
261
var method = (IMethod)member;
262
var othermethod = (IMethod)pair.Key;
263
isExplicit = CompareMethods (othermethod, method);
268
result.Append (CreateMemberImplementation (implementingType, part, pair.Key, isExplicit).Code);
269
implementedMembers.Add (pair.Key);
272
return result.ToString ();
275
170
public abstract string WrapInRegions (string regionName, string text);
276
171
public abstract CodeGeneratorMemberResult CreateMemberImplementation (ITypeDefinition implementingType, IUnresolvedTypeDefinition part, IUnresolvedMember member, bool explicitDeclaration);
277
172
public abstract CodeGeneratorMemberResult CreateMemberImplementation (ITypeDefinition implementingType, IUnresolvedTypeDefinition part, IMember member, bool explicitDeclaration);