private void ResolveBaseMethods() { foreach (var instruction in _callsToBaseMethods) { var method = (MethodReference)instruction.Operand; if (!HasMethod(method)) { var classMember = new ClassMember(method.DeclaringType, method.Resolve(), isInherited: true); _baseMethodsSet.Add(classMember); } } }
// marks the member as superceded in the target type public void MarkAsSuperceded(ClassMember supercedingMember) { _supercedingMember = supercedingMember; }
private void CreateCodeToCallBaseClassMethod(MethodDefinition derivedMethod, ClassMember baseMember) { var baseMethod = (MethodDefinition)baseMember.Definition; var methodReference = TargetType.Module.Import(baseMethod); // need to Import a method from another assembly. TODO: move this code to the MemberResolver, make it use the MutationContext PushParameters(derivedMethod); EmitCodeToCallMethod(derivedMethod, methodReference); derivedMethod.Body.GetILProcessor().Emit(OpCodes.Ret); }
private void ImplementBaseMethod(RoleCompositionMember typeMember, IEnumerable<RoleCompositionMember> overrides) { Tracer.TraceVerbose("Implement base method: {0}", typeMember.Definition); string baseMethodName = NameProvider.GetOriginalBaseMethodName(typeMember.Definition.Name); ClassMember baseMember = null; var currentType = TargetType.BaseType; do { var finder = new MemberFinder(currentType.Resolve()); var foundBase = finder.FindMatchFor(typeMember.Definition, baseMethodName); if (foundBase != null) { baseMember = new ClassMember(currentType, foundBase, isInherited: true); break; } currentType = currentType.Resolve().BaseType; } while (currentType != null); if (baseMember == null) throw new InvalidOperationException(); // TODO: refactor with AdjustSupercedingMember! var method = (MethodDefinition)typeMember.Definition; var targetMethod = new MemberResolver(baseMember.Class, Module).ResolveMethodDefinition(method, method.Name, MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.HideBySig); CreateCodeToCallBaseClassMethod(targetMethod, baseMember); TargetType.Methods.Add(targetMethod); AddOverrides(targetMethod, overrides); }
private MethodDefinition AdjustSupercedingMember(ClassMember classMember, IEnumerable<RoleCompositionMember> overrides) { if (overrides.Count() == 0) return null; var member = classMember.Definition; var method = member as MethodDefinition; if (method == null) return null; Tracer.TraceVerbose("Adjust superceding member: {0}", classMember.Definition); MethodDefinition targetMethod = null; if (!classMember.IsInherited) { targetMethod = method; } else { // if it's in a base class, create a new method in the target class that calls the base class method targetMethod = new MemberResolver(classMember.Class, Module).ResolveMethodDefinition(method); if (method.IsVirtual && !method.IsFinal) { targetMethod.IsNewSlot = false; // the derived method overrides the base method } if (!method.IsAbstract) { CreateCodeToCallBaseClassMethod(targetMethod, classMember); } TargetType.Methods.Add(targetMethod); } // add the corresponding overrides to the method AddOverrides(targetMethod, overrides); if (!(method.IsVirtual || method.IsAbstract)) { // to support polymorphism with regards to the role interface, mark as virtual sealed targetMethod.Attributes |= MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final; } return targetMethod; }