Пример #1
0
        internal static Script Add(
            ObjectTextDumper objectTextDumper,
            Type objectType,
            ClassDumpData classDumpData,
            DumpScript _dumpScript)
        {
            if (objectTextDumper == null)
            {
                throw new ArgumentNullException(nameof(objectTextDumper));
            }
            if (objectType == null)
            {
                throw new ArgumentNullException(nameof(objectType));
            }
            if (_dumpScript == null)
            {
                throw new ArgumentNullException(nameof(_dumpScript));
            }

            var lookup = new ScriptLookup(objectType, classDumpData, objectTextDumper);
            var script = _dumpScript.GetScriptAction();

            _sync.EnterWriteLock();

            _cache[lookup] = script;
            _buildingNow.Remove(lookup);

            _sync.ExitWriteLock();

            return(script);
        }
Пример #2
0
        public void DumpExpressionCSharpText()
        {
            var expression = Instance as Expression;

            if (expression == null || _dumper.IsSubExpression)
            {
                return;
            }

            // this is the highest level expression. all
            _dumper.IsSubExpression = true;

            var cSharpText = expression.DumpCSharpText();

            if (IsInDumpingMode)
            {
                _dumper.Indent();
                _dumper.Writer.WriteLine();
                _dumper.Writer.Write(DumpFormat.CSharpDumpLabel);
                _dumper.Indent();
                _dumper.Writer.WriteLine();
                _dumper.Writer.Write(cSharpText);
                _dumper.Unindent();
                _dumper.Unindent();
            }
            else
            {
                DumpScript.AddDumpExpressionText(cSharpText);
            }
        }
Пример #3
0
        public bool DumpedDelegate()
        {
            if (!typeof(Delegate).IsAssignableFrom(CurrentType))
            {
                return(false);
            }

            // it will be dumped at the descendant level
            if (CurrentType == typeof(MulticastDelegate) ||
                CurrentType == typeof(Delegate))
            {
                return(true);
            }

            if (Instance == null)
            {
                return(false);
            }

            if (IsInDumpingMode)
            {
                _dumper.Writer.Dumped((Delegate)Instance);
            }
            else
            {
                DumpScript.AddDumpedDelegate();
            }

            return(true);
        }
Пример #4
0
 internal void Unindent()
 {
     if (IsInDumpingMode)
     {
         _dumper.Unindent();
     }
     else
     {
         DumpScript.AddUnindent();
     }
 }
Пример #5
0
 internal void DecrementMaxDepth()
 {
     if (IsInDumpingMode)
     {
         _dumper._maxDepth--;
     }
     else
     {
         DumpScript.AddDecrementMaxDepth();
     }
 }
Пример #6
0
        bool DumpedSequence(
            IEnumerable sequence,
            MemberInfo mi,
            DumpAttribute dumpAttribute,
            bool enumerateCustom  = false,
            bool newLineForCustom = false)
        {
            if (sequence == null)
            {
                throw new ArgumentNullException(nameof(sequence));
            }
            if (dumpAttribute == null)
            {
                throw new ArgumentNullException(nameof(dumpAttribute));
            }

            var sequenceType = sequence.GetType();
            var isCustom     = !sequenceType.IsArray && !sequenceType.IsFromSystem();
            var dumpCustom   = enumerateCustom && dumpAttribute.Enumerate == ShouldDump.Dump;

            if (isCustom && !dumpCustom)
            {
                return(false);
            }

            if (IsInDumpingMode)
            {
                if (isCustom && newLineForCustom)
                {
                    _dumper.Writer.WriteLine();
                }

                return(_dumper.Writer.DumpedCollection(
                           sequence,
                           dumpAttribute,
                           o => _dumper.DumpObject(o, null, null, this),
                           _dumper.Indent,
                           _dumper.Unindent));
            }
            else
            {
                if (mi != null)
                {
                    DumpScript.AddDumpedCollection(mi, dumpAttribute);
                }
                else
                {
                    DumpScript.AddDumpedCollection(dumpAttribute);
                }

                return(true);
            }
        }
