private FieldReference ResolveStateClassField(TypeReference role) { var stateTypeDefinition = role.ResolveStateClass(); var stateTypeReference = new MemberResolver(role).ResolveMatchingType(stateTypeDefinition); var fieldDefinition = _targetType.Fields. SingleOrDefault(fd => TypeMatcher.IsMatch(fd.FieldType, stateTypeReference)); if (fieldDefinition == null) return null; // TODO: this is because the role was already implemented in a base class; it should be checked before, possibly in the conflict resolution stage return new FieldReference( fieldDefinition.Name, fieldDefinition.FieldType) { DeclaringType = fieldDefinition.DeclaringType.ResolveGenericArguments() }; }
public MemberFinder(TypeReference searchType) { if (searchType == null) throw new ArgumentNullException("searchType"); SearchType = searchType; _resolver = new MemberResolver(SearchType); ResolveMembers(); }
private IEnumerable<MethodDefinition> ResolveVirtualBaseMethodsDeclarations(IEnumerable<ClassMember> baseMethodsSet) { var definitions = new List<MethodDefinition>(); foreach (var baseMethod in baseMethodsSet) { var method = (MethodDefinition)baseMethod.Definition; var definition = new MemberResolver(baseMethod.Class). ResolveMethodDefinition( method, NameProvider.GetVirtualBaseMethodName(baseMethod.Class.Name, method.Name), MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Abstract | MethodAttributes.Virtual | MethodAttributes.NewSlot); definitions.Add(definition); } return definitions; }
private static void RetrieveRoles(this TypeReference self, Dictionary<TypeReference, int> roleCollector, int sortOrder = 1) { // Note: the roles from the base types are already implemented, so there's no need to reimplement them var directRoles = self.RetrieveDirectRoles(); // get the roles from the direct roles directRoles.ForEach(role => { if (!(self is TypeDefinition)) { role = new MemberResolver(self).ResolveConstituentType(role); } var roleInCollector = roleCollector.Keys.SingleOrDefault(type => TypeMatcher.IsMatch(type, role)); if (roleInCollector != null) { if (roleCollector[roleInCollector] < sortOrder) { roleCollector[roleInCollector] = sortOrder; role.RetrieveRoles(roleCollector, sortOrder + 1); // have to recurse to adjust the parents' sort order } } else { roleCollector.Add(role, sortOrder); role.RetrieveRoles(roleCollector, sortOrder + 1); } }); }
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; }