Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Activities / Rules / CodeDomDecompiler.cs / 1305376 / CodeDomDecompiler.cs
using System; using System.CodeDom; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Text; using System.Workflow.ComponentModel; namespace System.Workflow.Activities.Rules { internal static class RuleDecompiler { #region Decompile literals internal static void DecompileObjectLiteral(StringBuilder decompilation, object primitiveValue) { if (primitiveValue == null) { decompilation.Append("null"); } else { Type primitiveType = primitiveValue.GetType(); if (primitiveType == typeof(string)) DecompileStringLiteral(decompilation, (string)primitiveValue); else if (primitiveType == typeof(char)) DecompileCharacterLiteral(decompilation, (char)primitiveValue); else if (primitiveType == typeof(long)) DecompileSuffixedIntegerLiteral(decompilation, primitiveValue, "L"); else if (primitiveType == typeof(uint)) DecompileSuffixedIntegerLiteral(decompilation, primitiveValue, "U"); else if (primitiveType == typeof(ulong)) DecompileSuffixedIntegerLiteral(decompilation, primitiveValue, "UL"); else if (primitiveType == typeof(float)) DecompileFloatingPointLiteral(decompilation, primitiveValue, 'f'); else if (primitiveType == typeof(double)) DecompileFloatingPointLiteral(decompilation, primitiveValue, 'd'); else if (primitiveType == typeof(decimal)) DecompileFloatingPointLiteral(decompilation, primitiveValue, 'm'); else decompilation.Append(primitiveValue.ToString()); } } private static void DecompileFloatingPointLiteral(StringBuilder decompilation, object value, char suffix) { // Make sure decimal point isn't converted to a comma in European locales. string svalue = Convert.ToString(value, CultureInfo.InvariantCulture); decompilation.Append(svalue); if (suffix == 'd') { // Don't append 'd' suffixes, they're ugly. Only if the string-ified value contains // no decimal and no exponent do we need to append a ".0" to make it a double (as // opposed to an integer). bool hasDecimal = svalue.IndexOf('.') >= 0; bool hasExponent = svalue.IndexOfAny(new char[] { 'e', 'E' }) >= 0; if (!hasDecimal && !hasExponent) decompilation.Append(".0"); } else { decompilation.Append(suffix); } } private static void DecompileSuffixedIntegerLiteral(StringBuilder decompilation, object value, string suffix) { decompilation.Append(value.ToString()); decompilation.Append(suffix); } private static void DecompileStringLiteral(StringBuilder decompilation, string strValue) { decompilation.Append("\""); for (int i = 0; i < strValue.Length; ++i) { char c = strValue[i]; // is this character a surrogate pair? if ((char.IsHighSurrogate(c)) && (i+1 < strValue.Length) && (char.IsLowSurrogate(strValue[i+1]))) { // yes, so leave the two characters unchanged decompilation.Append(c); ++i; decompilation.Append(strValue[i]); } else AppendCharacter(decompilation, c, '"'); } decompilation.Append("\""); } private static void DecompileCharacterLiteral(StringBuilder decompilation, char charValue) { decompilation.Append("'"); AppendCharacter(decompilation, charValue, '\''); decompilation.Append("'"); } private static void AppendCharacter(StringBuilder decompilation, char charValue, char quoteCharacter) { if (charValue == quoteCharacter) { decompilation.Append("\\"); decompilation.Append(quoteCharacter); } else if (charValue == '\\') { decompilation.Append("\\\\"); } else if ((charValue >= ' ' && charValue < '\u007f') || char.IsLetterOrDigit(charValue) || char.IsPunctuation(charValue)) { decompilation.Append(charValue); } else { string escapeSequence = null; switch (charValue) { case '\0': escapeSequence = "\\0"; break; case '\n': escapeSequence = "\\n"; break; case '\r': escapeSequence = "\\r"; break; case '\b': escapeSequence = "\\b"; break; case '\a': escapeSequence = "\\a"; break; case '\t': escapeSequence = "\\t"; break; case '\f': escapeSequence = "\\f"; break; case '\v': escapeSequence = "\\v"; break; } if (escapeSequence != null) { decompilation.Append(escapeSequence); } else { decompilation.Append("\\u"); UInt16 cv = (UInt16)charValue; for (int i = 12; i >= 0; i -= 4) { int mask = 0xF << i; byte c = (byte)((cv & mask) >> i); decompilation.Append("0123456789ABCDEF"[c]); } } } } #endregion #region Type decompilation internal static string DecompileType(Type type) { if (type == null) return string.Empty; StringBuilder sb = new StringBuilder(); DecompileType_Helper(sb, type); return sb.ToString(); } private static void DecompileType_Helper(StringBuilder decompilation, Type type) { int i; if (type.HasElementType) { DecompileType_Helper(decompilation, type.GetElementType()); if (type.IsArray) { decompilation.Append("["); decompilation.Append(',', type.GetArrayRank() - 1); decompilation.Append("]"); } else if (type.IsByRef) { decompilation.Append('&'); } else if (type.IsPointer) { decompilation.Append('*'); } } else { string typeName = type.FullName; if (typeName == null) // Full name may be null for an unbound generic. typeName = type.Name; typeName = UnmangleTypeName(typeName); decompilation.Append(typeName); if (type.IsGenericType) { decompilation.Append("<"); Type[] typeArgs = type.GetGenericArguments(); DecompileType_Helper(decompilation, typeArgs[0]); // decompile the first type arg for (i = 1; i < typeArgs.Length; ++i) { decompilation.Append(", "); DecompileType_Helper(decompilation, typeArgs[i]); } decompilation.Append(">"); } } } internal static void DecompileType(StringBuilder decompilation, CodeTypeReference typeRef) { // Remove any back-tick decorations on generic types, if present. string baseType = UnmangleTypeName(typeRef.BaseType); decompilation.Append(baseType); if (typeRef.TypeArguments != null && typeRef.TypeArguments.Count > 0) { decompilation.Append("<"); bool first = true; foreach (CodeTypeReference argTypeRef in typeRef.TypeArguments) { if (!first) decompilation.Append(", "); first = false; DecompileType(decompilation, argTypeRef); } decompilation.Append(">"); } if (typeRef.ArrayRank > 0) { do { decompilation.Append("["); for (int i = 1; i < typeRef.ArrayRank; ++i) decompilation.Append(","); decompilation.Append("]"); typeRef = typeRef.ArrayElementType; } while (typeRef.ArrayRank > 0); } } private static DictionaryknownTypeMap = InitializeKnownTypeMap(); private static Dictionary InitializeKnownTypeMap() { Dictionary map = new Dictionary (); map.Add("System.Char", "char"); map.Add("System.Byte", "byte"); map.Add("System.SByte", "sbyte"); map.Add("System.Int16", "short"); map.Add("System.UInt16", "ushort"); map.Add("System.Int32", "int"); map.Add("System.UInt32", "uint"); map.Add("System.Int64", "long"); map.Add("System.UInt64", "ulong"); map.Add("System.Single", "float"); map.Add("System.Double", "double"); map.Add("System.Decimal", "decimal"); map.Add("System.Boolean", "bool"); map.Add("System.String", "string"); map.Add("System.Object", "object"); map.Add("System.Void", "void"); return map; } private static string TryReplaceKnownTypes(string typeName) { string newTypeName = null; if (!knownTypeMap.TryGetValue(typeName, out newTypeName)) newTypeName = typeName; return newTypeName; } private static string UnmangleTypeName(string typeName) { int tickIndex = typeName.IndexOf('`'); if (tickIndex > 0) typeName = typeName.Substring(0, tickIndex); // Replace the '+' for a nested type with a '.' typeName = typeName.Replace('+', '.'); typeName = TryReplaceKnownTypes(typeName); return typeName; } #endregion #region Method decompilation internal static string DecompileMethod(MethodInfo method) { if (method == null) return string.Empty; StringBuilder sb = new StringBuilder(); string operatorName; DecompileType_Helper(sb, method.DeclaringType); sb.Append('.'); if (knownOperatorMap.TryGetValue(method.Name, out operatorName)) sb.Append(operatorName); else sb.Append(method.Name); sb.Append('('); ParameterInfo[] parms = method.GetParameters(); for (int i = 0; i < parms.Length; ++i) { DecompileType_Helper(sb, parms[i].ParameterType); if (i != parms.Length - 1) sb.Append(", "); } sb.Append(')'); return sb.ToString(); } private static Dictionary knownOperatorMap = InitializeKnownOperatorMap(); private static Dictionary InitializeKnownOperatorMap() { Dictionary map = new Dictionary (27); // unary operators map.Add("op_UnaryPlus", "operator +"); map.Add("op_UnaryNegation", "operator -"); map.Add("op_OnesComplement", "operator ~"); map.Add("op_LogicalNot", "operator !"); map.Add("op_Increment", "operator ++"); map.Add("op_Decrement", "operator --"); map.Add("op_True", "operator true"); map.Add("op_False", "operator false"); map.Add("op_Implicit", "implicit operator"); map.Add("op_Explicit", "explicit operator"); // binary operators map.Add("op_Equality", "operator =="); map.Add("op_Inequality", "operator !="); map.Add("op_GreaterThan", "operator >"); map.Add("op_GreaterThanOrEqual", "operator >="); map.Add("op_LessThan", "operator <"); map.Add("op_LessThanOrEqual", "operator <="); map.Add("op_Addition", "operator +"); map.Add("op_Subtraction", "operator -"); map.Add("op_Multiply", "operator *"); map.Add("op_Division", "operator /"); map.Add("op_IntegerDivision", "operator \\"); map.Add("op_Modulus", "operator %"); map.Add("op_LeftShift", "operator <<"); map.Add("op_RightShift", "operator >>"); map.Add("op_BitwiseAnd", "operator &"); map.Add("op_BitwiseOr", "operator |"); map.Add("op_ExclusiveOr", "operator ^"); return map; } #endregion #region Operator Precedence // These operations are sorted in order of precedence, lowest-to-highest private enum Operation { RootExpression, LogicalOr, // || LogicalAnd, // && BitwiseOr, // | BitwiseAnd, // & Equality, // == != Comparitive, // < <= > >= Additive, // + - Multiplicative, // * / % Unary, // - ! (cast) Postfix, // field/property ref and method call NoParentheses // Highest } private delegate Operation ComputePrecedence(CodeExpression expresssion); private static Dictionary precedenceMap = InitializePrecedenceMap(); private static Dictionary InitializePrecedenceMap() { Dictionary map = new Dictionary (7); map.Add(typeof(CodeBinaryOperatorExpression), GetBinaryPrecedence); map.Add(typeof(CodeCastExpression), GetCastPrecedence); map.Add(typeof(CodeFieldReferenceExpression), GetPostfixPrecedence); map.Add(typeof(CodePropertyReferenceExpression), GetPostfixPrecedence); map.Add(typeof(CodeMethodInvokeExpression), GetPostfixPrecedence); map.Add(typeof(CodeObjectCreateExpression), GetPostfixPrecedence); map.Add(typeof(CodeArrayCreateExpression), GetPostfixPrecedence); return map; } private static Operation GetPostfixPrecedence(CodeExpression expression) { return Operation.Postfix; } private static Operation GetCastPrecedence(CodeExpression expression) { return Operation.Unary; } private static Operation GetBinaryPrecedence(CodeExpression expression) { CodeBinaryOperatorExpression binaryExpr = (CodeBinaryOperatorExpression)expression; Operation operation = Operation.NoParentheses; switch (binaryExpr.Operator) { case CodeBinaryOperatorType.Multiply: case CodeBinaryOperatorType.Divide: case CodeBinaryOperatorType.Modulus: operation = Operation.Multiplicative; break; case CodeBinaryOperatorType.Subtract: case CodeBinaryOperatorType.Add: operation = Operation.Additive; break; case CodeBinaryOperatorType.LessThan: case CodeBinaryOperatorType.LessThanOrEqual: case CodeBinaryOperatorType.GreaterThan: case CodeBinaryOperatorType.GreaterThanOrEqual: operation = Operation.Comparitive; break; case CodeBinaryOperatorType.IdentityEquality: case CodeBinaryOperatorType.ValueEquality: case CodeBinaryOperatorType.IdentityInequality: operation = Operation.Equality; break; case CodeBinaryOperatorType.BitwiseAnd: operation = Operation.BitwiseAnd; break; case CodeBinaryOperatorType.BitwiseOr: operation = Operation.BitwiseOr; break; case CodeBinaryOperatorType.BooleanAnd: operation = Operation.LogicalAnd; break; case CodeBinaryOperatorType.BooleanOr: operation = Operation.LogicalOr; break; default: string message = string.Format(CultureInfo.CurrentCulture, Messages.BinaryOpNotSupported, binaryExpr.Operator.ToString()); NotSupportedException exception = new NotSupportedException(message); exception.Data[RuleUserDataKeys.ErrorObject] = binaryExpr; throw exception; } return operation; } private static Operation GetPrecedence(CodeExpression expression) { // Assume the operation needs no parentheses. Operation operation = Operation.NoParentheses; ComputePrecedence computePrecedence; if (precedenceMap.TryGetValue(expression.GetType(), out computePrecedence)) operation = computePrecedence(expression); return operation; } internal static bool MustParenthesize(CodeExpression childExpr, CodeExpression parentExpr) { // No parent... we're at the root, so no need to parenthesize the root. if (parentExpr == null) return false; Operation childOperation = GetPrecedence(childExpr); Operation parentOperation = GetPrecedence(parentExpr); if (parentOperation == childOperation) { CodeBinaryOperatorExpression parentBinary = parentExpr as CodeBinaryOperatorExpression; if (parentBinary != null) { if (childExpr == parentBinary.Right) { // Something like 2 - (3 - 4) needs parentheses. return true; } else { // Something like (2 - 3) - 4 doesn't need parentheses. return false; } } else { return false; } } else if (parentOperation > childOperation) { return true; } else { return false; } } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System; using System.CodeDom; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Text; using System.Workflow.ComponentModel; namespace System.Workflow.Activities.Rules { internal static class RuleDecompiler { #region Decompile literals internal static void DecompileObjectLiteral(StringBuilder decompilation, object primitiveValue) { if (primitiveValue == null) { decompilation.Append("null"); } else { Type primitiveType = primitiveValue.GetType(); if (primitiveType == typeof(string)) DecompileStringLiteral(decompilation, (string)primitiveValue); else if (primitiveType == typeof(char)) DecompileCharacterLiteral(decompilation, (char)primitiveValue); else if (primitiveType == typeof(long)) DecompileSuffixedIntegerLiteral(decompilation, primitiveValue, "L"); else if (primitiveType == typeof(uint)) DecompileSuffixedIntegerLiteral(decompilation, primitiveValue, "U"); else if (primitiveType == typeof(ulong)) DecompileSuffixedIntegerLiteral(decompilation, primitiveValue, "UL"); else if (primitiveType == typeof(float)) DecompileFloatingPointLiteral(decompilation, primitiveValue, 'f'); else if (primitiveType == typeof(double)) DecompileFloatingPointLiteral(decompilation, primitiveValue, 'd'); else if (primitiveType == typeof(decimal)) DecompileFloatingPointLiteral(decompilation, primitiveValue, 'm'); else decompilation.Append(primitiveValue.ToString()); } } private static void DecompileFloatingPointLiteral(StringBuilder decompilation, object value, char suffix) { // Make sure decimal point isn't converted to a comma in European locales. string svalue = Convert.ToString(value, CultureInfo.InvariantCulture); decompilation.Append(svalue); if (suffix == 'd') { // Don't append 'd' suffixes, they're ugly. Only if the string-ified value contains // no decimal and no exponent do we need to append a ".0" to make it a double (as // opposed to an integer). bool hasDecimal = svalue.IndexOf('.') >= 0; bool hasExponent = svalue.IndexOfAny(new char[] { 'e', 'E' }) >= 0; if (!hasDecimal && !hasExponent) decompilation.Append(".0"); } else { decompilation.Append(suffix); } } private static void DecompileSuffixedIntegerLiteral(StringBuilder decompilation, object value, string suffix) { decompilation.Append(value.ToString()); decompilation.Append(suffix); } private static void DecompileStringLiteral(StringBuilder decompilation, string strValue) { decompilation.Append("\""); for (int i = 0; i < strValue.Length; ++i) { char c = strValue[i]; // is this character a surrogate pair? if ((char.IsHighSurrogate(c)) && (i+1 < strValue.Length) && (char.IsLowSurrogate(strValue[i+1]))) { // yes, so leave the two characters unchanged decompilation.Append(c); ++i; decompilation.Append(strValue[i]); } else AppendCharacter(decompilation, c, '"'); } decompilation.Append("\""); } private static void DecompileCharacterLiteral(StringBuilder decompilation, char charValue) { decompilation.Append("'"); AppendCharacter(decompilation, charValue, '\''); decompilation.Append("'"); } private static void AppendCharacter(StringBuilder decompilation, char charValue, char quoteCharacter) { if (charValue == quoteCharacter) { decompilation.Append("\\"); decompilation.Append(quoteCharacter); } else if (charValue == '\\') { decompilation.Append("\\\\"); } else if ((charValue >= ' ' && charValue < '\u007f') || char.IsLetterOrDigit(charValue) || char.IsPunctuation(charValue)) { decompilation.Append(charValue); } else { string escapeSequence = null; switch (charValue) { case '\0': escapeSequence = "\\0"; break; case '\n': escapeSequence = "\\n"; break; case '\r': escapeSequence = "\\r"; break; case '\b': escapeSequence = "\\b"; break; case '\a': escapeSequence = "\\a"; break; case '\t': escapeSequence = "\\t"; break; case '\f': escapeSequence = "\\f"; break; case '\v': escapeSequence = "\\v"; break; } if (escapeSequence != null) { decompilation.Append(escapeSequence); } else { decompilation.Append("\\u"); UInt16 cv = (UInt16)charValue; for (int i = 12; i >= 0; i -= 4) { int mask = 0xF << i; byte c = (byte)((cv & mask) >> i); decompilation.Append("0123456789ABCDEF"[c]); } } } } #endregion #region Type decompilation internal static string DecompileType(Type type) { if (type == null) return string.Empty; StringBuilder sb = new StringBuilder(); DecompileType_Helper(sb, type); return sb.ToString(); } private static void DecompileType_Helper(StringBuilder decompilation, Type type) { int i; if (type.HasElementType) { DecompileType_Helper(decompilation, type.GetElementType()); if (type.IsArray) { decompilation.Append("["); decompilation.Append(',', type.GetArrayRank() - 1); decompilation.Append("]"); } else if (type.IsByRef) { decompilation.Append('&'); } else if (type.IsPointer) { decompilation.Append('*'); } } else { string typeName = type.FullName; if (typeName == null) // Full name may be null for an unbound generic. typeName = type.Name; typeName = UnmangleTypeName(typeName); decompilation.Append(typeName); if (type.IsGenericType) { decompilation.Append("<"); Type[] typeArgs = type.GetGenericArguments(); DecompileType_Helper(decompilation, typeArgs[0]); // decompile the first type arg for (i = 1; i < typeArgs.Length; ++i) { decompilation.Append(", "); DecompileType_Helper(decompilation, typeArgs[i]); } decompilation.Append(">"); } } } internal static void DecompileType(StringBuilder decompilation, CodeTypeReference typeRef) { // Remove any back-tick decorations on generic types, if present. string baseType = UnmangleTypeName(typeRef.BaseType); decompilation.Append(baseType); if (typeRef.TypeArguments != null && typeRef.TypeArguments.Count > 0) { decompilation.Append("<"); bool first = true; foreach (CodeTypeReference argTypeRef in typeRef.TypeArguments) { if (!first) decompilation.Append(", "); first = false; DecompileType(decompilation, argTypeRef); } decompilation.Append(">"); } if (typeRef.ArrayRank > 0) { do { decompilation.Append("["); for (int i = 1; i < typeRef.ArrayRank; ++i) decompilation.Append(","); decompilation.Append("]"); typeRef = typeRef.ArrayElementType; } while (typeRef.ArrayRank > 0); } } private static Dictionary knownTypeMap = InitializeKnownTypeMap(); private static Dictionary InitializeKnownTypeMap() { Dictionary map = new Dictionary (); map.Add("System.Char", "char"); map.Add("System.Byte", "byte"); map.Add("System.SByte", "sbyte"); map.Add("System.Int16", "short"); map.Add("System.UInt16", "ushort"); map.Add("System.Int32", "int"); map.Add("System.UInt32", "uint"); map.Add("System.Int64", "long"); map.Add("System.UInt64", "ulong"); map.Add("System.Single", "float"); map.Add("System.Double", "double"); map.Add("System.Decimal", "decimal"); map.Add("System.Boolean", "bool"); map.Add("System.String", "string"); map.Add("System.Object", "object"); map.Add("System.Void", "void"); return map; } private static string TryReplaceKnownTypes(string typeName) { string newTypeName = null; if (!knownTypeMap.TryGetValue(typeName, out newTypeName)) newTypeName = typeName; return newTypeName; } private static string UnmangleTypeName(string typeName) { int tickIndex = typeName.IndexOf('`'); if (tickIndex > 0) typeName = typeName.Substring(0, tickIndex); // Replace the '+' for a nested type with a '.' typeName = typeName.Replace('+', '.'); typeName = TryReplaceKnownTypes(typeName); return typeName; } #endregion #region Method decompilation internal static string DecompileMethod(MethodInfo method) { if (method == null) return string.Empty; StringBuilder sb = new StringBuilder(); string operatorName; DecompileType_Helper(sb, method.DeclaringType); sb.Append('.'); if (knownOperatorMap.TryGetValue(method.Name, out operatorName)) sb.Append(operatorName); else sb.Append(method.Name); sb.Append('('); ParameterInfo[] parms = method.GetParameters(); for (int i = 0; i < parms.Length; ++i) { DecompileType_Helper(sb, parms[i].ParameterType); if (i != parms.Length - 1) sb.Append(", "); } sb.Append(')'); return sb.ToString(); } private static Dictionary knownOperatorMap = InitializeKnownOperatorMap(); private static Dictionary InitializeKnownOperatorMap() { Dictionary map = new Dictionary (27); // unary operators map.Add("op_UnaryPlus", "operator +"); map.Add("op_UnaryNegation", "operator -"); map.Add("op_OnesComplement", "operator ~"); map.Add("op_LogicalNot", "operator !"); map.Add("op_Increment", "operator ++"); map.Add("op_Decrement", "operator --"); map.Add("op_True", "operator true"); map.Add("op_False", "operator false"); map.Add("op_Implicit", "implicit operator"); map.Add("op_Explicit", "explicit operator"); // binary operators map.Add("op_Equality", "operator =="); map.Add("op_Inequality", "operator !="); map.Add("op_GreaterThan", "operator >"); map.Add("op_GreaterThanOrEqual", "operator >="); map.Add("op_LessThan", "operator <"); map.Add("op_LessThanOrEqual", "operator <="); map.Add("op_Addition", "operator +"); map.Add("op_Subtraction", "operator -"); map.Add("op_Multiply", "operator *"); map.Add("op_Division", "operator /"); map.Add("op_IntegerDivision", "operator \\"); map.Add("op_Modulus", "operator %"); map.Add("op_LeftShift", "operator <<"); map.Add("op_RightShift", "operator >>"); map.Add("op_BitwiseAnd", "operator &"); map.Add("op_BitwiseOr", "operator |"); map.Add("op_ExclusiveOr", "operator ^"); return map; } #endregion #region Operator Precedence // These operations are sorted in order of precedence, lowest-to-highest private enum Operation { RootExpression, LogicalOr, // || LogicalAnd, // && BitwiseOr, // | BitwiseAnd, // & Equality, // == != Comparitive, // < <= > >= Additive, // + - Multiplicative, // * / % Unary, // - ! (cast) Postfix, // field/property ref and method call NoParentheses // Highest } private delegate Operation ComputePrecedence(CodeExpression expresssion); private static Dictionary precedenceMap = InitializePrecedenceMap(); private static Dictionary InitializePrecedenceMap() { Dictionary map = new Dictionary (7); map.Add(typeof(CodeBinaryOperatorExpression), GetBinaryPrecedence); map.Add(typeof(CodeCastExpression), GetCastPrecedence); map.Add(typeof(CodeFieldReferenceExpression), GetPostfixPrecedence); map.Add(typeof(CodePropertyReferenceExpression), GetPostfixPrecedence); map.Add(typeof(CodeMethodInvokeExpression), GetPostfixPrecedence); map.Add(typeof(CodeObjectCreateExpression), GetPostfixPrecedence); map.Add(typeof(CodeArrayCreateExpression), GetPostfixPrecedence); return map; } private static Operation GetPostfixPrecedence(CodeExpression expression) { return Operation.Postfix; } private static Operation GetCastPrecedence(CodeExpression expression) { return Operation.Unary; } private static Operation GetBinaryPrecedence(CodeExpression expression) { CodeBinaryOperatorExpression binaryExpr = (CodeBinaryOperatorExpression)expression; Operation operation = Operation.NoParentheses; switch (binaryExpr.Operator) { case CodeBinaryOperatorType.Multiply: case CodeBinaryOperatorType.Divide: case CodeBinaryOperatorType.Modulus: operation = Operation.Multiplicative; break; case CodeBinaryOperatorType.Subtract: case CodeBinaryOperatorType.Add: operation = Operation.Additive; break; case CodeBinaryOperatorType.LessThan: case CodeBinaryOperatorType.LessThanOrEqual: case CodeBinaryOperatorType.GreaterThan: case CodeBinaryOperatorType.GreaterThanOrEqual: operation = Operation.Comparitive; break; case CodeBinaryOperatorType.IdentityEquality: case CodeBinaryOperatorType.ValueEquality: case CodeBinaryOperatorType.IdentityInequality: operation = Operation.Equality; break; case CodeBinaryOperatorType.BitwiseAnd: operation = Operation.BitwiseAnd; break; case CodeBinaryOperatorType.BitwiseOr: operation = Operation.BitwiseOr; break; case CodeBinaryOperatorType.BooleanAnd: operation = Operation.LogicalAnd; break; case CodeBinaryOperatorType.BooleanOr: operation = Operation.LogicalOr; break; default: string message = string.Format(CultureInfo.CurrentCulture, Messages.BinaryOpNotSupported, binaryExpr.Operator.ToString()); NotSupportedException exception = new NotSupportedException(message); exception.Data[RuleUserDataKeys.ErrorObject] = binaryExpr; throw exception; } return operation; } private static Operation GetPrecedence(CodeExpression expression) { // Assume the operation needs no parentheses. Operation operation = Operation.NoParentheses; ComputePrecedence computePrecedence; if (precedenceMap.TryGetValue(expression.GetType(), out computePrecedence)) operation = computePrecedence(expression); return operation; } internal static bool MustParenthesize(CodeExpression childExpr, CodeExpression parentExpr) { // No parent... we're at the root, so no need to parenthesize the root. if (parentExpr == null) return false; Operation childOperation = GetPrecedence(childExpr); Operation parentOperation = GetPrecedence(parentExpr); if (parentOperation == childOperation) { CodeBinaryOperatorExpression parentBinary = parentExpr as CodeBinaryOperatorExpression; if (parentBinary != null) { if (childExpr == parentBinary.Right) { // Something like 2 - (3 - 4) needs parentheses. return true; } else { // Something like (2 - 3) - 4 doesn't need parentheses. return false; } } else { return false; } } else if (parentOperation > childOperation) { return true; } else { return false; } } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- MonitoringDescriptionAttribute.cs
- TrailingSpaceComparer.cs
- EndGetFileNameFromUserRequest.cs
- TransactionsSectionGroup.cs
- WorkflowMarkupElementEventArgs.cs
- Internal.cs
- InvokePattern.cs
- ReverseInheritProperty.cs
- XhtmlConformanceSection.cs
- PageVisual.cs
- SslStream.cs
- VideoDrawing.cs
- TrackBar.cs
- QilUnary.cs
- DataTableTypeConverter.cs
- Parallel.cs
- HttpSessionStateWrapper.cs
- ActivityExecutionFilter.cs
- HandlerWithFactory.cs
- TabRenderer.cs
- EventMappingSettingsCollection.cs
- SqlTransaction.cs
- HtmlEncodedRawTextWriter.cs
- DbTransaction.cs
- XmlSchemaAttributeGroupRef.cs
- ColumnCollection.cs
- StructuralType.cs
- CompletedAsyncResult.cs
- StylusTip.cs
- SessionStateSection.cs
- InterleavedZipPartStream.cs
- WebBrowserContainer.cs
- DesignTimeParseData.cs
- DefaultSerializationProviderAttribute.cs
- ReferencedType.cs
- MD5.cs
- TextHidden.cs
- IBuiltInEvidence.cs
- OperandQuery.cs
- ObjectListGeneralPage.cs
- DateTimeSerializationSection.cs
- ThrowHelper.cs
- PersonalizationAdministration.cs
- Repeater.cs
- RunWorkerCompletedEventArgs.cs
- OdbcHandle.cs
- CodeTryCatchFinallyStatement.cs
- AvtEvent.cs
- TraversalRequest.cs
- RecognizedPhrase.cs
- ToolStripItem.cs
- PropertyChangedEventManager.cs
- BuildManagerHost.cs
- Globals.cs
- SynthesizerStateChangedEventArgs.cs
- CriticalHandle.cs
- XmlSchemaRedefine.cs
- XmlNamespaceMappingCollection.cs
- Manipulation.cs
- LambdaCompiler.Generated.cs
- DynamicActivityTypeDescriptor.cs
- SqlDataSourceCommandEventArgs.cs
- PerfCounters.cs
- TextClipboardData.cs
- QueryModel.cs
- BindingBase.cs
- SendActivityEventArgs.cs
- InputScopeConverter.cs
- InputBuffer.cs
- ListItemViewControl.cs
- EntityDataSourceContainerNameItem.cs
- Token.cs
- InvalidOleVariantTypeException.cs
- Function.cs
- ClientConfigPaths.cs
- SetterBase.cs
- InputLanguage.cs
- StringReader.cs
- XmlSchemaValidator.cs
- CorrelationResolver.cs
- Listbox.cs
- DataGridColumnHeadersPresenter.cs
- HebrewNumber.cs
- RedirectionProxy.cs
- SqlParameterizer.cs
- WebPartManagerInternals.cs
- NavigationProperty.cs
- HeaderLabel.cs
- XmlIlGenerator.cs
- SafeSecurityHelper.cs
- TableCell.cs
- NameTable.cs
- PrinterResolution.cs
- XmlValueConverter.cs
- StylusEventArgs.cs
- OdbcConnectionPoolProviderInfo.cs
- WorkflowInstance.cs
- HttpProfileBase.cs
- MaskedTextBox.cs
- CompilerGlobalScopeAttribute.cs