Пример #7
0
        bool DumpedDictionary(
            IEnumerable sequence,
            MemberInfo mi,
            DumpAttribute dumpAttribute)
        {
            if (sequence == null)
            {
                throw new ArgumentNullException(nameof(sequence));
            }
            if (dumpAttribute == null)
            {
                throw new ArgumentNullException(nameof(dumpAttribute));
            }

            if (sequence.IsDynamicObject())
            {
                return(false);
            }

            if (IsInDumpingMode)
            {
                return(_dumper.Writer.DumpedDictionary(
                           sequence,
                           dumpAttribute,
                           o => _dumper.DumpObject(o, null, null, this),
                           _dumper.Indent,
                           _dumper.Unindent));
            }
            else
            {
                if (sequence.GetType().DictionaryTypeArguments() == null)
                {
                    return(false);
                }

                if (mi != null)
                {
                    DumpScript.AddDumpedDictionary(mi, dumpAttribute);
                }
                else
                {
                    DumpScript.AddDumpedDictionary(dumpAttribute);
                }
            }

            return(true);
        }
Пример #8
0
        public void DumpType()
        {
            if (IsInDumpingMode)
            {
                var type = Instance.GetType();

                _dumper.Writer.Write(
                    DumpFormat.Type,
                    type.GetTypeName(),
                    type.Namespace,
                    type.AssemblyQualifiedName);
            }
            else
            {
                DumpScript.AddDumpType();
            }
        }
Пример #9
0
        public bool DumpedMemberInfo()
        {
            if (!(Instance is MemberInfo mi))
            {
                return(false);
            }

            if (IsInDumpingMode)
            {
                _dumper.Writer.Dumped(Instance as MemberInfo);
            }
            else
            {
                DumpScript.AddDumpedMemberInfo();
            }

            return(true);
        }
Пример #10
0
        private DumpState(
            ObjectTextDumper dumper,
            object instance,
            Type type,
            ClassDumpData classDumpData,
            DumpAttribute instanceDumpAttribute,
            DumpScript dumpScript,
            bool isTopLevelClass)
        {
            _dumper               = dumper ?? throw new ArgumentNullException(nameof(dumper));
            _isTopLevelClass      = isTopLevelClass;
            Instance              = instance ?? throw new ArgumentNullException(nameof(instance));
            InstanceType          = instance.GetType();
            CurrentType           = type ?? throw new ArgumentNullException(nameof(type));
            ClassDumpData         = classDumpData;
            InstanceDumpAttribute = instanceDumpAttribute ?? throw new ArgumentNullException(nameof(instanceDumpAttribute));
            DumpScript            = dumpScript;

            if (_isTopLevelClass)
            {
                var defaultProperty = DefaultProperty;

                if (!defaultProperty.IsNullOrWhiteSpace())
                {
                    var pi = CurrentType.GetProperty(defaultProperty);

                    Enumerator = pi != null
                                    ? (new MemberInfo[] { pi }).AsEnumerable().GetEnumerator()
                                    : (new MemberInfo[] { }).AsEnumerable().GetEnumerator();
                    return;
                }
            }

            Enumerator = CurrentType.GetProperties(_dumper.PropertiesBindingFlags | BindingFlags.DeclaredOnly)
                         .Union <MemberInfo>(
                CurrentType.GetFields(_dumper.FieldsBindingFlags | BindingFlags.DeclaredOnly))
                         .Where(mi => !mi.Name.StartsWith("<", StringComparison.Ordinal))
                         .OrderBy(p => p, ServiceResolver
                                  .Default
                                  .GetInstance <IMemberInfoComparer>()
                                  .SetMetadata(ClassDumpData.Metadata))
                         .GetEnumerator();
        }
Пример #11
0
        public bool DumpedMemberInfo()
        {
            var mi = Instance as MemberInfo;

            if (mi == null)
            {
                return(false);
            }

            if (IsInDumpingMode)
            {
                _dumper.Writer.Dumped(Instance as MemberInfo);
            }
            else
            {
                DumpScript.AddDumpedMemberInfo();
            }

            return(true);
        }
