DebugInfo.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.Activities / System / Activities / Debugger / DebugInfo.cs / 1438166 / DebugInfo.cs

                            //---------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------
namespace System.Activities.Debugger
{ 
    using System;
    using System.Activities.XamlIntegration; 
    using System.Collections.Generic; 
    using System.ComponentModel;
    using System.Diagnostics; 
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using System.Linq;
    using System.Linq.Expressions; 
    using System.Runtime;
    using System.Windows.Markup; 
    using System.Xaml; 

    // Class to communicate with Workflow's Expression Evaluation. 
    class DebugInfo
    {
        ActivityInstance activityInstance;
        LocalInfo[] locals; 
        LocalInfo[] arguments;
        Dictionary cachedLocalInfos; 
 
        public DebugInfo(ActivityInstance activityInstance)
        { 
            Fx.Assert(activityInstance != null, "activityInstance cannot be null");
            this.activityInstance = activityInstance;
        }
 
        public object EvaluateExpression(string expressionString)
        { 
            // This is to shortcircuit a common case where 
            // internally, vsdebugger calls our EE with literal "0"
            int intResult; 
            if (int.TryParse(expressionString, out intResult))
            {
                return intResult;
            } 

            // At refresh, Expression Evaluator may re-evaluate locals/arguments. 
            // To speed up the process, locals/arguments are cached. 
            LocalInfo cachedLocalInfo = null;
            if (this.cachedLocalInfos != null && this.cachedLocalInfos.TryGetValue(expressionString, out cachedLocalInfo)) 
            {
                return cachedLocalInfo;
            }
 
            Activity activity = activityInstance.Activity;
            LocationReferenceEnvironment locationReferenceEnvironment = activity.PublicEnvironment; 
 
            // a temporary context for EvaluateExpression
            // We're not using the executor so it's ok that it's null 
            ActivityContext context = new ActivityContext(activityInstance, null);

            object result;
            try 
            {
                // First try as R-Value 
                if (!TryEvaluateExpression(expressionString, null, locationReferenceEnvironment, context, out result)) 
                {
                    return SR.DebugInfoCannotEvaluateExpression(expressionString); 
                }
            }
            catch (Exception ex)
            { 
                // ---- all exceptions, this exception is generated by user typing input in either
                // Watch window or Immediate windows.  Exception should not affect the current runtime. 
                // Except for fatal exception. 
                if (Fx.IsFatal(ex))
                { 
                    throw;
                }
                context.Dispose();
                return SR.DebugInfoCannotEvaluateExpression(expressionString); 
            }
 
            // Now try expression as an L-Value if possible. 
            try
            { 
                object resultLocation;
                if (TryEvaluateExpression(expressionString, result.GetType(), locationReferenceEnvironment, context, out resultLocation))
                {
                    LocalInfo localInfo = new LocalInfo() 
                                            {
                                                Name = expressionString, 
                                                Location = resultLocation as Location 
                                            };
                    this.cachedLocalInfos[expressionString] = localInfo; 
                    return localInfo;
                }
            }
            catch (Exception ex) 
            {
                // ---- all exceptions, this exception is generated by user typing input in either 
                // Watch window or Immediate windows.  Exception should not affect the current runtime. 
                // Except for fatal exception.
                if (Fx.IsFatal(ex)) 
                {
                    throw;
                }
            } 
            finally
            { 
                context.Dispose(); 
            }
            return result; 
        }

        static bool TryEvaluateExpression(
            string expressionString, 
            Type locationValueType,                             // Non null for Reference type (location)
            LocationReferenceEnvironment locationReferenceEnvironment, 
            ActivityContext context, 
            out object result)
        { 
            expressionString = string.Format(CultureInfo.InvariantCulture, "[{0}]", expressionString);

            Type activityType;
            if (locationValueType != null) 
            {
                activityType = typeof(Activity<>).MakeGenericType(typeof(Location<>).MakeGenericType(locationValueType)); 
            } 
            else
            { 
                activityType = typeof(Activity);
            }

            // General expression. 
            ActivityWithResultConverter converter = new ActivityWithResultConverter(activityType);
            ActivityWithResult expression = converter.ConvertFromString( 
                new TypeDescriptorContext { LocationReferenceEnvironment = locationReferenceEnvironment }, 
                expressionString) as ActivityWithResult;
 
            if (locationValueType != null)
            {
                Type locationHelperType = typeof(LocationHelper<>).MakeGenericType(locationValueType);
                LocationHelper helper = (LocationHelper)Activator.CreateInstance(locationHelperType); 
                return helper.TryGetValue(expression, locationReferenceEnvironment, context, out result);
            } 
            else 
            {
                return TryEvaluateExpression(expression as ActivityWithResult, locationReferenceEnvironment, context, out result); 
            }
        }

