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); }
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); } }
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); }
internal void Unindent() { if (IsInDumpingMode) { _dumper.Unindent(); } else { DumpScript.AddUnindent(); } }
internal void DecrementMaxDepth() { if (IsInDumpingMode) { _dumper._maxDepth--; } else { DumpScript.AddDecrementMaxDepth(); } }
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); } }
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); }
public void DumpType() { if (IsInDumpingMode) { var type = Instance.GetType(); _dumper.Writer.Write( DumpFormat.Type, type.GetTypeName(), type.Namespace, type.AssemblyQualifiedName); } else { DumpScript.AddDumpType(); } }
public bool DumpedMemberInfo() { if (!(Instance is MemberInfo mi)) { return(false); } if (IsInDumpingMode) { _dumper.Writer.Dumped(Instance as MemberInfo); } else { DumpScript.AddDumpedMemberInfo(); } return(true); }
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(); }
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); }
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(); }
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); }
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); } }