public virtual IDiagramShapeCollection AddCollection(IDiagramShapeCollection coll, bool reparentLinks) { foreach (DiagramShape obj1 in coll) { if (!base.IsChildOf(obj1) && (this != obj1)) { continue; } throw new ArgumentException("Cannot add a group to itself or to one of its own children."); } DiagramShapeCollection collection1 = new DiagramShapeCollection(); foreach (DiagramShape obj2 in coll) { collection1.Add(obj2); } CollectionEnumerator enumerator2 = collection1.GetEnumerator(); while (enumerator2.MoveNext()) { DiagramShape obj3 = enumerator2.Current; bool flag1 = obj3.Layer != null; if (flag1) { GroupShape.setAllNoClear(obj3, true); obj3.Remove(); } this.Add(obj3); if (flag1) { GroupShape.setAllNoClear(obj3, false); } } if (reparentLinks && base.IsInDocument) { SubGraphNode.ReparentAllLinksToSubGraphs(collection1, true, base.Document.LinksLayer); } return(collection1); }
public virtual CollectionEnumerator VisitCollectionEnumerator(CollectionEnumerator ce, CollectionEnumerator changes, CollectionEnumerator deletions, CollectionEnumerator insertions){ this.UpdateSourceContext(ce, changes); if (ce == null) return changes; if (changes != null){ if (deletions == null || insertions == null) Debug.Assert(false); else{ ce.Collection = this.VisitExpression(ce.Collection, changes.Collection, deletions.Collection, insertions.Collection); //REVIEW: update method bindings? } }else if (deletions != null) return null; return ce; }
public virtual Differences VisitCollectionEnumerator(CollectionEnumerator ce1, CollectionEnumerator ce2){ Differences differences = new Differences(ce1, ce2); if (ce1 == null || ce2 == null){ if (ce1 != ce2) differences.NumberOfDifferences++; else differences.NumberOfSimilarities++; return differences; } CollectionEnumerator changes = (CollectionEnumerator)ce2.Clone(); CollectionEnumerator deletions = (CollectionEnumerator)ce2.Clone(); CollectionEnumerator insertions = (CollectionEnumerator)ce2.Clone(); Differences diff = this.VisitExpression(ce1.Collection, ce2.Collection); if (diff == null){Debug.Assert(false); return differences;} changes.Collection = diff.Changes as Expression; deletions.Collection = diff.Deletions as Expression; insertions.Collection = diff.Insertions as Expression; Debug.Assert(diff.Changes == changes.Collection && diff.Deletions == deletions.Collection && diff.Insertions == insertions.Collection); 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 CollectionEnumerator VisitCollectionEnumerator(CollectionEnumerator ce){ if (ce == null) return null; ce.Collection = this.VisitExpression(ce.Collection); return ce; }
public virtual bool VisitEnumerablePointer(CollectionEnumerator result, TypeNode collectionType, Expression collection, TypeNode targetVariableType) { return false; }
public virtual void LookForEnumerablePattern(TypeNode type, CollectionEnumerator result) { if (type == null || result == null) return; //A type implements the Enumerable pattern if it implements a suitable GetEnumerator method Method getEnumerator = null; MemberList getEnumerators = this.GetTypeView(type).GetMembersNamed(StandardIds.GetEnumerator); for (int i = 0, n = getEnumerators == null ? 0 : getEnumerators.Count; i < n; i++) { Method getEnumeratorMeth = getEnumerators[i] as Method; if (getEnumeratorMeth == null || (getEnumeratorMeth.Parameters != null && getEnumeratorMeth.Parameters.Count != 0)) continue; result.GetEnumerator = getEnumeratorMeth; if (!this.NotAccessible(getEnumeratorMeth) && !getEnumeratorMeth.IsStatic && !(getEnumeratorMeth.ImplementedTypes != null && getEnumeratorMeth.ImplementedTypes.Count > 0)) { TypeNode t = TypeNode.StripModifiers(getEnumeratorMeth.ReturnType); this.LookForEnumeratorPattern(t, result); Method moveNext = result.MoveNext; Method getCurrent = result.GetCurrent; if (moveNext != null && !this.NotAccessible(moveNext) && moveNext.ReturnType == SystemTypes.Boolean && !moveNext.IsStatic && getCurrent != null && !this.NotAccessible(getCurrent) && getCurrent.IsSpecialName && !getCurrent.IsStatic) { getEnumerator = getEnumeratorMeth; if (i >= n-1 || getCurrent.ReturnType != SystemTypes.Object) return; } } else if (getEnumerator == null) getEnumerator = getEnumeratorMeth; //Method is no good, but remember because it might mask a base class method } //A type implements the Enumerable pattern if it implements IEnumerable<T> or IEnumerable InterfaceList interfaces = this.GetTypeView(type).Interfaces; Interface enumerable = null; for (int i = 0, n = interfaces == null ? 0 : interfaces.Count; i < n; i++) { Interface iface = interfaces[i]; if (iface == null) continue; if (iface.Template == SystemTypes.GenericIEnumerable) { enumerable = iface; break; } if (iface == SystemTypes.IEnumerable) enumerable = iface; //Keep looking for a typed IEnumerable } if (enumerable != null) { Method getEnumeratorMeth = result.GetEnumerator = this.GetTypeView(enumerable).GetMethod(StandardIds.GetEnumerator); Debug.Assert(result.GetEnumerator != null); this.LookForEnumeratorPattern(TypeNode.StripModifiers(getEnumeratorMeth.ReturnType), result); //Guaranteed to work Debug.Assert(result.MoveNext != null); Debug.Assert(result.GetCurrent != null && result.GetCurrent.IsSpecialName); return; } //See if any inherited interface implements the pattern for (int i = 0, n = interfaces == null ? 0 : interfaces.Count; i < n; i++) { Interface iface = interfaces[i]; if (iface == null) continue; this.LookForEnumerablePattern(iface, result); if (result.GetEnumerator != null) return; } if (getEnumerator != null && !(getEnumerator.ImplementedTypes != null && getEnumerator.ImplementedTypes.Count > 0)) return; //Any good GetEnumerator on the base type is hidden, so give up. Class cl = type as Class; if (cl != null) this.LookForEnumerablePattern(cl.BaseClass, result); }
public virtual void LookForEnumeratorPattern(TypeNode type, CollectionEnumerator result) { if (type == null || result == null) return; //A type implements the Enumerator pattern if it implements a suitable MoveNext method and Current property Method moveNext = LookupMethod(type, StandardIds.MoveNext); if (moveNext != null) result.MoveNext = moveNext; Method getCurrent = LookupMethod(type, StandardIds.getCurrent); if (getCurrent != null) result.GetCurrent = getCurrent; if (moveNext != null && !this.NotAccessible(moveNext) && moveNext.ReturnType == SystemTypes.Boolean && !moveNext.IsStatic && getCurrent != null && !this.NotAccessible(getCurrent) && getCurrent.IsSpecialName && !getCurrent.IsStatic) { return; } //A type implements the Enumerator pattern if it implements IEnumerator<T> or IEnumerator InterfaceList interfaces = this.GetTypeView(type).Interfaces; Interface typedEnumerator = null; Interface untypedEnumerator = null; for (int i = 0, n = interfaces == null ? 0 : interfaces.Count; i < n; i++) { Interface iface = interfaces[i]; if (iface == null) continue; if (iface.Template == SystemTypes.GenericIEnumerator) typedEnumerator = iface; if (iface == SystemTypes.IEnumerator) untypedEnumerator = iface; } if (typedEnumerator != null) { result.MoveNext = this.GetTypeView(typedEnumerator).GetMethod(StandardIds.MoveNext); if (untypedEnumerator == null && result.MoveNext == null) untypedEnumerator = SystemTypes.IEnumerator; result.GetCurrent = this.GetTypeView(typedEnumerator).GetMethod(StandardIds.getCurrent); Debug.Assert(result.MoveNext != null); Debug.Assert(result.GetCurrent != null && result.GetCurrent.IsSpecialName); return; } if (untypedEnumerator != null && result.MoveNext == null) result.MoveNext = this.GetTypeView(untypedEnumerator).GetMethod(StandardIds.MoveNext); Class cl = type as Class; if (cl != null) this.LookForEnumeratorPattern(cl.BaseClass, result); //TODO: what if the base class implements only one part of the pattern? }
public virtual CollectionEnumerator VisitEnumerableCollection(Expression collection, TypeNode targetVariableType) { if (collection == null) return null; collection = this.VisitExpression(collection); if (collection == null) return null; TypeNode collectionType = TypeNode.StripModifier(collection.Type, SystemTypes.NonNullType); if (collectionType == null) return null; while (collectionType is TypeAlias) { //HACK collectionType = ((TypeAlias)collectionType).AliasedType; collection = this.typeSystem.ExplicitCoercion(collection, collectionType, this.TypeViewer); collectionType = TypeNode.StripModifiers(collection.Type); } CollectionEnumerator result = new CollectionEnumerator(); result.Collection = collection; result.SourceContext = collection.SourceContext; TypeNode ctype = collectionType; Reference r = collectionType as Reference; if (r != null) { ctype = TypeNode.StripModifiers(r.ElementType); result.Collection = this.typeSystem.AutoDereferenceCoercion(result.Collection); } //Special case for arrays ArrayType arrayType = ctype as ArrayType; if (arrayType != null && arrayType.IsSzArray()) { result.ElementLocal = new Local(Identifier.Empty, arrayType.ElementType, collection.SourceContext); result.ElementCoercion = this.typeSystem.ExplicitCoercion(result.ElementLocal, targetVariableType, this.TypeViewer); if (result.ElementCoercion == null) return null; return result; } //Special case for pointers if (ctype.IsPointerType) { if (this.VisitEnumerablePointer(result, ctype, collection, targetVariableType)) return result; } //Look for Enumerable pattern. If not present, look for Enumerator pattern. this.LookForEnumerablePattern(ctype, result); Method getEnumerator = result.GetEnumerator; if (getEnumerator == null) this.LookForEnumeratorPattern(ctype, result); else { TypeNode enumeratorType = getEnumerator.ReturnType; enumeratorType = TypeNode.StripModifiers(enumeratorType); if (!(enumeratorType is Class || enumeratorType is Struct || enumeratorType is Interface)) { this.HandleError(collection, Error.BadGetEnumerator, this.GetTypeName(enumeratorType)); return null; } } Method moveNext = result.MoveNext; Method getCurrent = result.GetCurrent; if (this.NotAccessible(getEnumerator) || (getEnumerator == null && (moveNext == null || getCurrent == null))) { if (collection.Type == SystemTypes.Object && collection is Literal && ((Literal)collection).Value == null) this.HandleError(collection, Error.NullNotAllowed); else this.HandleError(collection, Error.BadForeachCollection, this.GetTypeName(ctype), this.GetTypeName(ctype), "GetEnumerator"); return null; } if (getCurrent == null || this.NotAccessible(getCurrent) || !getCurrent.IsSpecialName || getCurrent.IsStatic) { this.HandleError(collection, Error.BadForeachCollection, this.GetTypeName(ctype), getCurrent == null ? this.GetTypeName(getEnumerator.ReturnType) : this.GetTypeName(getCurrent.DeclaringType), "Current"); return null; } if (moveNext == null || this.NotAccessible(moveNext) || moveNext.ReturnType != SystemTypes.Boolean || moveNext.IsStatic) { this.HandleError(collection, Error.BadForeachCollection, this.GetTypeName(ctype), moveNext == null ? this.GetTypeName(getEnumerator.ReturnType) : this.GetTypeName(moveNext.DeclaringType), "MoveNext"); return null; } result.ElementLocal = new Local(Identifier.Empty, getCurrent.ReturnType); result.ElementLocal.SourceContext = collection.SourceContext; Expression elementLocalExp = result.ElementLocal; if (targetVariableType.IsValueType && getCurrent.ReturnType == SystemTypes.Object) { // add explicit cast to non-null elementLocalExp = this.typeSystem.ExplicitNonNullCoercion(elementLocalExp, OptionalModifier.For(SystemTypes.NonNullType, getCurrent.ReturnType)); } result.ElementCoercion = this.typeSystem.ExplicitCoercion(elementLocalExp, targetVariableType, this.TypeViewer); if (result.ElementCoercion == null) return null; return result; }
public bool HasEnumerablePattern(TypeNode Type) { CollectionEnumerator result = new CollectionEnumerator(); this.LookForEnumerablePattern(Type, result); Method getEnumerator = result.GetEnumerator; if (getEnumerator == null) this.LookForEnumeratorPattern(Type, result); else { TypeNode enumeratorType = getEnumerator.ReturnType; enumeratorType = TypeNode.StripModifiers(enumeratorType); if (!(enumeratorType is Class || enumeratorType is Struct || enumeratorType is Interface)) return false; } Method moveNext = result.MoveNext; Method getCurrent = result.GetCurrent; if (this.NotAccessible(getEnumerator) || (getEnumerator == null && (moveNext == null || getCurrent == null))) return false; if (getCurrent == null || this.NotAccessible(getCurrent) || !getCurrent.IsSpecialName || getCurrent.IsStatic) return false; if (moveNext == null || this.NotAccessible(moveNext) || moveNext.ReturnType != SystemTypes.Boolean || moveNext.IsStatic) return false; return true; }
public virtual void VisitCollectionEnumerator(CollectionEnumerator ce) { if (ce == null) return; this.VisitExpression(ce.Collection); }
public override CollectionEnumerator VisitCollectionEnumerator(CollectionEnumerator ce) { if (ce == null) return null; return base.VisitCollectionEnumerator((CollectionEnumerator)ce.Clone()); }
public virtual CollectionEnumerator VisitCollectionEnumerator(CollectionEnumerator ce1, CollectionEnumerator ce2) { if (ce1 == null) return null; if (ce2 == null) ce1.Collection = this.VisitExpression(ce1.Collection, null); else ce1.Collection = this.VisitExpression(ce1.Collection, ce2.Collection); return ce1; }
protected virtual TypeNode ForeachArrayElementType(CollectionEnumerator cenum) { ArrayType arrType = this.typeSystem.GetUnderlyingType(cenum.Collection.Type) as ArrayType; if (arrType != null && arrType.IsSzArray()) { return this.typeSystem.GetUnderlyingType(arrType.ElementType); } return null; }