        static bool TryEvaluateExpression( 
            Activity expression,
            LocationReferenceEnvironment locationReferenceEnvironment, 
            ActivityContext context, 
            out object result)
        { 
            T value;
            if (!expression.TryGetValue(context, out value))
            {
                result = SR.DebugInfoTryGetValueFailed; 
                return false;
            } 
 
            // value is some expression type and needs to be opened
            Activity element = value as Activity; 
            context.Activity = element;
            if (element != null && !element.IsRuntimeReady)
            {
                WorkflowInspectionServices.CacheMetadata(element, locationReferenceEnvironment); 
            }
 
            IExpressionContainer container = value as IExpressionContainer; 
            if (container == null)
            { 
                result = SR.DebugInfoNotAnIExpressionContainer;
                return false;
            }
 
            Expression> lambda = container.Expression as Expression>;
            if (lambda == null) 
            { 
                result = SR.DebugInfoNoLambda;
                return false; 
            }

            result = lambda.Compile()(context);
            return true; 
        }
 
        public LocalInfo[] GetArguments() 
        {
            if (this.arguments == null || this.arguments.Length == 0) 
            {
                this.arguments =
                    activityInstance.Activity.RuntimeArguments.Select(argument =>
                        new LocalInfo 
                        {
                            Name = argument.Name, 
                            Location = argument.InternalGetLocation(activityInstance.Environment) 
                        }).ToArray();
 
                if (this.arguments.Length > 0)
                {
                    this.CacheLocalInfos(this.arguments);
                } 
            }
            return this.arguments; 
        } 

        public LocalInfo[] GetLocals() 
        {
            if (this.locals == null || this.locals.Length == 0)
            {
                Activity activity = activityInstance.Activity; 
                List allVariables = new List();
                List allArguments = new List(); 
                List allDelegateArguments = new List(); 

                HashSet existingNames = new HashSet(); 
                while (activity != null)
                {
                    allVariables.AddRange(RemoveHiddenVariables(existingNames, activity.RuntimeVariables));
                    allVariables.AddRange(RemoveHiddenVariables(existingNames, activity.ImplementationVariables)); 
                    if (activity.HandlerOf != null)
                    { 
                        allDelegateArguments.AddRange(RemoveHiddenDelegateArguments(existingNames, 
                           activity.HandlerOf.RuntimeDelegateArguments.Select(delegateArgument =>
                                delegateArgument.BoundArgument))); 
                    }
                    allArguments.AddRange(RemoveHiddenArguments(existingNames, activity.RuntimeArguments));
                    activity = activity.Parent;
                } 

                this.locals = 
                    new LocalInfo[]{ 
                                new LocalInfo
                                { 
                                    Name = "this",
                                    Type = "System.Activities.ActivityInstance",
                                    Value = activityInstance
                                } 
                            }
                        .Concat(allVariables.Select(variable => 
                            new LocalInfo 
                            {
                                Name = variable.Name, 
                                Location = variable.InternalGetLocation(activityInstance.Environment)
                            })
                        .Concat(allArguments.Select(argument =>
                            new LocalInfo 
                            {
                                Name = argument.Name, 
                                Location = argument.InternalGetLocation(activityInstance.Environment) 
                            }))
                        .Concat(allDelegateArguments.Select(argument => 
                            new LocalInfo
                            {
                                Name = argument.Name,
                                Location = argument.InternalGetLocation(activityInstance.Environment) 
                            }))
                        .OrderBy(info => info.Name)) 
                        .ToArray(); 

                if (this.locals.Length > 0) 
                {
                    this.CacheLocalInfos(this.locals);
                }
            } 
            return this.locals;
        } 
 
