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; }
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 Expression VisitConstructIterator(ConstructIterator consIterator){ return consIterator; }
public override Expression VisitConstructIterator(ConstructIterator consIterator) { throw new ApplicationException("unimplemented"); }
public override Expression VisitConstructIterator(ConstructIterator consIterator) { if (consIterator == null) return null; return base.VisitConstructIterator((ConstructIterator)consIterator.Clone()); }
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; }