示例#1
0
 public virtual Expression VisitConstructIterator(ConstructIterator consIterator, ConstructIterator changes, ConstructIterator deletions, ConstructIterator insertions){
   this.UpdateSourceContext(consIterator, changes);
   if (consIterator == null) return changes;
   if (changes != null){
     if (deletions == null || insertions == null)
       Debug.Assert(false);
     else{
       consIterator.Body = this.VisitBlock(consIterator.Body, changes.Body, deletions.Body, insertions.Body);
       consIterator.ElementType = this.VisitTypeReference(consIterator.ElementType, changes.ElementType); 
       consIterator.State = this.VisitClass(consIterator.State, changes.State, deletions.State, insertions.State);
     }
   }else if (deletions != null)
     return null;
   return consIterator;
 }
    public virtual Differences VisitConstructIterator(ConstructIterator consIterator1, ConstructIterator consIterator2){
      Differences differences = new Differences(consIterator1, consIterator2);
      if (consIterator1 == null || consIterator2 == null){
        if (consIterator1 != consIterator2) differences.NumberOfDifferences++; else differences.NumberOfSimilarities++;
        return differences;
      }
      ConstructIterator changes = (ConstructIterator)consIterator2.Clone();
      ConstructIterator deletions = (ConstructIterator)consIterator2.Clone();
      ConstructIterator insertions = (ConstructIterator)consIterator2.Clone();

      Differences diff = this.VisitBlock(consIterator1.Body, consIterator2.Body);
      if (diff == null){Debug.Assert(false); return differences;}
      changes.Body = diff.Changes as Block;
      deletions.Body = diff.Deletions as Block;
      insertions.Body = diff.Insertions as Block;
      Debug.Assert(diff.Changes == changes.Body && diff.Deletions == deletions.Body && diff.Insertions == insertions.Body);
      differences.NumberOfDifferences += diff.NumberOfDifferences;
      differences.NumberOfSimilarities += diff.NumberOfSimilarities;

      diff = this.VisitTypeNode(consIterator1.ElementType, consIterator2.ElementType);
      if (diff == null){Debug.Assert(false); return differences;}
      changes.ElementType = diff.Changes as TypeNode;
      deletions.ElementType = diff.Deletions as TypeNode;
      insertions.ElementType = diff.Insertions as TypeNode;
      //Debug.Assert(diff.Changes == changes.ElementType && diff.Deletions == deletions.ElementType && diff.Insertions == insertions.ElementType);
      differences.NumberOfDifferences += diff.NumberOfDifferences;
      differences.NumberOfSimilarities += diff.NumberOfSimilarities;

      diff = this.VisitClass(consIterator1.State, consIterator2.State);
      if (diff == null){Debug.Assert(false); return differences;}
      changes.State = diff.Changes as Class;
      deletions.State = diff.Deletions as Class;
      insertions.State = diff.Insertions as Class;
      //Debug.Assert(diff.Changes == changes.State && diff.Deletions == deletions.State && diff.Insertions == insertions.State);
      differences.NumberOfDifferences += diff.NumberOfDifferences;
      differences.NumberOfSimilarities += diff.NumberOfSimilarities;

      if (differences.NumberOfDifferences == 0){
        differences.Changes = null;
        differences.Deletions = null;
        differences.Insertions = null;
      }else{
        differences.Changes = changes;
        differences.Deletions = deletions;
        differences.Insertions = insertions;
      }
      return differences;
    }
示例#3
0
 public virtual Expression VisitConstructIterator(ConstructIterator consIterator){
   return consIterator;
 }
 public override Expression VisitConstructIterator(ConstructIterator consIterator)
 {
   throw new ApplicationException("unimplemented");
 }
示例#5
0
 public override Expression VisitConstructIterator(ConstructIterator consIterator)
 {
     if (consIterator == null) return null;
     return base.VisitConstructIterator((ConstructIterator)consIterator.Clone());
 }