Пример #12
0
        public DumpState(
            ObjectTextDumper dumper,
            object instance,
            ClassDumpData classDumpData,
            bool buildScript)
            : this(dumper, instance, instance.GetType(), classDumpData, classDumpData.DumpAttribute, null, true)
        {
            if (dumper == null)
            {
                throw new ArgumentNullException(nameof(dumper));
            }
            if (instance == null)
            {
                throw new ArgumentNullException(nameof(instance));
            }

            // let's not create script if we don't need it or are not doing anything here.
            if (buildScript && CurrentType != typeof(object))
            {
                DumpScript = new DumpScript(instance.GetType());
            }

            DecrementMaxDepth();
        }
Пример #13
0
        bool DumpedPropertyCustom(
            object value,
            Type type)
        {
            if (value == null)
            {
                return(false);
            }

            // did they specify DumpAttribute.ValueFormat="ToString"?
            if (CurrentPropertyDumpAttribute.ValueFormat == Resources.ValueFormatToString)
            {
                if (IsInDumpingMode)
                {
                    _dumper.Writer.Write(value.ToString());
                }
                else
                {
                    DumpScript.AddCustomDumpPropertyOrField(CurrentProperty, null);
                }

                return(true);
            }

            // did they specify DumpAttribute.DumpMethod?
            var dumpMethodName = CurrentPropertyDumpAttribute.DumpMethod;
            var dumpClass      = CurrentPropertyDumpAttribute.DumpClass;

            if (dumpClass == null && dumpMethodName.IsNullOrWhiteSpace())
            {
                return(false);
            }

            if (dumpMethodName.IsNullOrWhiteSpace())
            {
                dumpMethodName = "Dump";
            }

            MethodInfo dumpMethod  = null; // best match
            MethodInfo dumpMethod2 = null; // second best

            // try the external class if specified
            if (dumpClass != null)
            {
                foreach (var mi in dumpClass.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
                         .Where(mi => mi.Name == dumpMethodName &&
                                mi.ReturnType == typeof(string) &&
                                mi.GetParameters().Count() == 1))
                {
                    if (mi.GetParameters()[0].ParameterType == type)
                    {
                        // exact match
                        dumpMethod = mi;
                        break;
                    }

                    if (mi.GetParameters()[0].ParameterType.IsAssignableFrom(type))
                    {
                        // candidate
                        dumpMethod = mi;
                    }
                }

                if (dumpMethod != null)
                {
                    if (IsInDumpingMode)
                    {
                        _dumper.Writer.Write((string)dumpMethod.Invoke(null, new object[] { value }));
                    }
                    else
                    {
                        DumpScript.AddCustomDumpPropertyOrField(CurrentProperty, dumpMethod);
                    }
                }
                else
                {
                    var message0 = string.Format(CultureInfo.InvariantCulture, Resources.CouldNotFindCustomDumpers, dumpMethodName, type.FullName, dumpClass.FullName);

                    if (IsInDumpingMode)
                    {
                        _dumper.Writer.Write(message0);
                    }
                    else
                    {
                        DumpScript.AddWrite(message0);
                    }
                }

                return(true);
            }

            // try the property's class or base class, or metadata class
            foreach (var mi in type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy)
                     .Where(mi => mi.Name == dumpMethodName &&
                            mi.ReturnType == typeof(string))
                     .Union(
                         type.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
                         .Where(mi => mi.Name == dumpMethodName &&
                                mi.ReturnType == typeof(string) &&
                                mi.GetParameters().Count() == 1))
                     .Union(
                         ClassDumpData.Metadata
                         .GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
                         .Where(mi => mi.Name == dumpMethodName &&
                                mi.ReturnType == typeof(string) &&
                                mi.GetParameters().Count() == 1)))
            {
                // found an instance method
                if (!mi.IsStatic && mi.GetParameters().Count() == 0)
                {
                    dumpMethod = mi;
                    break;
                }

                if (mi.IsStatic)
                {
                    if (mi.GetParameters()[0].ParameterType == type)
                    {
                        dumpMethod = mi;
                    }
                    else
                    {
                        if (mi.GetParameters()[0].ParameterType.IsAssignableFrom(type))
                        {
                            dumpMethod2 = mi;
                        }
                    }
                }
            }

            if (dumpMethod == null)
            {
                dumpMethod = dumpMethod2;
            }

            if (dumpMethod != null)
            {
                if (IsInDumpingMode)
                {
                    var text = dumpMethod.IsStatic
                                    ? (string)dumpMethod.Invoke(null, new object[] { value })
                                    : (string)dumpMethod.Invoke(value, null);

                    _dumper.Writer.Write(text);
                }
                else
                {
                    DumpScript.AddCustomDumpPropertyOrField(CurrentProperty, dumpMethod);
                }

                return(true);
            }

            var message = string.Format(CultureInfo.InvariantCulture, Resources.CouldNotFindCustomDumpers, dumpMethodName, type.FullName, type.FullName);

            if (IsInDumpingMode)
            {
                _dumper.Writer.Write(message);
            }
            else
            {
                DumpScript.AddWrite(message);
            }

            return(true);
        }