        // Remove ancestor's variables that are hidden because the same name already define in the current scope.
        // This will also update existingNames to include ancestor variable names that are retained. 
        static List RemoveHiddenVariables(HashSet existingNames, IEnumerable ancestorVariables)
        {
            List cleanUpList = new List();
            foreach (Variable variable in ancestorVariables) 
            {
                if (variable.Name == null) 
                { 
                    continue;
                } 

                if (!(variable.Name.StartsWith("_", StringComparison.Ordinal) ||                  // private variables that should be hidden
                        existingNames.Contains(variable.Name)))         // variable name already exists in current scope
                { 
                    cleanUpList.Add(variable);
                    existingNames.Add(variable.Name); 
                } 
            }
            return cleanUpList; 
        }

        // Remove ancestor's arguments that are hidden because the same name already define in the current scope.
        // This will also update existingNames to include ancestor delegate argument names that are retained. 
        static List RemoveHiddenDelegateArguments(HashSet existingNames, IEnumerable ancestorDelegateArguments)
        { 
            List cleanUpList = new List(); 
            foreach (DelegateArgument delegateArgument in ancestorDelegateArguments)
            { 
                if (delegateArgument != null && delegateArgument.Name != null)
                {
                    if (!existingNames.Contains(delegateArgument.Name)) // variable name already exists in current scope
                    { 
                        cleanUpList.Add(delegateArgument);
                        existingNames.Add(delegateArgument.Name); 
                    } 
                }
            } 
            return cleanUpList;
        }

        // Remove ancestor's arguments that are hidden because the same name already define in the current scope. 
        // This will also update existingNames to include ancestor argument names that are retained.
        static List RemoveHiddenArguments(HashSet existingNames, IList ancestorArguments) 
        { 
            List cleanUpList = new List(ancestorArguments.Count);
            foreach (RuntimeArgument argument in ancestorArguments) 
            {
                if (!existingNames.Contains(argument.Name))
                {
                    cleanUpList.Add(argument); 
                    existingNames.Add(argument.Name);
                } 
            } 
            return cleanUpList;
        } 

        public bool SetValueAsString(Location location, string value, string stringRadix)
        {
            bool succeed = true; 
            try
            { 
                value = value.Trim(); 

                Type t = location.LocationType; 

                if (t == typeof(string) && value.StartsWith("\"", StringComparison.Ordinal) && value.EndsWith("\"", StringComparison.Ordinal))
                {
                    location.Value = RemoveQuotes(value); 
                }
                else if (t == typeof(bool)) 
                { 
                    location.Value = Convert.ToBoolean(value, CultureInfo.InvariantCulture);
                } 
                else if (t == typeof(sbyte))
                {
                    location.Value = Convert.ToSByte(RemoveHexadecimalPrefix(value), Convert.ToInt32(stringRadix, CultureInfo.InvariantCulture));
                } 
                else if (t == typeof(char))
                { 
                    char ch; 
                    succeed = ConvertToChar(value, Convert.ToInt32(stringRadix, CultureInfo.InvariantCulture), out ch);
                    if (succeed) 
                    {
                        location.Value = ch;
                    }
                } 
                else if (t == typeof(Int16))
                { 
                    location.Value = Convert.ToInt16(RemoveHexadecimalPrefix(value), Convert.ToInt32(stringRadix, CultureInfo.InvariantCulture)); 
                }
                else if (t == typeof(Int32)) 
                {
                    location.Value = Convert.ToInt32(RemoveHexadecimalPrefix(value), Convert.ToInt32(stringRadix, CultureInfo.InvariantCulture));
                }
                else if (t == typeof(Int64)) 
                {
                    location.Value = Convert.ToInt64(RemoveHexadecimalPrefix(value), Convert.ToInt32(stringRadix, CultureInfo.InvariantCulture)); 
                } 
                else if (t == typeof(byte))
                { 
                    location.Value = Convert.ToByte(RemoveHexadecimalPrefix(value), Convert.ToInt32(stringRadix, CultureInfo.InvariantCulture));
                }
                else if (t == typeof(UInt16))
                { 
                    location.Value = Convert.ToUInt16(RemoveHexadecimalPrefix(value), Convert.ToInt32(stringRadix, CultureInfo.InvariantCulture));
                } 
                else if (t == typeof(UInt32)) 
                {
                    location.Value = Convert.ToUInt32(RemoveHexadecimalPrefix(value), Convert.ToInt32(stringRadix, CultureInfo.InvariantCulture)); 
                }
                else if (t == typeof(UInt64))
                {
                    location.Value = Convert.ToUInt64(RemoveHexadecimalPrefix(value), Convert.ToInt32(stringRadix, CultureInfo.InvariantCulture)); 
                }
                else if (t == typeof(Single)) 
                { 
                    if (!value.Contains(","))
                    { 
                        location.Value = Convert.ToSingle(value, CultureInfo.InvariantCulture);
                    }
                    else
                    { 
                        succeed = false;
                    } 
                } 
                else if (t == typeof(Double))
                { 
                    if (!value.Contains(","))
                    {
                        location.Value = Convert.ToDouble(value, CultureInfo.InvariantCulture);
                    } 
                    else
                    { 
                        succeed = false; 
                    }
                } 
                else if (t == typeof(Decimal))
                {
                    value = value.TrimEnd();
                    if (value.EndsWith("M", StringComparison.OrdinalIgnoreCase) ||  // suffix for Decimal format in C# 
                        value.EndsWith("D", StringComparison.OrdinalIgnoreCase))    // suffix for Decimal format in VB
                    { 
                        value = value.Substring(0, value.Length - 1);   // remove the suffix 
                    }
                    if (value.Contains(",")) 
                    {
                        succeed = false;
                    }
                    else 
                    {
                        location.Value = Convert.ToDecimal(value, CultureInfo.InvariantCulture); 
                    } 
                }
                else if (t == typeof(DateTime)) 
                {
                    location.Value = Convert.ToDateTime(value, CultureInfo.CurrentCulture);
                }
                else if (t.IsEnum) 
                {
                    location.Value = Enum.Parse(t, value, true); 
                } 
            }
            catch (InvalidCastException) 
            {
                succeed = false;
            }
            catch (OverflowException) 
            {
                succeed = false; 
            } 
            catch (FormatException)
            { 
                succeed = false;
            }
            catch (ArgumentOutOfRangeException)
            { 
                succeed = false;
            } 
            return succeed; 
        }
 