示例#6
0
 public override Expression VisitConstructIterator(ConstructIterator consIterator){
   if (consIterator == null) return null;
   Field savedCurrValue = this.currentIteratorValue;
   Field savedCurrEntryPoint = this.currentIteratorEntryPoint;
   BlockList savedEntryPoints = this.iteratorEntryPoints;
   this.iteratorEntryPoints = new BlockList();
   Class state = consIterator.State;
   state.Flags &= ~TypeFlags.Abstract;
   //this.ClosureClasses[state.UniqueKey] = state;
   //Field for current value
   TypeNode elementType = this.currentMethod.Scope.FixTypeReference(consIterator.ElementType);
   Field currValue = this.currentIteratorValue = new Field(state, null, FieldFlags.Private, Normalizer.IteratorCurrentValue, elementType, null);
   state.Members.Add(currValue);
   //Field for current entrypoint
   Field currEntryPoint = this.currentIteratorEntryPoint = new Field(state, null, FieldFlags.Private, Normalizer.IteratorCurrentEntryPont, SystemTypes.Int32, null);
   state.Members.Add(currEntryPoint);
   //MoveNext
   This ThisParameter = new This(state);
   StatementList statements = new StatementList(4);
   Local savedCurrentClosureLocal = this.currentClosureLocal;
   this.currentClosureLocal = new Local(savedCurrentClosureLocal.Name, state);
   if (state.TemplateParameters != null && state.TemplateParameters.Count > 0)
     this.currentClosureLocal.Type = state.GetTemplateInstance(this.currentType, state.TemplateParameters);
   AssignmentStatement init = new AssignmentStatement(this.currentClosureLocal, ThisParameter);
   init.SourceContext = consIterator.Body.SourceContext;
   init.SourceContext.EndPos = consIterator.Body.SourceContext.StartPos;
   statements.Add(init);
   statements.Add(new SwitchInstruction(new MemberBinding(ThisParameter, this.currentIteratorEntryPoint), this.iteratorEntryPoints));
   this.iteratorEntryPoints.Add(consIterator.Body);
   Local savedCurrentReturnLocal = this.currentReturnLocal;
   this.currentReturnLocal = new Local(SystemTypes.Boolean);
   Block savedCurrentReturnLabel = this.currentReturnLabel;
   this.currentReturnLabel = new Block();
   This savedCurrentThisParameter = this.currentThisParameter;
   this.currentThisParameter = ThisParameter;
   statements.Add(this.VisitBlock(consIterator.Body));
   Expression index = new Literal(this.iteratorEntryPoints.Count, SystemTypes.Int32);
   statements.Add(new AssignmentStatement(new MemberBinding(this.currentThisParameter, this.currentIteratorEntryPoint), index));
   Block b = new Block(new StatementList(0));
   statements.Add(b);
   this.iteratorEntryPoints.Add(b);
   this.currentThisParameter = savedCurrentThisParameter;
   statements.Add(new AssignmentStatement(this.currentReturnLocal, new Literal(false, SystemTypes.Boolean)));
   statements.Add(this.currentReturnLabel);
   Return ret = new Return(this.currentReturnLocal);
   ret.SourceContext = consIterator.SourceContext;
   ret.SourceContext.StartPos = consIterator.SourceContext.EndPos-1;
   statements.Add(ret);
   Method moveNext = (Method)state.GetMembersNamed(StandardIds.MoveNext)[0];
   moveNext.ThisParameter = ThisParameter;
   moveNext.Body = new Block(statements);
   moveNext.Body.HasLocals = true;
   moveNext.ExceptionHandlers = this.currentMethod.ExceptionHandlers;
   this.currentMethod.ExceptionHandlers = null;
   //IDispose.Dispose
   statements = new StatementList(1);
   statements.Add(new Return());
   Method dispose = new Method(state, null, StandardIds.Dispose, null, SystemTypes.Void, new Block(statements));
   dispose.CallingConvention = CallingConventionFlags.HasThis;
   dispose.Flags = MethodFlags.Public|MethodFlags.Virtual;
   state.Members.Add(dispose);
   //IEnumerator.Reset
   statements = new StatementList(1);
   statements.Add(new Return()); //TODO: throw exception
   Method reset = new Method(state, null, StandardIds.Reset, null, SystemTypes.Void, new Block(statements));
   reset.CallingConvention = CallingConventionFlags.HasThis;
   reset.Flags = MethodFlags.Public|MethodFlags.Virtual;
   state.Members.Add(reset);
   //IEnumerator.GetCurrent
   statements = new StatementList(1);
   ThisParameter = new This(state);
   Expression currVal = new MemberBinding(ThisParameter, currValue);    
   switch (elementType.NodeType){
     case NodeType.TypeIntersection:
       currVal = this.typeSystem.CoerceTypeIntersectionToObject(currVal, this.TypeViewer);
       break;
     case NodeType.TypeUnion:
       currVal = this.typeSystem.CoerceTypeUnionToObject(currVal, this.TypeViewer);
       break;
     default:
       if (elementType.IsValueType || (elementType.IsTemplateParameter && this.useGenerics))
         currVal = new BinaryExpression(currVal, new MemberBinding(null, elementType), NodeType.Box, SystemTypes.Object);
       break;
   }
   statements.Add(new Return(currVal));
   Method ieGetCurrent = new Method(state, null, StandardIds.IEnumeratorGetCurrent, null, SystemTypes.Object, new Block(statements));
   ieGetCurrent.ThisParameter = ThisParameter;
   ieGetCurrent.ImplementedInterfaceMethods = new MethodList(Runtime.GetCurrent);
   ieGetCurrent.CallingConvention = CallingConventionFlags.HasThis;
   ieGetCurrent.Flags = MethodFlags.Private|MethodFlags.Virtual|MethodFlags.SpecialName;
   state.Members.Add(ieGetCurrent);
   //get_Current
   //TODO: need to check if MoveNext has been called and did not return false
   statements = new StatementList(1);
   ThisParameter = new This(state);
   statements.Add(new Return(new MemberBinding(ThisParameter, currValue)));
   Method getCurrent = (Method)state.GetMembersNamed(StandardIds.getCurrent)[0];
   getCurrent.ThisParameter = ThisParameter;
   getCurrent.Body = new Block(statements);
   //Current
   Property prop = new Property(state, null, PropertyFlags.None, StandardIds.Current, getCurrent, null);
   state.Members.Add(prop);
   //GetEnumerator
   statements = new StatementList(1);
   ThisParameter = new This(state);
   statements.Add(new Return(new BinaryExpression(new MethodCall(new MemberBinding(ThisParameter, Runtime.MemberwiseClone), null),
     new Literal(state,SystemTypes.Type), NodeType.Castclass)));
   Method getEnumerator = new Method(state, null, StandardIds.GetEnumerator, null, state.Interfaces[1], new Block(statements));
   getEnumerator.ThisParameter = ThisParameter;
   getEnumerator.CallingConvention = CallingConventionFlags.HasThis;
   getEnumerator.Flags = MethodFlags.Public|MethodFlags.Virtual;
   state.Members.Add(getEnumerator);
   //IEnumerable.GetEnumerator
   statements = new StatementList(1);
   ThisParameter = new This(state);
   statements.Add(new Return(new BinaryExpression(new MethodCall(new MemberBinding(ThisParameter, Runtime.MemberwiseClone), null),
     new Literal(state,SystemTypes.Type), NodeType.Castclass)));
   getEnumerator = new Method(state, null, StandardIds.IEnumerableGetEnumerator, null, SystemTypes.IEnumerator, new Block(statements));
   getEnumerator.ThisParameter = ThisParameter;
   getEnumerator.ImplementedInterfaceMethods = new MethodList(Runtime.GetEnumerator);
   getEnumerator.CallingConvention = CallingConventionFlags.HasThis;
   getEnumerator.Flags = MethodFlags.Private|MethodFlags.Virtual|MethodFlags.SpecialName;
   state.Members.Add(getEnumerator);
   if (this.currentClosureLocal != null && this.currentClosureLocal.Type != null && this.currentClosureLocal.Type.Template == state) {
     TypeNode stateInstance = this.currentClosureLocal.Type;
     MemberList members = stateInstance.Members;
     stateInstance.Members = null; //Force specialization of new members
     MemberList newMembers = stateInstance.Members;
     for (int i = 0, n = members.Count; i < n; i++){
       Member oldMember = members[i];
       for (int j = 0, m = newMembers.Count; j < m; j++ ) {
         if (oldMember.Name.UniqueIdKey == newMembers[j].Name.UniqueIdKey) {
           newMembers[j] = oldMember;
           break;
         }
       }
     }
   }
   //exit iteration scope & return
   this.currentClosureLocal = savedCurrentClosureLocal;
   this.currentReturnLabel = savedCurrentReturnLabel;
   this.currentReturnLocal = savedCurrentReturnLocal;
   this.currentIteratorValue = savedCurrValue;
   this.currentIteratorEntryPoint = savedCurrEntryPoint;
   this.iteratorEntryPoints = savedEntryPoints;
   return this.currentClosureLocal;
 }