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;
 }
Ejemplo n.º 3
0
 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);
 }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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;
        }