public virtual Differences VisitMemberList(MemberList list1, MemberList list2, out MemberList changes, out MemberList deletions, out MemberList insertions){ changes = list1 == null ? null : list1.Clone(); deletions = list1 == null ? null : list1.Clone(); insertions = list1 == null ? new MemberList() : list1.Clone(); //^ assert insertions != null; Differences differences = new Differences(); //Compare definitions that have matching key attributes TrivialHashtable matchingPosFor = new TrivialHashtable(); TrivialHashtable matchedNodes = new TrivialHashtable(); for (int j = 0, n = list2 == null ? 0 : list2.Count; j < n; j++){ //^ assert list2 != null; Member nd2 = list2[j]; if (nd2 == null || nd2.Name == null) continue; string fullName = nd2.FullName; if (fullName == null) continue; matchingPosFor[Identifier.For(fullName).UniqueIdKey] = j; insertions.Add(null); } for (int i = 0, n = list1 == null ? 0 : list1.Count; i < n; i++){ //^ assert list1 != null && changes != null && deletions != null; Member nd1 = list1[i]; if (nd1 == null || nd1.Name == null) continue; string fullName = nd1.FullName; if (fullName == null) continue; object pos = matchingPosFor[Identifier.For(fullName).UniqueIdKey]; if (!(pos is int)) continue; //^ assert pos != null; //^ assume list2 != null; //since there was entry int matchingPosFor int j = (int)pos; Member nd2 = list2[j]; //^ assume nd2 != null; //nd1 and nd2 have the same key attributes and are therefore treated as the same entity matchedNodes[nd1.UniqueKey] = nd1; matchedNodes[nd2.UniqueKey] = nd2; //nd1 and nd2 may still be different, though, so find out how different Differences diff = this.VisitMember(nd1, nd2); if (diff == null){Debug.Assert(false); continue;} if (diff.NumberOfDifferences != 0){ changes[i] = diff.Changes as Member; deletions[i] = diff.Deletions as Member; insertions[i] = diff.Insertions as Member; insertions[n+j] = nd1; //Records the position of nd2 in list2 in case the change involved a permutation Debug.Assert(diff.Changes == changes[i] && diff.Deletions == deletions[i] && diff.Insertions == insertions[i]); differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; if ((nd1.DeclaringType != null && nd1.DeclaringType.DeclaringModule == this.OriginalModule) || (nd1 is TypeNode && ((TypeNode)nd1).DeclaringModule == this.OriginalModule)){ if (this.MembersThatHaveChanged == null) this.MembersThatHaveChanged = new MemberList(); this.MembersThatHaveChanged.Add(nd1); } continue; } changes[i] = null; deletions[i] = null; insertions[i] = null; insertions[n+j] = nd1; //Records the position of nd2 in list2 in case the change involved a permutation } //Find deletions for (int i = 0, n = list1 == null ? 0 : list1.Count; i < n; i++){ //^ assert list1 != null && changes != null && deletions != null; Member nd1 = list1[i]; if (nd1 == null) continue; if (matchedNodes[nd1.UniqueKey] != null) continue; changes[i] = null; deletions[i] = nd1; insertions[i] = null; differences.NumberOfDifferences += 1; if ((nd1.DeclaringType != null && nd1.DeclaringType.DeclaringModule == this.OriginalModule) || (nd1 is TypeNode && ((TypeNode)nd1).DeclaringModule == this.OriginalModule)){ if (this.MembersThatHaveChanged == null) this.MembersThatHaveChanged = new MemberList(); this.MembersThatHaveChanged.Add(nd1); } } //Find insertions for (int j = 0, n = list1 == null ? 0 : list1.Count, m = list2 == null ? 0 : list2.Count; j < m; j++){ //^ assert list2 != null; Member nd2 = list2[j]; if (nd2 == null) continue; if (matchedNodes[nd2.UniqueKey] != null) continue; insertions[n+j] = nd2; //Records nd2 as an insertion into list1, along with its position in list2 differences.NumberOfDifferences += 1; //REVIEW: put the size of the tree here? } if (differences.NumberOfDifferences == 0){ changes = null; deletions = null; insertions = null; } return differences; }
public virtual MemberList InferMethodTemplateArguments(MemberList members, ExpressionList arguments, bool doNotDiscardOverloadsWithMoreParameters){ if (arguments == null) return members; int numArgs = arguments.Count; if (numArgs == 0) return members; MemberList result = null; for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++){ Method m = members[i] as Method; if (m == null || m.Parameters == null) continue; int numPars = m.Parameters.Count; if (m.Parameters.Count == 0) continue; TypeNode paramArrayElemType = m.Parameters[numPars-1] == null ? null : m.Parameters[numPars-1].GetParamArrayElementType(); if (numPars > numArgs){ if (!doNotDiscardOverloadsWithMoreParameters && (numPars != numArgs+1 || paramArrayElemType == null)) continue; }else if (numPars < numArgs && paramArrayElemType == null) { continue; } if (m.TemplateParameters == null || m.TemplateParameters.Count == 0) continue; Method mti = this.InferMethodTemplateArgumentsAndReturnTemplateInstance(m, arguments, doNotDiscardOverloadsWithMoreParameters, paramArrayElemType); if (mti == null || mti == m) continue; if (result == null) result = members.Clone(); result[i] = mti; } if (result == null) return members; return result; }