public override void VisitDereferenceField(DereferenceField n) { _shouldLoadAddress = true; n.Object.Visit(this); _shouldLoadAddress = false; if (!Enum.GetNames(typeof(InternalTrancheTypes)).Contains(_lastWalkedType.Name)) { // this isn't a tranche type, have to handle it separately if (!n.IsLeftHandSide) _gen.Emit(OpCodes.Call, _lastWalkedType.GetMethod("get_"+n.Field)); else _assignmentCallback = gen => gen.Emit(OpCodes.Stfld, _lastWalkedType.GetMethod("set_"+n.Field)); _lastWalkedType = _lastWalkedType.GetProperty(n.Field).PropertyType; } else { var info = _typeManager.GetBuilderInfo(_lastWalkedType.Name); var field = info.FieldMap[n.Field]; _lastWalkedType = field.FieldType; var shouldbeStatic = Enum.GetNames(typeof (InternalTrancheTypes)).Contains(field.Name) || (field.DeclaringType != null && field.DeclaringType.Name == "Simulation"); //either have to load the field if getting, or store it if setting // depends on why we're dereferencing, to read or write if (!n.IsLeftHandSide) _gen.Emit(shouldbeStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, field); else _assignmentCallback = gen => gen.Emit(shouldbeStatic ? OpCodes.Stsfld : OpCodes.Stfld, field); } }
public override void VisitDereferenceField(DereferenceField n) { //lvalue.identifier var lhs = CheckSubTree(n.Object); if(!(lhs is TypeClass)) { var members = lhs.CilType.GetMembers(); var thisProperty = members.FirstOrDefault(p => p.Name.Equals(n.Field, StringComparison.OrdinalIgnoreCase)); if (thisProperty == null) throw new Exception(string.Format("Attribute {0} not available on type {1} (object {2})", n.Field, lhs.CilType, n.Object)); switch(lhs.CilType.GetProperty("Days").PropertyType.Name) { case "Int32": n.InternalType = _lastSeenType = new TypeInteger(); break; case "DateTime": n.InternalType = _lastSeenType = new TypeDate(); break; case "String": n.InternalType = _lastSeenType = new TypeString(); break; case "Double": n.InternalType = _lastSeenType = new TypeReal(); break; case "Boolean": n.InternalType = _lastSeenType = new TypeBoolean(); break; } } }