Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / xsp / System / Web / Compilation / CodeDOMUtility.cs / 2 / CodeDOMUtility.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Web.Compilation { using System.Text; using System.Runtime.Serialization.Formatters; using System.ComponentModel; using System.ComponentModel.Design.Serialization; using System; using System.Collections; using System.Reflection; using System.IO; using System.Globalization; using System.Web.Util; using System.Web.UI; using System.Web.Configuration; using System.Diagnostics; using Debug = System.Diagnostics.Debug; using System.CodeDom; using System.CodeDom.Compiler; using Util = System.Web.UI.Util; internal static class CodeDomUtility { internal static BooleanSwitch WebFormsCompilation = new BooleanSwitch("WebFormsCompilation", "Outputs information about the WebForms compilation of ASPX templates"); internal /*public*/ static CodeExpression GenerateExpressionForValue(PropertyInfo propertyInfo, object value, Type valueType) { #if DEBUG if (WebFormsCompilation.Enabled) { Debug.WriteLine("GenerateExpressionForValue() {"); Debug.Indent(); } #endif // DEBUG CodeExpression rightExpr = null; if (valueType == null) { throw new ArgumentNullException("valueType"); } PropertyDescriptor pd = null; if (propertyInfo != null) { pd = TypeDescriptor.GetProperties(propertyInfo.ReflectedType)[propertyInfo.Name]; } if (valueType == typeof(string) && value is string) { if (WebFormsCompilation.Enabled) Debug.WriteLine("simple string"); rightExpr = new CodePrimitiveExpression((string)value); } else if (valueType.IsPrimitive) { if (WebFormsCompilation.Enabled) Debug.WriteLine("primitive"); rightExpr = new CodePrimitiveExpression(value); } else if (propertyInfo == null && valueType == typeof(object) && (value == null || value.GetType().IsPrimitive)) { // If the type is object, and the value is a primitive, simply use a // CodePrimitiveExpression instead of trying to use a TypeConverter (VSWhidbey 518773) if (WebFormsCompilation.Enabled) Debug.WriteLine("primitive to object"); rightExpr = new CodePrimitiveExpression(value); } else if (valueType.IsArray) { if (WebFormsCompilation.Enabled) Debug.WriteLine("array"); Array array = (Array)value; CodeArrayCreateExpression exp = new CodeArrayCreateExpression(); exp.CreateType = new CodeTypeReference(valueType.GetElementType()); if (array != null) { foreach (object o in array) { exp.Initializers.Add(GenerateExpressionForValue(null, o, valueType.GetElementType())); } } rightExpr = exp; } else if (valueType == typeof(Type)) { rightExpr = new CodeTypeOfExpression((Type) value); } else { if (WebFormsCompilation.Enabled) Debug.WriteLine("other"); TypeConverter converter = null; if (pd != null) { converter = pd.Converter; } else { converter = TypeDescriptor.GetConverter(valueType); } bool added = false; if (converter != null) { InstanceDescriptor desc = null; if (converter.CanConvertTo(typeof(InstanceDescriptor))) { desc = (InstanceDescriptor)converter.ConvertTo(value, typeof(InstanceDescriptor)); } if (desc != null) { if (WebFormsCompilation.Enabled) Debug.WriteLine("has converter with instance descriptor"); // static field ref... // if (desc.MemberInfo is FieldInfo) { if (WebFormsCompilation.Enabled) Debug.WriteLine("persistinfo is a field ref"); CodeFieldReferenceExpression fieldRef = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(desc.MemberInfo.DeclaringType.FullName), desc.MemberInfo.Name); rightExpr = fieldRef; added = true; } // static property ref else if (desc.MemberInfo is PropertyInfo) { if (WebFormsCompilation.Enabled) Debug.WriteLine("persistinfo is a property ref"); CodePropertyReferenceExpression propRef = new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(desc.MemberInfo.DeclaringType.FullName), desc.MemberInfo.Name); rightExpr = propRef; added = true; } // static method invoke // else { object[] args = new object[desc.Arguments.Count]; desc.Arguments.CopyTo(args, 0); CodeExpression[] expressions = new CodeExpression[args.Length]; if (desc.MemberInfo is MethodInfo) { MethodInfo mi = (MethodInfo)desc.MemberInfo; ParameterInfo[] parameters = mi.GetParameters(); for(int i = 0; i < args.Length; i++) { expressions[i] = GenerateExpressionForValue(null, args[i], parameters[i].ParameterType); } if (WebFormsCompilation.Enabled) Debug.WriteLine("persistinfo is a method invoke"); CodeMethodInvokeExpression methCall = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(desc.MemberInfo.DeclaringType.FullName), desc.MemberInfo.Name); foreach (CodeExpression e in expressions) { methCall.Parameters.Add(e); } rightExpr = new CodeCastExpression(valueType, methCall); added = true; } else if (desc.MemberInfo is ConstructorInfo) { ConstructorInfo ci = (ConstructorInfo)desc.MemberInfo; ParameterInfo[] parameters = ci.GetParameters(); for(int i = 0; i < args.Length; i++) { expressions[i] = GenerateExpressionForValue(null, args[i], parameters[i].ParameterType); } if (WebFormsCompilation.Enabled) Debug.WriteLine("persistinfo is a constructor call"); CodeObjectCreateExpression objectCreate = new CodeObjectCreateExpression(desc.MemberInfo.DeclaringType.FullName); foreach (CodeExpression e in expressions) { objectCreate.Parameters.Add(e); } rightExpr = objectCreate; added = true; } } } } if (!added) { #if DEBUG if (WebFormsCompilation.Enabled) { Debug.WriteLine("unabled to determine type, attempting Parse"); Debug.Indent(); Debug.WriteLine("value.GetType == " + value.GetType().FullName); Debug.WriteLine("value.ToString == " + value.ToString()); Debug.WriteLine("valueType == " + valueType.FullName); if (propertyInfo != null) { Debug.WriteLine("propertyInfo == " + propertyInfo.ReflectedType.FullName + "." + propertyInfo.Name + " : " + propertyInfo.PropertyType.FullName); } else { Debug.WriteLine("propertyInfo == (null)"); } Debug.Unindent(); } #endif // DEBUG // Not a known type: try calling Parse // If possible, pass it an InvariantCulture (ASURT 79412) if (valueType.GetMethod("Parse", new Type[] {typeof(string), typeof(CultureInfo)}) != null) { CodeMethodInvokeExpression methCall = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(valueType.FullName), "Parse"); // Convert the object to a string. // If we have a type converter, use it to convert to a string in a culture // invariant way (ASURT 87094) string s; if (converter != null) { s = converter.ConvertToInvariantString(value); } else { s = value.ToString(); } methCall.Parameters.Add(new CodePrimitiveExpression(s)); methCall.Parameters.Add(new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(typeof(CultureInfo)), "InvariantCulture")); rightExpr = methCall; } else if (valueType.GetMethod("Parse", new Type[] {typeof(string)}) != null) { // Otherwise, settle for passing just the string CodeMethodInvokeExpression methCall = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(valueType.FullName), "Parse"); methCall.Parameters.Add(new CodePrimitiveExpression(value.ToString())); rightExpr = methCall; } else { throw new HttpException(SR.GetString(SR.CantGenPropertySet, propertyInfo.Name, valueType.FullName)); } } } #if DEBUG if (WebFormsCompilation.Enabled) { Debug.Unindent(); Debug.WriteLine("}"); } #endif // DEBUG return rightExpr; } // Adds a property assignment statement to "statements". This takes into account // checking for nulls when the destination property type is a value type. This can // also generate expressions that use IAttributeAccessor when desinationType is null. internal static void CreatePropertySetStatements(CodeStatementCollection methodStatements, CodeStatementCollection statements, CodeExpression target, string targetPropertyName, Type destinationType, CodeExpression value, CodeLinePragma linePragma) { // Generates: // If destination is property: // If destination type is string: // {{target}}.{{targetPropertyName}} = System.Convert.ToString( {{value}} ); // Else If destination type is reference type: // {{target}}.{{targetPropertyName}} = ( {{destinationType}} ) {{value}}; // Else destination type is value type: // {{target}}.{{targetPropertyName}} = ( {{destinationType}} ) ({value}); // Else use SetAttribute (expandos): // ((IAttributeAccessor) {{target}} ).SetAttribute( {{targetPropertyName}} , System.Convert.ToString( {{value}} )); bool useSetAttribute = false; // This signifies it's using SetAttribute if (destinationType == null) { useSetAttribute = true; } if (useSetAttribute) { // ((IAttributeAccessor) {{target}} ).SetAttribute( {{targetPropertyName}} , System.Convert.ToString( {{value}} )); CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression(); CodeExpressionStatement setAttributeCall = new CodeExpressionStatement(methodInvoke); setAttributeCall.LinePragma = linePragma; methodInvoke.Method.TargetObject = new CodeCastExpression(typeof(IAttributeAccessor), target); methodInvoke.Method.MethodName = "SetAttribute"; methodInvoke.Parameters.Add(new CodePrimitiveExpression(targetPropertyName)); methodInvoke.Parameters.Add(GenerateConvertToString(value)); statements.Add(setAttributeCall); } else { // Use the property setter. Must take into account that null cannot be // cast to a value type, so we have to explicitly check for that in // the code we generate. if (destinationType.IsValueType) { // {{target}}.{{targetPropertyName}} = ( {{destinationType}} ) ({value}); CodeAssignStatement assignStmt = new CodeAssignStatement( BuildPropertyReferenceExpression(target, targetPropertyName), new CodeCastExpression(destinationType, value)); assignStmt.LinePragma = linePragma; statements.Add(assignStmt); } else { CodeExpression rightSide; if (destinationType == typeof(string)) { // {{target}}.{{targetPropertyName}} = System.Convert.ToString( {{value}} ); rightSide = GenerateConvertToString(value); } else { // {{target}}.{{targetPropertyName}} = ( {{destinationType}} ) {{value}}; rightSide = new CodeCastExpression(destinationType, value); } CodeAssignStatement assignStmt = new CodeAssignStatement( BuildPropertyReferenceExpression(target, targetPropertyName), rightSide); assignStmt.LinePragma = linePragma; statements.Add(assignStmt); } } } // Generate a call to System.Convert.ToString(value, CultureInfo.CurrentCulture) internal static CodeExpression GenerateConvertToString(CodeExpression value) { CodeMethodInvokeExpression invokeExpr = new CodeMethodInvokeExpression(); invokeExpr.Method.TargetObject = new CodeTypeReferenceExpression(typeof(System.Convert)); invokeExpr.Method.MethodName = "ToString"; invokeExpr.Parameters.Add(value); invokeExpr.Parameters.Add(new CodePropertyReferenceExpression( new CodeTypeReferenceExpression(typeof(CultureInfo)), "CurrentCulture")); return invokeExpr; } // Prepend a string TO the CompilerOptions string internal static void PrependCompilerOption( CompilerParameters compilParams, string compilerOptions) { if (compilParams.CompilerOptions == null) compilParams.CompilerOptions = compilerOptions; else compilParams.CompilerOptions = compilerOptions + " " + compilParams.CompilerOptions; } // Append a string to the CompilerOptions string internal static void AppendCompilerOption( CompilerParameters compilParams, string compilerOptions) { if (compilParams.CompilerOptions == null) compilParams.CompilerOptions = compilerOptions; else compilParams.CompilerOptions = compilParams.CompilerOptions + " " + compilerOptions; } internal static CodeExpression BuildPropertyReferenceExpression( CodeExpression objRefExpr, string propName) { // The name may contain several '.' separated properties, so we // need to make sure we build the CodeDom accordingly (ASURT 91875, VSWhidbey 313018) string[] parts = propName.Split('.'); CodeExpression ret = objRefExpr; foreach (string part in parts) ret = new CodePropertyReferenceExpression(ret, part); return ret; } internal static CodeCastExpression BuildJSharpCastExpression(Type castType, CodeExpression expression) { // VJ# does not support automatic boxing of value types, so passing a simple type, say a bool, into a method // expecting an object will give a compiler error. We are working around this issue by adding special code for // VJ# that will cast the expression for boxing. When the VJ# team adds implicit boxing of value types, we // should remove this code. VSWhidbey 269028 CodeCastExpression castedExpression = new CodeCastExpression(castType, expression); castedExpression.UserData.Add("CastIsBoxing", true); return castedExpression; } } }
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- QilVisitor.cs
- RunInstallerAttribute.cs
- NotFiniteNumberException.cs
- InvalidAsynchronousStateException.cs
- Utils.cs
- StyleTypedPropertyAttribute.cs
- SplitterEvent.cs
- ClientScriptManagerWrapper.cs
- AdornerHitTestResult.cs
- OdbcFactory.cs
- PeerHelpers.cs
- ManagementException.cs
- IncrementalReadDecoders.cs
- MethodImplAttribute.cs
- PersonalizationEntry.cs
- ContextMarshalException.cs
- StringFunctions.cs
- Int16KeyFrameCollection.cs
- TextPattern.cs
- mediaeventargs.cs
- XsltContext.cs
- DeviceFiltersSection.cs
- ViewStateException.cs
- ScriptReferenceEventArgs.cs
- Menu.cs
- AnyReturnReader.cs
- SevenBitStream.cs
- EventLevel.cs
- TableParagraph.cs
- StringSorter.cs
- QilInvoke.cs
- XmlObjectSerializer.cs
- GPPOINT.cs
- CustomAttributeBuilder.cs
- TypedTableGenerator.cs
- AsyncParams.cs
- StringFreezingAttribute.cs
- Simplifier.cs
- SmiTypedGetterSetter.cs
- RawStylusActions.cs
- EntityClientCacheEntry.cs
- UITypeEditor.cs
- ICollection.cs
- TextElementEnumerator.cs
- QilName.cs
- ThicknessKeyFrameCollection.cs
- PackagePart.cs
- IODescriptionAttribute.cs
- XamlUtilities.cs
- DataServiceQueryProvider.cs
- CodeCompiler.cs
- HitTestResult.cs
- Permission.cs
- codemethodreferenceexpression.cs
- MissingManifestResourceException.cs
- UpnEndpointIdentityExtension.cs
- PropertySourceInfo.cs
- ToggleButtonAutomationPeer.cs
- ObjectItemNoOpAssemblyLoader.cs
- TextElementCollectionHelper.cs
- ProxyHelper.cs
- IPCCacheManager.cs
- ToolStripItemRenderEventArgs.cs
- ToolboxItemWrapper.cs
- WebBrowserSiteBase.cs
- ToolStripAdornerWindowService.cs
- GridSplitterAutomationPeer.cs
- RequiredFieldValidator.cs
- Processor.cs
- ViewStateException.cs
- BinaryObjectInfo.cs
- SqlRetyper.cs
- PersonalizationStateInfo.cs
- ListenerConnectionModeReader.cs
- TextAdaptor.cs
- CannotUnloadAppDomainException.cs
- ObjectDataSourceMethodEventArgs.cs
- ContextDataSource.cs
- EntityTypeBase.cs
- HttpRuntime.cs
- CompositeTypefaceMetrics.cs
- UnsafeNativeMethods.cs
- XmlDataContract.cs
- ServiceModelInstallComponent.cs
- InvalidPrinterException.cs
- CodeArrayIndexerExpression.cs
- XmlDictionaryReader.cs
- UrlPropertyAttribute.cs
- ObjectToken.cs
- DecoderExceptionFallback.cs
- CreationContext.cs
- DbConnectionPool.cs
- OpenFileDialog.cs
- MenuItemBinding.cs
- XmlDataFileEditor.cs
- DisableDpiAwarenessAttribute.cs
- RuntimeIdentifierPropertyAttribute.cs
- EndpointBehaviorElementCollection.cs
- TempFiles.cs
- DrawingAttributeSerializer.cs