        // Cache local infos for faster evaluation.
        void CacheLocalInfos(LocalInfo[] localInfos)
        {
            if (this.cachedLocalInfos == null) 
            {
                this.cachedLocalInfos = new Dictionary(StringComparer.OrdinalIgnoreCase); 
            } 
            foreach (LocalInfo localInfo in localInfos)
            { 
                this.cachedLocalInfos[localInfo.Name] = localInfo;
            }
        }
 
        static string RemoveHexadecimalPrefix(string stringValue)
        { 
            stringValue = stringValue.Trim().ToUpperInvariant(); 
            if (stringValue.StartsWith("0X", StringComparison.Ordinal))
            { 
                stringValue = stringValue.Substring(2);
            }
            return stringValue;
        } 

        static string RemoveQuotes(string stringValue) 
        { 
            if (stringValue.StartsWith("\"", StringComparison.Ordinal))
            { 
                stringValue = stringValue.Substring(1);
            }
            if (stringValue.EndsWith("\"", StringComparison.Ordinal))
            { 
                stringValue = stringValue.Substring(0, stringValue.Length - 1);
            } 
            return stringValue; 
        }
 
        static bool ConvertToChar(string stringValue, int radix, out char ch)
        {
            bool succeed = false;
            ch = '\0';  // null character 
            try
            { 
                if ((stringValue[0] == '\'') || (stringValue[0] == '"'))  // VB Char is using double quote 
                {
                    if (stringValue[1] == '\\') 
                    {
                        switch (stringValue[2])
                        {
                            case '\'':  // single quote 
                            case 'a':
                            case 'b': 
                            case 'f': 
                            case 'n':
                            case 'r': 
                            case 't':
                            case 'v':
                                if (stringValue[3] == stringValue[0])     // matched single/double quote
                                { 
                                    ch = stringValue[2];
                                } 
                                succeed = true; 
                                break;
                        } 
                    }
                    else if (stringValue[2] == stringValue[0])  // matched single/double quote
                    {
                        ch = stringValue[1]; 
                        succeed = true;
                    } 
                } 
                else
                {   // It can be either an digit , e.g. 65, or 65'A'. 
                    // For the second case, we ignore the char.
                    int endIndex = stringValue.IndexOf('\'');
                    if (endIndex < 0)
                    { 
                        endIndex = stringValue.IndexOf('"');
                    } 
                    if (endIndex > 0) 
                    {
                        stringValue = stringValue.Substring(0, endIndex); 
                    }
                    ch = (char) Convert.ToUInt16(RemoveHexadecimalPrefix(stringValue), radix);
                    succeed = true;
                } 
            }
            catch (IndexOutOfRangeException) 
            {   // Invalid character length 
                succeed = false;
            } 
            return succeed;
        }

 
        public class LocalInfo
        { 
            string type; 
            object valueField;
            public string Name; 
            public Location Location;