Пример #14
0
        public void DumpProperty()
        {
            // should we dump it at all?
            if (!CurrentProperty.CanRead() || CurrentPropertyDumpAttribute.Skip == ShouldDump.Skip)
            {
                return;
            }

            var pi = CurrentProperty as PropertyInfo;

            // can't dump indexers
            if (pi != null && pi.GetIndexParameters().Length > 0)
            {
                return;
            }

            if (pi != null && pi.IsVirtual())
            {
                // for virtual properties dump the instance value at the the least derived class level that declares the property for first time.
                if (CurrentType.BaseType.GetProperty(CurrentProperty.Name, _dumper.PropertiesBindingFlags) != null)
                {
                    return;
                }

                pi = InstanceType.GetProperty(CurrentProperty.Name, _dumper.PropertiesBindingFlags);
            }

            var    fi    = CurrentProperty as FieldInfo;
            Type   type  = null;
            object value = null;

            try
            {
                if (pi != null)
                {
                    type  = pi.PropertyType;
                    value = pi.GetValue(Instance, null);
                }
                else
                {
                    type  = fi.FieldType;
                    value = fi.GetValue(Instance);
                }
            }
            catch (Exception x)
            {
                // this should not happen but...
                value = $"<{x.Message}>";
            }

            var dontDumpNulls = CurrentPropertyDumpAttribute.DumpNullValues == ShouldDump.Skip ||
                                CurrentPropertyDumpAttribute.DumpNullValues == ShouldDump.Default && DumpNullValues == ShouldDump.Skip;

            if (IsInDumpingMode)
            {
                // should we dump a null value of the current property
                if (value == null && dontDumpNulls)
                {
                    return;
                }

                // write the property header
                _dumper.Writer.WriteLine();
                _dumper.Writer.Write(
                    CurrentPropertyDumpAttribute.LabelFormat,
                    CurrentProperty.Name);

                if (!(DumpedPropertyCustom(value, type) ||                                           // dump the property value using caller's customization (see ValueFormat="ToString", DumpClass, DumpMethod) if any.
                      _dumper.Writer.DumpedBasicValue(value, CurrentPropertyDumpAttribute) ||
                      _dumper.Writer.DumpedBasicNullable(value, CurrentPropertyDumpAttribute) ||
                      _dumper.Writer.Dumped(value as Delegate) ||
                      _dumper.Writer.Dumped(value as MemberInfo) ||
                      DumpedCollection(value, CurrentProperty, CurrentPropertyDumpAttribute)))
                {
                    // dump a property representing an associated class or struct object
                    var currentPropertyDumpAttribute = !CurrentPropertyDumpAttribute.IsDefaultAttribute() ? CurrentPropertyDumpAttribute : null;

                    _dumper.DumpObject(value, null, currentPropertyDumpAttribute, this);
                }
            }
            else
            {
                // write the property header
                DumpScript.BeginDumpProperty(CurrentProperty, CurrentPropertyDumpAttribute);

                if (!DumpedPropertyCustom(value, type))                                             // dump the property value using caller's customization (see ValueFormat="ToString", DumpClass, DumpMethod) if any.
                {
                    DumpScript.AddDumpPropertyOrCollectionValue(CurrentProperty, CurrentPropertyDumpAttribute);
                }

                DumpScript.EndDumpProperty(CurrentProperty, dontDumpNulls);
            }
        }