VariableDefinition AddNullableProperty(PropertyDefinition property, Collection <Instruction> ins, TypeDefinition type, VariableDefinition variable) { var getMethod = ModuleDefinition.ImportReference(property.GetGetMethod(type)); ins.If(c => { var nullablePropertyResolved = property.PropertyType.Resolve(); var nullablePropertyImported = ModuleDefinition.ImportReference(property.PropertyType); ins.Add(Instruction.Create(OpCodes.Ldarg_0)); c.Add(Instruction.Create(OpCodes.Call, getMethod)); variable = new VariableDefinition(getMethod.ReturnType); c.Add(Instruction.Create(OpCodes.Stloc, variable)); c.Add(Instruction.Create(OpCodes.Ldloca, variable)); var hasValuePropertyResolved = nullablePropertyResolved.Properties.First(x => x.Name == "HasValue").Resolve(); var hasMethod = ModuleDefinition.ImportReference(hasValuePropertyResolved.GetGetMethod(nullablePropertyImported)); c.Add(Instruction.Create(OpCodes.Call, hasMethod)); }, t => { var nullableProperty = ModuleDefinition.ImportReference(property.PropertyType); t.Add(Instruction.Create(OpCodes.Ldarg_0)); var imp = property.GetGetMethod(type); var imp2 = ModuleDefinition.ImportReference(imp); t.Add(Instruction.Create(OpCodes.Call, imp2)); t.Add(Instruction.Create(OpCodes.Box, nullableProperty)); t.Add(Instruction.Create(OpCodes.Callvirt, GetHashcode)); }, e => e.Add(Instruction.Create(OpCodes.Ldc_I4_0))); return(variable); }
static void AddCollectionEquals(TypeDefinition type, MethodDefinition collectionEquals, PropertyDefinition property, TypeDefinition propType, Collection <Instruction> e, ParameterDefinition left, ParameterDefinition right) { e.If( cf => { cf.Add(Instruction.Create(type.GetLdArgForType(), right)); cf.Add(Instruction.Create(OpCodes.Ldnull)); cf.Add(Instruction.Create(OpCodes.Ceq)); }, t => t.Add(Instruction.Create(OpCodes.Ldc_I4_0)), es => { var getMethod = property.GetGetMethod(type); var getMethodImported = ReferenceFinder.ImportCustom(getMethod); es.Add(Instruction.Create(type.GetLdArgForType(), left)); es.Add(Instruction.Create(getMethodImported.GetCallForMethod(), getMethodImported)); if (propType.IsValueType && !property.PropertyType.IsArray) { es.Add(Instruction.Create(OpCodes.Box, propType)); } es.Add(Instruction.Create(type.GetLdArgForType(), right)); es.Add(Instruction.Create(getMethodImported.GetCallForMethod(), getMethodImported)); if (propType.IsValueType && !property.PropertyType.IsArray) { es.Add(Instruction.Create(OpCodes.Box, propType)); } es.Add(Instruction.Create(OpCodes.Call, collectionEquals)); }); }
void LoadVariable(PropertyDefinition property, Collection <Instruction> ins, TypeDefinition type) { var get = property.GetGetMethod(type); var imported = ModuleDefinition.ImportReference(get); ins.Add(Instruction.Create(OpCodes.Ldarg_0)); ins.Add(Instruction.Create(OpCodes.Call, imported)); }
void AddSimpleValueCheck(Collection <Instruction> c, PropertyDefinition property, TypeDefinition type, ParameterDefinition left, ParameterDefinition right) { var getMethod = property.GetGetMethod(type); var getMethodImported = ModuleDefinition.ImportReference(getMethod); c.Add(Instruction.Create(type.GetLdArgForType(), left)); c.Add(Instruction.Create(getMethodImported.GetCallForMethod(), getMethodImported)); c.Add(Instruction.Create(type.GetLdArgForType(), right)); c.Add(Instruction.Create(getMethodImported.GetCallForMethod(), getMethodImported)); c.Add(Instruction.Create(OpCodes.Ceq)); }
static void AddNormalCheck(TypeDefinition type, Collection <Instruction> c, PropertyDefinition property, ParameterDefinition left, ParameterDefinition right) { var genericInstance = new Lazy <TypeReference>(() => ReferenceFinder.ImportCustom(property.PropertyType.GetGenericInstanceType(type))); var getMethodImported = ReferenceFinder.ImportCustom(property.GetGetMethod(type)); c.Add(Instruction.Create(type.GetLdArgForType(), left)); c.Add(Instruction.Create(getMethodImported.GetCallForMethod(), getMethodImported)); if (property.PropertyType.IsValueType || property.PropertyType.IsGenericParameter) { c.Add(Instruction.Create(OpCodes.Box, genericInstance.Value)); } c.Add(Instruction.Create(type.GetLdArgForType(), right)); c.Add(Instruction.Create(getMethodImported.GetCallForMethod(), getMethodImported)); if (property.PropertyType.IsValueType || property.PropertyType.IsGenericParameter) { c.Add(Instruction.Create(OpCodes.Box, genericInstance.Value)); } c.Add(Instruction.Create(OpCodes.Call, ReferenceFinder.Object.StaticEquals)); }
void AddCollectionCall(TypeDefinition type, MethodDefinition collectionEquals, PropertyDefinition property, TypeReference propType, ParameterDefinition left, ParameterDefinition right, Collection <Instruction> es) { var getMethod = property.GetGetMethod(type); var getMethodImported = ModuleDefinition.ImportReference(getMethod); es.Add(Instruction.Create(type.GetLdArgForType(), left)); es.Add(Instruction.Create(getMethodImported.GetCallForMethod(), getMethodImported)); if (propType.IsValueType && !property.PropertyType.IsArray) { var imported = ModuleDefinition.ImportReference(property.PropertyType); es.Add(Instruction.Create(OpCodes.Box, imported)); } es.Add(Instruction.Create(type.GetLdArgForType(), right)); es.Add(Instruction.Create(getMethodImported.GetCallForMethod(), getMethodImported)); if (propType.IsValueType && !property.PropertyType.IsArray) { var imported = ModuleDefinition.ImportReference(property.PropertyType); es.Add(Instruction.Create(OpCodes.Box, imported)); } es.Add(Instruction.Create(OpCodes.Call, collectionEquals)); }
void AddPropertyCode(MethodBody body, int index, PropertyDefinition property, TypeDefinition targetType, Collection <VariableDefinition> variables) { var ins = body.Instructions; ins.Add(Instruction.Create(OpCodes.Ldloc_0)); ins.Add(Instruction.Create(OpCodes.Ldc_I4, index)); var get = ModuleDefinition.ImportReference(property.GetGetMethod(targetType)); ins.Add(Instruction.Create(OpCodes.Ldarg_0)); ins.Add(Instruction.Create(OpCodes.Call, get)); if (get.ReturnType.IsValueType) { var returnType = ModuleDefinition.ImportReference(property.GetMethod.ReturnType); if (returnType.FullName == "System.DateTime") { var convertToUtc = ModuleDefinition.ImportReference(returnType.Resolve().FindMethod("ToUniversalTime")); var variable = new VariableDefinition(returnType); variables.Add(variable); ins.Add(Instruction.Create(OpCodes.Stloc, variable)); ins.Add(Instruction.Create(OpCodes.Ldloca, variable)); ins.Add(Instruction.Create(OpCodes.Call, convertToUtc)); } ins.Add(Instruction.Create(OpCodes.Box, returnType)); } else { var propType = property.PropertyType.Resolve(); var isCollection = !property.PropertyType.IsGenericParameter && propType.IsCollection(); if (isCollection) { AssignFalseToFirstFLag(ins); If(ins, nc => nc.Add(Instruction.Create(OpCodes.Dup)), nt => { GetEnumerator(nt); NewStringBuilder(nt); AppendString(nt, "["); While(nt, c => { c.Add(Instruction.Create(OpCodes.Ldloc_2)); c.Add(Instruction.Create(OpCodes.Callvirt, moveNext)); }, b => { AppendSeparator(b); ins.Add(Instruction.Create(OpCodes.Ldloc_1)); If(ins, c => { c.Add(Instruction.Create(OpCodes.Ldloc_2)); c.Add(Instruction.Create(OpCodes.Callvirt, current)); }, t => { t.Add(Instruction.Create(OpCodes.Call, getInvariantCulture)); string format; var collectionType = ((GenericInstanceType)property.PropertyType).GenericArguments[0]; if (HaveToAddQuotes(collectionType)) { format = "\"{0}\""; } else { format = "{0}"; } t.Add(Instruction.Create(OpCodes.Ldstr, format)); t.Add(Instruction.Create(OpCodes.Ldc_I4, 1)); t.Add(Instruction.Create(OpCodes.Newarr, objectTypeRef)); t.Add(Instruction.Create(OpCodes.Stloc, body.Variables[4])); t.Add(Instruction.Create(OpCodes.Ldloc, body.Variables[4])); t.Add(Instruction.Create(OpCodes.Ldc_I4_0)); t.Add(Instruction.Create(OpCodes.Ldloc_2)); t.Add(Instruction.Create(OpCodes.Callvirt, current)); t.Add(Instruction.Create(OpCodes.Stelem_Ref)); t.Add(Instruction.Create(OpCodes.Ldloc, body.Variables[4])); t.Add(Instruction.Create(OpCodes.Call, formatMethod)); }, e => e.Add(Instruction.Create(OpCodes.Ldstr, "null"))); ins.Add(Instruction.Create(OpCodes.Callvirt, appendString)); ins.Add(Instruction.Create(OpCodes.Pop)); }); AppendString(ins, "]"); StringBuilderToString(ins); }, nf => { ins.Add(Instruction.Create(OpCodes.Pop)); ins.Add(Instruction.Create(OpCodes.Ldstr, "null")); }); } else { If(ins, c => { ins.Add(Instruction.Create(OpCodes.Dup)); AddBoxing(property, targetType, c); }, t => AddBoxing(property, targetType, t), e => { ins.Add(Instruction.Create(OpCodes.Pop)); ins.Add(Instruction.Create(OpCodes.Ldstr, "null")); }); } } ins.Add(Instruction.Create(OpCodes.Stelem_Ref)); }