            [SuppressMessage(FxCop.Category.Performance, FxCop.Rule.AvoidUncalledPrivateCode, Justification = "Called by Expression Evaluator")]
            public object Value 
            {
                get 
                { 
                    if (this.Location != null)
                    { 
                        return this.Location.Value;
                    }
                    return this.valueField;
                } 
                set
                { 
                    this.valueField = value; 
                }
            } 

            [SuppressMessage(FxCop.Category.Performance, FxCop.Rule.AvoidUncalledPrivateCode, Justification = "Called by Expression Evaluator")]
            public string Type
            { 
                get
                { 
                    if (this.Location != null) 
                    {
                        return this.Location.LocationType.Name; 
                    }
                    return this.type;
                }
                set 
                {
                    this.type = value; 
                } 

            } 


        }
 

        class TypeDescriptorContext : ITypeDescriptorContext, IXamlNamespaceResolver, INameScope, INamespacePrefixLookup 
        { 
            public LocationReferenceEnvironment LocationReferenceEnvironment;
 
            public IContainer Container
            {
                get { throw FxTrace.Exception.AsError(new NotImplementedException()); }
            } 

            public object Instance 
            { 
                get { throw FxTrace.Exception.AsError(new NotImplementedException()); }
            } 

            public PropertyDescriptor PropertyDescriptor
            {
                get { throw FxTrace.Exception.AsError(new NotImplementedException()); } 
            }
 
 
            public void OnComponentChanged()
            { 
                throw FxTrace.Exception.AsError(new NotImplementedException());
            }

            public bool OnComponentChanging() 
            {
                throw FxTrace.Exception.AsError(new NotImplementedException()); 
            } 

            public object GetService(Type serviceType) 
            {
                if (serviceType.IsAssignableFrom(typeof(TypeDescriptorContext)))
                {
                    return this; 
                }
                return null; 
            } 

 
            public string GetNamespace(string prefix)
            {
                if (string.IsNullOrEmpty(prefix))
                { 
                    return String.Empty;
                } 
                throw FxTrace.Exception.AsError(new NotImplementedException()); 
            }
 
            public object FindName(string name)
            {
                LocationReference result;
                if (LocationReferenceEnvironment.TryGetLocationReference(name, out result)) 
                {
                    return result; 
                } 

                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.VariableOrArgumentDoesNotExist(name))); 
            }

            public void RegisterName(string name, object scopedElement)
            { 
                throw FxTrace.Exception.AsError(new NotImplementedException());
            } 
 
            public void UnregisterName(string name)
            { 
                throw FxTrace.Exception.AsError(new NotImplementedException());
            }

            public string LookupPrefix(string name) 
            {
                throw FxTrace.Exception.AsError(new NotImplementedException()); 
            } 

            public IEnumerable GetNamespacePrefixes() 
            {
                return Enumerable.Empty();
            }
        } 

        // to perform the generics dance around Locations we need these helpers 
        abstract class LocationHelper 
        {
            public abstract bool TryGetValue(Activity expression, LocationReferenceEnvironment locationReferenceEnvironment, ActivityContext context, out object result); 
        }

        class LocationHelper : LocationHelper
        { 
            public override bool TryGetValue(Activity expression, LocationReferenceEnvironment locationReferenceEnvironment, ActivityContext context, out object result)
            { 
                Activity> activity = expression as Activity>; 
                result = null;
                if (activity != null) 
                {
                    context.Activity = expression;
                    if (activity != null && !activity.IsRuntimeReady)
                    { 
                        WorkflowInspectionServices.CacheMetadata(activity, locationReferenceEnvironment);
                    } 
                    Location locValue; 
                    if (activity.TryGetValue(context, out locValue))
                    { 
                        result = locValue;
                        return true;
                    }
                } 
                return false;
            } 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK