public virtual SwitchCaseList VisitSwitchCaseList(SwitchCaseList switchCases, SwitchCaseList changes, SwitchCaseList deletions, SwitchCaseList insertions){ if (switchCases == null) return changes; if (changes != null){ if (deletions == null || insertions == null) Debug.Assert(false); else{ } }else if (deletions != null) return null; return switchCases; }
public virtual Differences VisitSwitchCaseList(SwitchCaseList list1, SwitchCaseList list2, out SwitchCaseList changes, out SwitchCaseList deletions, out SwitchCaseList insertions){ changes = list1 == null ? null : list1.Clone(); deletions = list1 == null ? null : list1.Clone(); insertions = list1 == null ? new SwitchCaseList() : list1.Clone(); //^ assert insertions != null; Differences differences = new Differences(); for (int j = 0, n = list2 == null ? 0 : list2.Count; j < n; j++){ //^ assert list2 != null; SwitchCase nd2 = list2[j]; if (nd2 == null) continue; insertions.Add(null); } TrivialHashtable savedDifferencesMapFor = this.differencesMapFor; this.differencesMapFor = null; TrivialHashtable matchedNodes = new TrivialHashtable(); for (int i = 0, k = 0, n = list1 == null ? 0 : list1.Count; i < n; i++){ //^ assert list1 != null && changes != null && deletions != null; SwitchCase nd1 = list1[i]; if (nd1 == null) continue; Differences diff; int j; SwitchCase nd2 = this.GetClosestMatch(nd1, list1, list2, i, ref k, matchedNodes, out diff, out j); if (nd2 == null || diff == null){Debug.Assert(nd2 == null && diff == null); continue;} matchedNodes[nd1.UniqueKey] = nd1; matchedNodes[nd2.UniqueKey] = nd2; changes[i] = diff.Changes as SwitchCase; deletions[i] = diff.Deletions as SwitchCase; insertions[i] = diff.Insertions as SwitchCase; 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; } //Find deletions for (int i = 0, n = list1 == null ? 0 : list1.Count; i < n; i++){ //^ assert list1 != null && changes != null && deletions != null; SwitchCase 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; } //Find insertions for (int j = 0, n = list1 == null ? 0 : list1.Count, m = list2 == null ? 0 : list2.Count; j < m; j++){ //^ assert list2 != null; SwitchCase 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; } this.differencesMapFor = savedDifferencesMapFor; return differences; }
public virtual SwitchCase GetClosestMatch(SwitchCase/*!*/ nd1, SwitchCaseList/*!*/ list1, SwitchCaseList list2, int list1pos, ref int list2start, TrivialHashtable/*!*/ matchedNodes, out Differences closestDifferences, out int list2pos) { closestDifferences = null; list2pos = -1; if (list2 == null) return null; if (nd1 == null || list1 == null || matchedNodes == null || list1pos < 0 || list1pos >= list1.Count || list2start < 0 || list2start >= list2.Count) { Debug.Assert(false); return null; } SwitchCase closest = null; Differences winnerSoFar = null; for (int j = list2start, m = list2.Count; j < m; j++){ SwitchCase nd2 = list2[j]; if (list2start == j) list2start++; if (nd2 == null) continue; if (matchedNodes[nd2.UniqueKey] != null) continue; Differences diff = this.GetDifferences(nd1, nd2); if (diff == null){Debug.Assert(false); continue;} if (diff.Similarity <= 0.5){ //Not a good enough match if (list2start == j+1) list2start--; //The next call to GetClosestMatch will start looking at list2start, so this node will be considered then continue; //ignore it for the rest of this call } if (winnerSoFar != null && winnerSoFar.Similarity >= diff.Similarity) continue; winnerSoFar = closestDifferences = diff; closest = nd2; list2pos = j; if (diff.NumberOfDifferences == 0) return closest; //Perfect match, no need to look for other matches } if (closest != null){ //^ assert winnerSoFar != null; //closest is closer to nd1 than any other node in list2, but this is no good if some other node in list1 has a better claim on closest for (int i = list1pos+1, n = list1.Count; i < n; i++){ SwitchCase nd1alt = list1[i]; if (nd1alt == null) continue; if (matchedNodes[nd1alt.UniqueKey] != null) continue; Differences diff = this.GetDifferences(nd1alt, closest); if (diff == null){Debug.Assert(false); continue;} if (diff.Similarity <= winnerSoFar.Similarity) continue; //nd1alt has a better claim on closest. See if it wants closest. Differences diff2; int j, k = list2start; SwitchCase nd2alt = this.GetClosestMatch(nd1alt, list1, list2, i, ref k, matchedNodes, out diff2, out j); if (nd2alt != closest){ Debug.Assert(nd2alt != null && diff2 != null && diff2.Similarity >= diff.Similarity); continue; //nd1alt prefers nd2alt to closest, so closest is still available } //nd1alt wants closest, take it out of the running matchedNodes[closest.UniqueKey] = nd1alt; //Now that closest is out of the running, try again k = list2start; SwitchCase newClosest = this.GetClosestMatch(nd1, list1, list2, i, ref k, matchedNodes, out winnerSoFar, out list2pos); //put closest back in the running so that the next call to this routine will pick it up matchedNodes[closest.UniqueKey] = closest; closest = newClosest; break; } } closestDifferences = winnerSoFar; return closest; }
public override Statement VisitSwitch(Switch Switch) { if (Switch == null) return null; this.CheckForDuplicateDeclarations(Switch.Scope); Expression swexpr = this.VisitExpression(Switch.Expression); if (swexpr == null) return null; TypeNode swexprType = swexpr.Type; Reference r = swexprType as Reference; if (r != null) swexprType = r.ElementType; if (this.typeSystem.IsNullableType(swexprType)) { Switch.Nullable = new Local(swexprType); Switch.NullableExpression = swexpr; swexprType = this.typeSystem.RemoveNullableWrapper(swexprType); Switch.Expression = swexpr = this.typeSystem.ExplicitCoercion(Switch.Nullable, swexprType, this.TypeViewer); } TypeNode govType = this.GetGoverningType(swexprType); if (govType == null) this.HandleError(swexpr, Error.IntegralTypeValueExpected); else { if (swexprType != swexpr.Type) swexpr = this.typeSystem.ExplicitCoercion(swexpr, swexprType, this.TypeViewer); Switch.Expression = swexpr = this.typeSystem.ImplicitCoercion(swexpr, govType, this.TypeViewer); } TypeNode savedGoverningType = this.currentSwitchGoverningType; this.currentSwitchGoverningType = govType; SwitchCaseList cases = Switch.Cases; if (swexpr == null || cases == null) return null; Literal swlit = swexpr as Literal; int n = cases.Count; SwitchCaseList savedCases = this.currentSwitchCases; this.currentSwitchCases = cases; Hashtable alreadySeenLabelValues = new Hashtable(); for (int i = 0; i < n; i++) { SwitchCase scase = cases[i]; if (scase == null) continue; Literal lit = scase.Label as Literal; if (lit == null && scase.Label != null) { MemberBinding mb = scase.Label as MemberBinding; if (mb != null && mb.BoundMember is Field && ((Field)mb.BoundMember).IsLiteral) lit = ((Field)mb.BoundMember).DefaultValue; if (lit == null) { this.HandleError(scase.Label, Error.ConstantExpected); cases[i] = null; continue; } } if (lit != null && govType != null) { if (Switch.Nullable == null || !Literal.IsNullLiteral(lit)) lit = this.typeSystem.ImplicitLiteralCoercion(lit, lit.Type, govType, this.TypeViewer); if (lit != null && lit.Value != null) { Node prev = (Node)alreadySeenLabelValues[lit.Value]; if (prev != null) { this.HandleError(scase.Label, Error.DuplicateCaseLabel, "case "+scase.Label.SourceContext.SourceText+":"); this.HandleError(prev, Error.RelatedErrorLocation); } alreadySeenLabelValues[lit.Value] = scase.Label; if (swlit != null && swlit.Value != null && lit.Value != null && !swlit.Value.Equals(lit.Value)) { this.HandleError(scase, Error.UnreachableCode); if (scase.Body != null && scase.Body.Statements != null && scase.Body.Statements.Count > 0 && scase.Body.Statements[scase.Body.Statements.Count-1] != null && scase.Body.Statements[scase.Body.Statements.Count-1].NodeType == NodeType.SwitchCaseBottom) scase.Body.Statements[scase.Body.Statements.Count-1] = null; scase.IsErroneous = true; } } scase.Label = lit; } } this.switchCaseCount++; for (int i = 0; i < n; i++) { SwitchCase scase = cases[i]; if (scase == null) continue; scase.Body = this.VisitBlock(scase.Body); } this.switchCaseCount--; this.currentSwitchCases = savedCases; this.currentSwitchGoverningType = savedGoverningType; return Switch; }
public virtual SwitchCaseList VisitSwitchCaseList(SwitchCaseList switchCases){ if (switchCases == null) return null; for (int i = 0, n = switchCases.Count; i < n; i++) switchCases[i] = this.Visit(switchCases[i]) as SwitchCase; return switchCases; }
public override SwitchCaseList VisitSwitchCaseList(SwitchCaseList switchCases) { throw new ApplicationException("unimplemented"); }
public virtual void VisitSwitchCaseList(SwitchCaseList switchCases) { if (switchCases == null) return; for (int i = 0, n = switchCases.Count; i < n; i++) this.Visit(switchCases[i]); }
public override SwitchCaseList VisitSwitchCaseList(SwitchCaseList switchCases) { if (switchCases == null) return null; return base.VisitSwitchCaseList(switchCases.Clone()); }
public virtual SwitchCaseList VisitSwitchCaseList(SwitchCaseList switchCases1, SwitchCaseList switchCases2) { if (switchCases1 == null) return null; for (int i = 0, n = switchCases1.Count, m = switchCases2 == null ? 0 : switchCases2.Count; i < n; i++) { //^ assert switchCases2 != null; if (i >= m) switchCases1[i] = this.VisitSwitchCase(switchCases1[i], null); else switchCases1[i] = this.VisitSwitchCase(switchCases1[i], switchCases2[i]); } return switchCases1; }
public Switch(Expression expression, SwitchCaseList cases) : base(NodeType.Switch) { this.Cases = cases; this.Expression = expression; }
public EventingVisitor(Action<SwitchCaseList> visitSwitchCaseList) { VisitedSwitchCaseList += visitSwitchCaseList; } public event Action<SwitchCaseList> VisitedSwitchCaseList; public override SwitchCaseList VisitSwitchCaseList(SwitchCaseList switchCases) { if (VisitedSwitchCaseList != null) VisitedSwitchCaseList(switchCases); return base.VisitSwitchCaseList(switchCases); }