private ILCodeParameter GenerateCollectionContent(ExtendedType target, string refName) { var collectionMembers = new CollectionMembers(target); var isValueType = collectionMembers.ElementType.IsValueType; var collectionLocal = _il.DeclareLocal("collection", collectionMembers.VariableType); _il.Construct(collectionMembers.Constructor); _il.Cast(collectionMembers.VariableType); _il.Var.Set(collectionLocal); var valueLocal = DeclareCollectionItemLocal("cv", collectionMembers.ElementType); ; if (collectionMembers.ElementTypeExt.IsValueOrNullableOfValue()) { _il.Snippets.WhileLoop(il => { // While condition _il.Snippets.InvokeMethod(_visitorVariable, Members.VisitorTryVisitValue[collectionMembers.ElementType], Members.VisitArgsCollectionItem, valueLocal); var valueNotFoundLabel = _il.DefineLabel(); _il.TransferLongIfFalse(valueNotFoundLabel); if (isValueType) { _il.Snippets.InvokeMethod(valueLocal, Members.Nullable[collectionMembers.ElementType].GetHasValue); } else { _il.Snippets.AreEqual(valueLocal, ILCodeParameter.Null); _il.Negate(); } var isNullLabel = _il.DefineLabel(); _il.TransferLong(isNullLabel); _il.MarkLabel(valueNotFoundLabel); _il.LoadValue(0); _il.MarkLabel(isNullLabel); }, il => { _il.Var.Load(collectionLocal); GenerateLoadParamValueCode(valueLocal); _il.CallVirt(collectionMembers.Add); }); } else if (collectionMembers.ElementTypeExt.Class == TypeClass.Dictionary) { _il.Snippets.WhileLoop(il => { // Condition var callTryVisit = new CallMethodILCode(_visitorVariable, Members.VisitorTryVisit, Members.VisitArgsDictionaryInCollection); _il.Snippets.AreEqual(callTryVisit, (int)ValueState.Found); }, il => { var contentParam = GenerateDictionaryEnumerateCode(collectionMembers.ElementType, refName); _il.Snippets.InvokeMethod(_visitorVariable, Members.VisitorLeave, Members.VisitArgsDictionaryInCollection); _il.Snippets.InvokeMethod(collectionLocal, collectionMembers.Add, contentParam); }); } else if (collectionMembers.ElementTypeExt.Class == TypeClass.Collection) { _il.Snippets.WhileLoop(il => { // Condition var callTryVisit = new CallMethodILCode(_visitorVariable, Members.VisitorTryVisit, Members.VisitArgsCollectionInCollection); _il.Snippets.AreEqual(callTryVisit, (int)ValueState.Found); }, il => { var contentParam = GenerateCollectionContent(collectionMembers.ElementTypeExt, refName); _il.Snippets.InvokeMethod(_visitorVariable, Members.VisitorLeave, Members.VisitArgsCollectionInCollection); _il.Snippets.InvokeMethod(collectionLocal, collectionMembers.Add, contentParam); }); } else { _il.Snippets.WhileLoop(il => { var callTryVisit = new CallMethodILCode(_visitorVariable, Members.VisitorTryVisit, Members.VisitArgsCollectionItem); _il.Snippets.AreEqual(callTryVisit, (int)ValueState.Found); }, il => { GenerateCreateAndChildCallCode(valueLocal); _il.Snippets.InvokeMethod(_visitorVariable, Members.VisitorLeave, Members.VisitArgsCollectionItem); _il.Snippets.InvokeMethod(collectionLocal, collectionMembers.Add, valueLocal); }); } if (target.Ref.IsArray) return new CallMethodILCode(collectionMembers.ToArray, collectionLocal); return collectionLocal; }
private ILPointer GenerateCollectionContent(ExtendedType target, string refName) { var collectionMembers = new CollectionMembers(target); var isValueType = collectionMembers.ElementType.GetTypeInfo().IsValueType; var collectionLocal = _il.NewLocal(collectionMembers.VariableType); var collection = ILPointer.New(collectionMembers.Constructor) .Cast(collectionMembers.VariableType); _il.Set(collectionLocal, collection); var valueLocal = DeclareCollectionItemLocal(collectionMembers.ElementType);; if (collectionMembers.ElementTypeExt.IsValueOrNullableOfValue()) { _il.WhileLoop(il => { // While condition _il.InvokeMethod(_visitorVariable, Members.VisitorTryVisitValue[collectionMembers.ElementType], Members.VisitArgsCollectionItem, valueLocal); var valueNotFoundLabel = _il.NewLabel(); valueNotFoundLabel.TransferLongIfFalse(); if (isValueType) { _il.InvokeMethod(valueLocal, Members.Nullable[collectionMembers.ElementType].GetHasValue); } else { _il.AreEqual(valueLocal, ILPointer.Null); _il.Negate(); } var isNullLabel = _il.NewLabel(); isNullLabel.TransferLong(); valueNotFoundLabel.Mark(); _il.Load(0); isNullLabel.Mark(); }, il => { _il.Load(collectionLocal); GenerateLoadParamValueCode(valueLocal); _il.EmitCall(OpCodes.Callvirt, collectionMembers.Add, null); }); } else if (collectionMembers.ElementTypeExt.Classification == TypeClassification.Dictionary) { _il.WhileLoop(il => { // Condition var callTryVisit = new ILCallMethodSnippet(_visitorVariable, Members.VisitorTryVisit, Members.VisitArgsDictionaryInCollection); _il.AreEqual(callTryVisit, (int)ValueState.Found); }, il => { var contentParam = GenerateDictionaryEnumerateCode(collectionMembers.ElementType, refName); _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, Members.VisitArgsDictionaryInCollection); _il.InvokeMethod(collectionLocal, collectionMembers.Add, contentParam); }); } else if (collectionMembers.ElementTypeExt.Classification == TypeClassification.Collection) { _il.WhileLoop(il => { // Condition var callTryVisit = new ILCallMethodSnippet(_visitorVariable, Members.VisitorTryVisit, Members.VisitArgsCollectionInCollection); _il.AreEqual(callTryVisit, (int)ValueState.Found); }, il => { var contentParam = GenerateCollectionContent(collectionMembers.ElementTypeExt, refName); _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, Members.VisitArgsCollectionInCollection); _il.InvokeMethod(collectionLocal, collectionMembers.Add, contentParam); }); } else { _il.WhileLoop(il => { var callTryVisit = new ILCallMethodSnippet(_visitorVariable, Members.VisitorTryVisit, Members.VisitArgsCollectionItem); _il.AreEqual(callTryVisit, (int)ValueState.Found); }, il => { GenerateCreateAndChildCallCode(valueLocal); _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, Members.VisitArgsCollectionItem); _il.InvokeMethod(collectionLocal, collectionMembers.Add, valueLocal); }); } if (target.Ref.IsArray) { return(new ILCallMethodSnippet(collectionMembers.ToArray, collectionLocal)); } return(collectionLocal); }