Example #1
0
 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;
 }
Example #4
0
 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;
 }
Example #5
0
 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");
 }
Example #7
0
 public virtual void VisitSwitchCaseList(SwitchCaseList switchCases)
 {
   if (switchCases == null) return;
   for (int i = 0, n = switchCases.Count; i < n; i++)
     this.Visit(switchCases[i]);
 }
Example #8
0
 public override SwitchCaseList VisitSwitchCaseList(SwitchCaseList switchCases)
 {
     if (switchCases == null) return null;
     return base.VisitSwitchCaseList(switchCases.Clone());
 }
Example #9
0
 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;
 }
Example #10
0
 public Switch(Expression expression, SwitchCaseList cases)
     : base(NodeType.Switch)
 {
     this.Cases = cases;
     this.Expression = expression;
 }
Example #11
0
 public override SwitchCaseList VisitSwitchCaseList(SwitchCaseList switchCases)
 {
     throw new ApplicationException("unimplemented");
 }
 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); }