public ConflictDetectionResult Process(ContributedConflictGroup group)
        {
            group.ResolvedMember = null;
              group.HasConflict = false;

              var result = new ConflictDetectionResult();

              if (group.IsSuperceded) {
            return result; // TODO: process warnings? views here are superfluous since the member is overriden!
              }

              // to solve the conflict, EXACTLY one non-abstract member must remain in the list

              // only consider foreign members
              var resolvedMembers = group.Members.Where(roleMember => roleMember.IsForeign).ToList();

              // process excluded members
              resolvedMembers = resolvedMembers.Where(roleMember => !roleMember.IsExcluded).ToList();
              if (resolvedMembers.Count == 0) {
            result.AddMessage(Error.AllMembersExcluded(group.TargetType, group.ResolveRepresentation()));
            return result;
              }

              // process aliased members
              resolvedMembers = resolvedMembers.Where(roleMember => !roleMember.IsAliased).ToList();
              if (resolvedMembers.Count == 0) {
            // all members are aliased
            group.ResolvedMember = null;
            return result;
              }

              // process base methods
              if (resolvedMembers.All(roleMember => roleMember.Definition.IsBaseMethod())) {
            // all members are virtual base members, they'll be provided by the composing class
            group.IsBaseMethod = true;
            group.ResolvedMember = null;
            return result;
              }
              Tracer.Assert(!resolvedMembers.Any(roleMember => roleMember.Definition.IsBaseMethod()), "Base methods cannot be provided by roles");

              if (resolvedMembers.All(roleMember => roleMember.IsAbstract)) {
            if (!group.TargetType.IsRole()) {
              result.AddMessage(Error.DoesNotImplementAbstractRoleMember(group.TargetType, group.ResolveRepresentation()));
            }
            return result;
              }

              // process abstract members
              resolvedMembers = resolvedMembers.Where(roleMember => !roleMember.IsAbstract).ToList();
              if (resolvedMembers.Count > 1) {
            group.HasConflict = true;
            result.AddMessage(Error.Conflict(group.TargetType, group.ResolveRepresentation(), resolvedMembers));
            return result;
              }

              group.ResolvedMember = resolvedMembers.Single();

              return result;
        }
示例#2
0
        public IMemberDefinition Compose(ContributedConflictGroup group, MethodAttributes accessSpecifier)
        {
            Group = group;
              if (group.ImplementedMember != null) {
            return group.ImplementedMember;
              }
              if (group.DontImplement) {
            return null;
              }

              if (group.IsSuperceded) {
            // the superceding member in the class is the implementing member for the role member
            return group.ImplementedMember = AdjustSupercedingMember(group.Supercede, group.ResolveOverridingMembers());
              }

              if (group.IsBaseMethod) {
            ImplementBaseMethod(group.Members[0], group.ResolveOverridingMembers()); // any member will do, they all point to the same base method
            // TODO: use the ImplementedMember here?
            return null;
              }

              // the resolved member implements all the other members in the group by calling its implementing member
              var resolvedMember = group.ResolvedMember;

              if (resolvedMember == null) {
            // this member does not get composed (it will be aliased by another member)
            return null;
              }

              var implementedMember = ImplementMember(
            resolvedMember.Definition.Name,
            resolvedMember.ResolveImplementingMember(),
            group.ResolveOverridingMembers(),
            accessSpecifier);
              if (implementedMember == null) {
            // this member was not implemented (it was provided by a base class)
            return null;
              }
              if (group.ReuseSlot) {
            ((MethodDefinition)implementedMember).IsNewSlot = false;
              }
              return group.ImplementedMember = implementedMember;
        }
示例#3
0
 public IMemberDefinition Compose(ContributedConflictGroup group)
 {
     return Compose(group, MethodAttributes.Public);
 }