public virtual void visit(IForeachNode value) { }
public override void visit(IForeachNode value) { VarInfo vi = helper.GetVariable(value.VarIdent); //Type interf = helper.GetTypeReference(value.InWhatExpr.type).tp; Type var_tp = helper.GetTypeReference(value.VarIdent.type).tp; //(ssyy) 12.04.2008 Поиск IEnumerable не нужен! Это дело семантики! Type in_what_type = helper.GetTypeReference(value.InWhatExpr.type).tp; Type return_type = null; bool is_generic = false; MethodInfo enumer_mi = null; //typeof(System.Collections.IEnumerable).GetMethod("GetEnumerator", Type.EmptyTypes); /*if (var_tp.IsValueType) { enumer_mi = helper.GetEnumeratorMethod(in_what_type); is_generic = enumer_mi.ReturnType.IsGenericType; return_type = enumer_mi.ReturnType; if (in_what_type.IsGenericType && return_type.IsGenericType && !return_type.IsGenericTypeDefinition) return_type = return_type.GetGenericTypeDefinition().MakeGenericType(in_what_type.GetGenericArguments()); else if (in_what_type.IsArray && return_type.IsGenericType && !return_type.IsGenericTypeDefinition) return_type = return_type.GetGenericTypeDefinition().MakeGenericType(in_what_type.GetElementType()); } else*/ { enumer_mi = typeof(System.Collections.IEnumerable).GetMethod("GetEnumerator", Type.EmptyTypes); return_type = enumer_mi.ReturnType; } LocalBuilder lb = il.DeclareLocal(return_type); //Label br_lbl = il.DefineLabel(); //Label cont_lbl = il.DefineLabel(); if (save_debug_info) lb.SetLocalSymInfo("$enumer$" + uid++); value.InWhatExpr.visit(this); il.Emit(OpCodes.Callvirt, enumer_mi); il.Emit(OpCodes.Stloc, lb); Label exl = il.BeginExceptionBlock(); Label l1 = il.DefineLabel(); Label l2 = il.DefineLabel(); Label leave_label = il.DefineLabel(); il.Emit(OpCodes.Br, l2); il.MarkLabel(l1); if (vi.kind == VarKind.vkNonLocal) il.Emit(OpCodes.Ldloc, (smi.Peek() as MethInfo).frame); if (lb.LocalType.IsValueType) il.Emit(OpCodes.Ldloca, lb); else il.Emit(OpCodes.Ldloc, lb); MethodInfo get_current_meth = enumer_mi.ReturnType.GetMethod("get_Current"); if (enumer_mi.ReturnType.IsGenericType && !enumer_mi.ReturnType.IsGenericTypeDefinition) { if (helper.IsConstructedGenericType(return_type)) get_current_meth = TypeBuilder.GetMethod(return_type, enumer_mi.ReturnType.GetGenericTypeDefinition().GetMethod("get_Current")); else get_current_meth = return_type.GetMethod("get_Current"); /*try { get_current_meth = TypeBuilder.GetMethod(return_type, enumer_mi.ReturnType.GetGenericTypeDefinition().GetMethod("get_Current")); } catch { get_current_meth = return_type.GetMethod("get_Current"); }*/ } il.Emit(OpCodes.Callvirt, get_current_meth); if (vi.kind == VarKind.vkLocal) { if (!lb.LocalType.IsValueType && (vi.lb.LocalType.IsValueType || vi.lb.LocalType.IsGenericParameter)) { //if (helper.GetTypeReference(value.InWhatExpr.type).is_set) if (!is_generic) emit_conversion(vi.lb.LocalType); else emit_numeric_conversion(vi.lb.LocalType, get_current_meth.ReturnType); //else //il.Emit(OpCodes.Unbox_Any, vi.lb.LocalType); } if (vi.lb.LocalType == TypeFactory.ObjectType && get_current_meth.ReturnType.IsValueType) il.Emit(OpCodes.Box, get_current_meth.ReturnType); il.Emit(OpCodes.Stloc, vi.lb); } else if (vi.kind == VarKind.vkGlobal) { if (!lb.LocalType.IsValueType && (vi.fb.FieldType.IsValueType || vi.fb.FieldType.IsGenericParameter)) { if (!is_generic) emit_conversion(vi.fb.FieldType); else emit_numeric_conversion(vi.fb.FieldType, get_current_meth.ReturnType); } if (vi.fb.FieldType == TypeFactory.ObjectType && get_current_meth.ReturnType.IsValueType) il.Emit(OpCodes.Box, get_current_meth.ReturnType); il.Emit(OpCodes.Stsfld, vi.fb); } else { if (!lb.LocalType.IsValueType && (vi.fb.FieldType.IsValueType || vi.fb.FieldType.IsGenericParameter)) { if (!is_generic) emit_conversion(vi.fb.FieldType); else emit_numeric_conversion(vi.fb.FieldType, get_current_meth.ReturnType); } if (vi.fb.FieldType == TypeFactory.ObjectType && get_current_meth.ReturnType.IsValueType) il.Emit(OpCodes.Box, get_current_meth.ReturnType); il.Emit(OpCodes.Stfld, vi.fb); } labels.Push(leave_label); clabels.Push(l2); ConvertStatement(value.Body); MarkSequencePoint(value.Location); il.MarkLabel(l2); if (lb.LocalType.IsValueType) il.Emit(OpCodes.Ldloca, lb); else il.Emit(OpCodes.Ldloc, lb); il.Emit(OpCodes.Callvirt, TypeFactory.IEnumeratorType.GetMethod("MoveNext", BindingFlags.Instance | BindingFlags.Public)); il.Emit(OpCodes.Brtrue, l1); //il.Emit(OpCodes.Leave, leave_label); il.BeginFinallyBlock(); //il.MarkLabel(br_lbl); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Stloc, lb); il.EndExceptionBlock(); il.MarkLabel(leave_label); }
public void visit(IForeachNode value) { string s = value.GetType().Name + "."; //prepare_node(value.Body, "IForeachNode.Body"); //prepare_node(value.InWhatExpr, "IForeachnode.InWhatExpr"); //prepare_node(value.VarIdent, "IForeachNode.VarIdent"); }
public void visit(IForeachNode value) { throw new System.NotSupportedException(value.GetType().ToString()); //prepare_node(value.Body, "IForeachNode.Body"); ? //prepare_node(value.InWhatExpr, "IForeachnode.InWhatExpr"); ? //prepare_node(value.VarIdent, "IForeachNode.VarIdent"); ? }