private Expression FixCaseLiteralValue(LiteralExpression literalCondition) { TypeReference conditionType = theSwitch.Condition.ExpressionType; int integerRepresentation = Convert.ToInt32(literalCondition.Value) + this.conditionOffset; literalCondition.Value = integerRepresentation; var theTypeSystem = context.MethodContext.Method.Module.TypeSystem; if (conditionType.Name == "System.Nullable`1" && conditionType.HasGenericParameters) { conditionType = conditionType.GenericParameters[0]; } if (conditionType.FullName == theTypeSystem.Char.FullName) { //switch cases should have char labels; return new LiteralExpression(Convert.ToChar(integerRepresentation),theTypeSystem, null); } else if (conditionType.FullName == theTypeSystem.Boolean.FullName) { return new LiteralExpression(Convert.ToBoolean(integerRepresentation),theTypeSystem,null); } else { TypeDefinition resolvedConditionType = conditionType.Resolve(); if (resolvedConditionType != null && resolvedConditionType.IsEnum) { Expression result = EnumHelper.GetEnumExpression(resolvedConditionType,literalCondition,theTypeSystem); if (result is LiteralExpression) { result = new CastExpression(result, resolvedConditionType, null); } return result; } } return literalCondition; }
private Expression GetMethodHandleExpression(MethodReference methodReference, IEnumerable<Instruction> instructions) { TypeDefinition corlibTypeTypeDefinition = GetSystemTypeTypeDefinition(); string[] parametersNames = methodReference.HasParameters ? new string[] { "System.String", "System.Type[]" } : new string[] { "System.String" }; MethodReference getMethodReference = GetSystemTypeMethodReference(corlibTypeTypeDefinition, "GetMethod", parametersNames); MethodReference getMethodHandleReference = GetHandlePropertyGetterReference(typeof(System.Reflection.MethodBase), "get_MethodHandle"); TypeOfExpression typeOfExpression = new TypeOfExpression(methodReference.DeclaringType, null); MethodReferenceExpression getMethodMethodReferenceExpression = new MethodReferenceExpression(typeOfExpression, getMethodReference, null); MethodInvocationExpression getMethodMethodInvocationExpression = new MethodInvocationExpression(getMethodMethodReferenceExpression, null); LiteralExpression argument = new LiteralExpression(methodReference.Name, this.typeSystem, null); getMethodMethodInvocationExpression.Arguments.Add(argument); if (methodReference.HasParameters) { BlockExpression blockExpression = new BlockExpression(null); foreach (ParameterDefinition parameter in methodReference.Parameters) { blockExpression.Expressions.Add(new TypeOfExpression(parameter.ParameterType, null)); } InitializerExpression initializer = new InitializerExpression(blockExpression, InitializerType.ArrayInitializer); ArrayCreationExpression getMethodTypeParametersArray = new ArrayCreationExpression(corlibTypeTypeDefinition, initializer, null); getMethodTypeParametersArray.Dimensions.Add(new LiteralExpression(blockExpression.Expressions.Count, this.typeSystem, null)); getMethodMethodInvocationExpression.Arguments.Add(getMethodTypeParametersArray); } MethodReferenceExpression getMethodHandleMethodReferenceExpression = new MethodReferenceExpression(getMethodMethodInvocationExpression, getMethodHandleReference, null); MethodInvocationExpression getMethodHandleMethodInvocationExpression = new MethodInvocationExpression(getMethodHandleMethodReferenceExpression, instructions); PropertyReferenceExpression methodHandlePropertyReferenceExpression = new PropertyReferenceExpression(getMethodHandleMethodInvocationExpression, null); return methodHandlePropertyReferenceExpression; }
protected virtual void WriteFieldDeclaration(FieldDefinition field) { if (!this.TypeContext.BackingFieldToNameMap.ContainsKey(field) && this.ModuleContext.RenamedMembers.Contains(field.MetadataToken.ToUInt32())) { string originalFieldName = GetOriginalFieldName(field); WriteComment(originalFieldName); WriteLine(); } WriteMemberVisibility(field); WriteSpace(); if (field.IsInitOnly) { WriteKeyword(KeyWordWriter.ReadOnly); WriteSpace(); } if (field.IsLiteral) { WriteKeyword(KeyWordWriter.Const); WriteSpace(); } else if (field.IsStatic) { WriteKeyword(KeyWordWriter.Static); WriteSpace(); } WriteFieldTypeAndName(field); if (field.HasConstant) { WriteSpace(); WriteToken("="); WriteSpace(); TypeDefinition fieldType = field.FieldType.Resolve(); if (fieldType != null && fieldType.IsEnum) { LiteralExpression fieldConstant = new LiteralExpression(field.Constant.Value, field.DeclaringType.Module.TypeSystem, null); Expression constant = EnumHelper.GetEnumExpression(fieldType, fieldConstant, field.DeclaringType.Module.TypeSystem); Write(constant); } else { WriteLiteralInLanguageSyntax(field.Constant.Value); } } }
public override void VisitLiteralExpression(LiteralExpression node) { WriteLiteralInLanguageSyntax(node.Value); }
private int GetIntegerValue(LiteralExpression size) { if (size != null) { try { return Convert.ToInt32(size.Value); } catch (InvalidCastException) { return -1; } } return -1; }
public static Expression GetEnumExpression(TypeDefinition enumDefinition, LiteralExpression targetedValue, TypeSystem typeSystem) { int enumDefinitionUnderlyingTypeSize = GetEnumBitSize(enumDefinition); /// This depends on the unchecked context, which is default for C# ulong value = 0; switch (targetedValue.Value.GetType().FullName) { case "System.Int32": /// This is done, so that the same size extension is used when casting the literal's value to ulong /// and when casting anum's contstants to ulong. /// Otherwise, casting int -1 and long -1 to ulong will yield different results. if (enumDefinitionUnderlyingTypeSize == 32) { value = (uint)(int)targetedValue.Value; } else { value = (ulong)(int)targetedValue.Value; } break; case "System.Int64": value = (ulong)(long)targetedValue.Value; break; case "System.UInt32": value = (uint)targetedValue.Value; break; case "System.UInt64": value = (ulong)targetedValue.Value; break; // The types below should not be present at any point, but are added just to complete all the possible cases. case "System.Byte": value = (byte)targetedValue.Value; break; case "System.SByte": value = (ulong)(sbyte)targetedValue.Value; break; case "System.Int16": value = (ulong)(short)targetedValue.Value; break; case "System.UInt16": value = (ushort)targetedValue.Value; break; } Collection<FieldDefinition> fields = enumDefinition.Fields; List<FieldDefinition> enumFields = new List<FieldDefinition>(); foreach (FieldDefinition currentField in fields) { if (currentField.Constant != null && currentField.Constant.Value != null) { ulong fieldValue = 0; switch (currentField.Constant.Value.GetType().FullName) { case "System.Int32": // most common case fieldValue = (uint)(int)(currentField.Constant.Value); break; case "System.UInt32": fieldValue = (uint)(currentField.Constant.Value); break; case "System.Byte": fieldValue = (byte)(currentField.Constant.Value); break; case "System.SByte": fieldValue = (byte)(sbyte)(currentField.Constant.Value); break; case "System.Int16": fieldValue = (ushort)(short)(currentField.Constant.Value); break; case "System.UInt16": fieldValue = (ushort)(currentField.Constant.Value); break; case "System.Int64": fieldValue = (ulong)(long)(currentField.Constant.Value); break; case "System.UInt64": fieldValue = (ulong)(currentField.Constant.Value); break; } if (fieldValue == value) { return new EnumExpression(currentField, targetedValue.UnderlyingSameMethodInstructions); } if (fieldValue != 0 && (fieldValue | value) == value) //if (IsPartOfValue(fieldValue, value)) { ///Then this one of the flags, used to generate the value. enumFields.Add(currentField); } } } ///Generate the expression of the flags. if (enumFields.Count < 2) { return targetedValue; } Expression result = new BinaryExpression(BinaryOperator.BitwiseOr, new EnumExpression(enumFields[0], null), new EnumExpression(enumFields[1], null), typeSystem, null); result.ExpressionType = enumDefinition; for (int i = 2; i < enumFields.Count; i++) { result = new BinaryExpression(BinaryOperator.BitwiseOr, result, new EnumExpression(enumFields[i], null), typeSystem, null); result.ExpressionType = enumDefinition; } return result.CloneAndAttachInstructions(targetedValue.UnderlyingSameMethodInstructions); }
private object GetDecrementedValue(LiteralExpression expression) { switch (expression.ExpressionType.Name) { case "Byte": byte byteValue = (byte)expression.Value; byteValue--; return byteValue; case "SByte": sbyte sbyteValue = (sbyte)expression.Value; sbyteValue--; return sbyteValue; case "Int16": short shortValue = (short)expression.Value; shortValue--; return shortValue; case "UInt16": ushort ushortValue = (ushort)expression.Value; ushortValue--; return ushortValue; case "Int32": int intValue = (int)expression.Value; intValue--; return intValue; case "UInt32": uint uintValue = (uint)expression.Value; uintValue--; return uintValue; case "Int64": long longValue = (long)expression.Value; longValue--; return longValue; case "UInt64": ulong ulongValue = (ulong)expression.Value; ulongValue--; return ulongValue; case "Char": char charValue = (char)expression.Value; charValue--; return charValue; default: throw new ArgumentException("Invalid data type for dimension of an array."); } }
private string GetExpressionType(LiteralExpression literalExpression) { if (literalExpression.Value is decimal) return "Decimal"; if (literalExpression.Value is Single) return "Float"; if (literalExpression.Value is byte) return "Byte"; if (literalExpression.Value is sbyte) return "SByte"; if (literalExpression.Value is char) return "Char"; if (literalExpression.Value is double) return "Double"; if (literalExpression.Value is bool) return "Boolean"; if (literalExpression.Value is short) return "Short"; if (literalExpression.Value is int) return "Integer"; if (literalExpression.Value is long) return "Long"; if (literalExpression.Value is ushort) return "UShort"; if (literalExpression.Value is uint) return "UInteger"; if (literalExpression.Value is ulong) return "ULong"; if (literalExpression.Value is string) return "String"; return "Object"; }
private void FixCharLiteral(LiteralExpression literal) { literal.Value = Convert.ToChar(literal.Value); }
private void FixBooleanLiteral(LiteralExpression literal) { literal.Value = Convert.ToBoolean(literal.Value); }
private void HandleLiteralArgument(TypeReference parameterType, LiteralExpression literalArgument) { if (parameterType.FullName == currentTypeSystem.Boolean.FullName) { FixBooleanLiteral(literalArgument); } else if (parameterType.FullName == currentTypeSystem.Char.FullName) { FixCharLiteral(literalArgument); } }
public override Expression CloneExpressionOnly() { LiteralExpression result = new LiteralExpression(value, typeSystem, null); return result; }
public override Expression Clone() { LiteralExpression result = new LiteralExpression(value, typeSystem, this.instructions); return result; }
private uint GetIndexFromLiteralExpression(LiteralExpression dimention) { object boxedValue = dimention.Value; if (dimention.ExpressionType.FullName == "System.Int32") { int value = (int)boxedValue; if (value < 0) { throw new IndexOutOfRangeException(); } return (uint)value; } if (dimention.ExpressionType.FullName == "System.UInt32") { return (uint)boxedValue; } if (dimention.ExpressionType.FullName == "System.Int16") { short value = (short)boxedValue; if (value < 0) { throw new IndexOutOfRangeException(); } return (uint)value; } if (dimention.ExpressionType.FullName == "System.UInt16") { return (ushort)boxedValue; } if (dimention.ExpressionType.FullName == "System.Int8") { sbyte value = (sbyte)boxedValue; if (value < 0) { throw new IndexOutOfRangeException(); } return (uint)value; } if (dimention.ExpressionType.FullName == "System.UInt8") { return (byte)boxedValue; } if (dimention.ExpressionType.FullName == "System.Int64") { long value = (long)boxedValue; if (value < 0 || value > uint.MaxValue) { throw new IndexOutOfRangeException(); } return (uint)value; } if (dimention.ExpressionType.FullName == "System.UInt64") { ulong value = (ulong)boxedValue; if (value < 0 || value > uint.MaxValue) { throw new IndexOutOfRangeException(); } return (uint)value; } throw new IndexOutOfRangeException(); }
public virtual void VisitLiteralExpression(LiteralExpression node) { }