public static string GetChecksum(this TypeDefinition type, TextualRepresentationOptions options)
        {
            uint            lastHash        = 0;
            StringBuilder   checksumBuilder = new StringBuilder(2 * ChecksumThreshold);
            Action <string> appendAction    = (s) =>
            {
                checksumBuilder.Append(s);
                if (checksumBuilder.Length > ChecksumThreshold)
                {
                    byte[] bytes = Encoding.ASCII.GetBytes(checksumBuilder.ToString());
                    lastHash = Crc32CAlgorithm.Append(lastHash, bytes);
                    checksumBuilder.Clear();
                }
            };

            type.GetTextualRepresentation(appendAction, options);
            // clear if something left in StringBuilder
            if (checksumBuilder.Length > 0)
            {
                byte[] bytes = Encoding.ASCII.GetBytes(checksumBuilder.ToString());
                lastHash = Crc32CAlgorithm.Append(lastHash, bytes);
                checksumBuilder.Clear();
            }
            return(lastHash.ToString());
        }
        public static string GetTextualRepresentation(this TypeDefinition type, TextualRepresentationOptions options)
        {
            StringBuilder   sb           = new StringBuilder();
            Action <string> appendAction = (s) => { sb.Append(s); };

            type.GetTextualRepresentation(appendAction, options);
            return(sb.ToString());
        }
        public static void GetTextualRepresentation(this VariableDefinition variable, Action <string> appendAction, TextualRepresentationOptions options)
        {
            if (variable == null)
            {
                return;
            }

            appendAction(variable.Index.ToString());
            appendAction(variable.IsPinned.ToString());
            appendAction(variable.Name.ToString());
            variable.VariableType.GetTextualRepresentation(appendAction, options);
        }
        public static void GetTextualRepresentation(this ExceptionHandler handler, Action <string> appendAction, TextualRepresentationOptions options)
        {
            if (handler == null)
            {
                return;
            }

            handler.CatchType.GetTextualRepresentation(appendAction, options);

            for (Instruction current = handler.HandlerStart; ; current = current.Next)
            {
                // Add Instructions inside of the handler
                current.GetTextualRepresentation(appendAction, options);
                if (current == handler.HandlerEnd)
                {
                    break;
                }
            }

            appendAction(handler.HandlerType.ToString());

            for (Instruction current = handler.TryStart; ; current = current.Next)
            {
                // Add Instructions inside of the try block
                // TODO: Check if this is already included through MethodBody.Instructions
                current.GetTextualRepresentation(appendAction, options);
                if (current == handler.TryEnd)
                {
                    break;
                }
            }

            // TODO: Check what to do with filters
            // For those who never heard what filter is :)
            // https://lostechies.com/jimmybogard/2015/07/17/c-6-exception-filters-will-improve-your-home-life/
        }
        public static void GetTextualRepresentation(this Instruction instr, Action <string> appendAction, TextualRepresentationOptions options)
        {
            if (instr == null)
            {
                return;
            }

            if (!options.UseSmartRepresentation && instr.SequencePoint != null)
            {
                appendAction(instr.SequencePoint.StartLine.ToString());
                appendAction(instr.SequencePoint.StartColumn.ToString());
                appendAction(instr.SequencePoint.EndLine.ToString());
                appendAction(instr.SequencePoint.EndColumn.ToString());
            }
            appendAction(instr.ToString());
        }
        public static void GetTextualRepresentation(this MethodBody body, Action <string> appendAction, TextualRepresentationOptions options)
        {
            if (body == null)
            {
                return;
            }

            appendAction(body.MaxStackSize.ToString());

            foreach (var instr in body.Instructions)
            {
                instr.GetTextualRepresentation(appendAction, options);
            }

            if (body.HasExceptionHandlers)
            {
                foreach (var handler in body.ExceptionHandlers)
                {
                    handler.GetTextualRepresentation(appendAction, options);
                }
            }

            if (body.HasVariables)
            {
                foreach (var variable in body.Variables)
                {
                    variable.GetTextualRepresentation(appendAction, options);
                }
            }
        }
        public static void GetTextualRepresentation(this MethodReturnType type, Action <string> appendAction, TextualRepresentationOptions options)
        {
            if (type == null)
            {
                return;
            }

            if (type.HasConstant)
            {
                appendAction(type.Constant.ToString());
            }
            if (type.HasMarshalInfo)
            {
                type.MarshalInfo.GetTextualRepresentation(appendAction, options);
            }
            if (type.HasCustomAttributes)
            {
                foreach (var attrib in type.CustomAttributes)
                {
                    attrib.GetTextualRepresentation(appendAction, options);
                }
            }
        }
 public static void GetTextualRepresentation(this PropertyDefinition property, Action <string> appendAction, TextualRepresentationOptions options)
 {
     return;
 }
        public static void GetTextualRepresentation(this TypeDefinition type, Action <string> appendAction, TextualRepresentationOptions options)
        {
            if (type == null)
            {
                return;
            }

            appendAction(type.Attributes.ToString());

            if (type.HasGenericParameters)
            {
                foreach (GenericParameter param in type.GenericParameters)
                {
                    param.GetTextualRepresentation(appendAction, options);
                }
            }
            if (type.HasInterfaces)
            {
                IEnumerable <TypeReference> interfaces = type.Interfaces;

                foreach (TypeReference inter in interfaces)
                {
                    inter.GetTextualRepresentation(appendAction, options);
                }
            }
            //if (type.HasNestedTypes)
            //{
            //    foreach (var nested in type.NestedTypes)
            //    {
            //        appendAction(nested.GetTextualRepresentation(options));
            //    }
            //}
            if (type.HasLayoutInfo)
            {
                appendAction(type.ClassSize.ToString());
            }
            if (type.HasFields)
            {
                foreach (var field in type.Fields)
                {
                    field.GetTextualRepresentation(appendAction, options);
                }
            }
            if (type.HasMethods)
            {
                IEnumerable <MethodDefinition> methods = type.Methods;
                foreach (var method in methods)
                {
                    method.GetTextualRepresentation(appendAction, options);
                }
            }
            if (type.HasProperties)
            {
                foreach (var property in type.Properties)
                {
                    property.GetTextualRepresentation(appendAction, options);
                }
            }
            if (type.HasEvents)
            {
                foreach (var ev in type.Events)
                {
                    ev.GetTextualRepresentation(appendAction, options);
                }
            }
            if (type.HasSecurityDeclarations)
            {
                foreach (var sd in type.SecurityDeclarations)
                {
                    sd.GetTextualRepresentation(appendAction, options);
                }
            }
            if (type.HasCustomAttributes)
            {
                foreach (var customAttribute in type.CustomAttributes)
                {
                    customAttribute.GetTextualRepresentation(appendAction, options);
                }
            }
        }
        public static void GetTextualRepresentation(this PInvokeInfo invokeInfo, Action <string> appendAction, TextualRepresentationOptions options)
        {
            if (invokeInfo == null)
            {
                return;
            }

            appendAction(invokeInfo.IsBestFitDisabled.ToString());
            appendAction(invokeInfo.IsBestFitEnabled.ToString());
            appendAction(invokeInfo.IsCallConvCdecl.ToString());
            appendAction(invokeInfo.IsCallConvFastcall.ToString());
            appendAction(invokeInfo.IsCallConvStdCall.ToString());
            appendAction(invokeInfo.IsCallConvThiscall.ToString());
            appendAction(invokeInfo.IsCallConvWinapi.ToString());
            appendAction(invokeInfo.IsCharSetAnsi.ToString());
            appendAction(invokeInfo.IsCharSetAuto.ToString());
            appendAction(invokeInfo.IsCharSetNotSpec.ToString());
            appendAction(invokeInfo.IsCharSetUnicode.ToString());
            appendAction(invokeInfo.IsNoMangle.ToString());
            appendAction(invokeInfo.IsThrowOnUnmappableCharDisabled.ToString());
            appendAction(invokeInfo.IsThrowOnUnmappableCharEnabled.ToString());
        }
        public static void GetTextualRepresentation(this TypeReference type, Action <string> appendAction, TextualRepresentationOptions options)
        {
            if (type == null)
            {
                return;
            }

            appendAction(type.FullName);
        }
        public static void GetTextualRepresentation(this MethodReference method, Action <string> appendAction, TextualRepresentationOptions options)
        {
            if (method == null)
            {
                return;
            }

            appendAction(method.FullName);
        }
        public static void GetTextualRepresentation(this GenericParameter parameter, Action <string> appendAction, TextualRepresentationOptions options)
        {
            if (parameter == null)
            {
                return;
            }

            if (parameter.HasConstraints)
            {
                foreach (TypeReference constraint in parameter.Constraints)
                {
                    constraint.GetTextualRepresentation(appendAction, options);
                }
            }
        }
        public static void GetTextualRepresentation(this CustomAttribute customAttribute, Action <string> appendAction, TextualRepresentationOptions options)
        {
            if (customAttribute == null)
            {
                return;
            }

            appendAction(Encoding.ASCII.GetString(customAttribute.GetBlob()));
        }
        public static void GetTextualRepresentation(this ParameterDefinition param, Action <string> appendAction, TextualRepresentationOptions options)
        {
            if (param == null)
            {
                return;
            }

            if (param.HasConstant)
            {
                // Constant could have a null value
                var constant = param.Constant ?? "";
                appendAction(constant.ToString());
            }
            if (param.HasMarshalInfo)
            {
                param.MarshalInfo.GetTextualRepresentation(appendAction, options);
            }
            if (param.HasCustomAttributes)
            {
                foreach (var attrib in param.CustomAttributes)
                {
                    attrib.GetTextualRepresentation(appendAction, options);
                }
            }
        }
 public static void GetTextualRepresentation(this EventDefinition ev, Action <string> appendAction, TextualRepresentationOptions options)
 {
     return;
 }
        public static string GetTextualRepresentation(this MarshalInfo marshalInfo, Action <string> appendAction, TextualRepresentationOptions options)
        {
            if (marshalInfo == null)
            {
                return(string.Empty);
            }

            return(marshalInfo.NativeType.ToString());
        }
        public static void GetTextualRepresentation(this SecurityDeclaration securityDeclaration, Action <string> appendAction, TextualRepresentationOptions options)
        {
            if (securityDeclaration == null)
            {
                return;
            }

            if (securityDeclaration.HasSecurityAttributes)
            {
                foreach (var attrib in securityDeclaration.SecurityAttributes)
                {
                    attrib.AttributeType.GetTextualRepresentation(appendAction, options);
                }
            }
        }
        public static void GetTextualRepresentation(this MethodDefinition method, Action <string> appendAction, TextualRepresentationOptions options)
        {
            if (method == null)
            {
                return;
            }

            if (method.HasGenericParameters)
            {
                foreach (GenericParameter param in method.GenericParameters)
                {
                    param.GetTextualRepresentation(appendAction, options);
                }
            }
            if (method.HasParameters)
            {
                foreach (ParameterDefinition param in method.Parameters)
                {
                    param.GetTextualRepresentation(appendAction, options);
                }
            }
            if (method.HasOverrides)
            {
                foreach (var overr in method.Overrides)
                {
                    overr.GetTextualRepresentation(appendAction, options);
                }
            }
            if (method.IsPInvokeImpl)
            {
                method.PInvokeInfo.GetTextualRepresentation(appendAction, options);
            }
            if (method.HasSecurityDeclarations)
            {
                foreach (var securityDeclaration in method.SecurityDeclarations)
                {
                    securityDeclaration.GetTextualRepresentation(appendAction, options);
                }
            }
            if (method.HasCustomAttributes)
            {
                foreach (var attrib in method.CustomAttributes)
                {
                    attrib.GetTextualRepresentation(appendAction, options);
                }
            }
            method.MethodReturnType.GetTextualRepresentation(appendAction, options);
            if (method.HasBody)
            {
                method.Body.GetTextualRepresentation(appendAction, options);
            }
        }
        public static void GetTextualRepresentation(this FieldDefinition field, Action <string> appendAction, TextualRepresentationOptions options)
        {
            if (field == null)
            {
                return;
            }

            if (field.HasConstant)
            {
                // TODO: Check if there are cases when this does not work
                if (field.Constant == null)
                {
                    // if constant itself is null value
                    appendAction("null");
                }
                else
                {
                    appendAction(field.Constant.ToString());
                }
            }
            if (field.HasLayoutInfo)
            {
                appendAction(field.Offset.ToString());
            }
            if (field.RVA > 0)
            {
                foreach (var b in field.InitialValue)
                {
                    appendAction(b.ToString());
                }
            }
            if (field.HasMarshalInfo)
            {
                field.MarshalInfo.GetTextualRepresentation(appendAction, options);
            }
            if (field.HasCustomAttributes)
            {
                foreach (CustomAttribute attrib in field.CustomAttributes)
                {
                    attrib.GetTextualRepresentation(appendAction, options);
                }
            }
        }