Ejemplo n.º 1
0
        private static void     DrawStackFrame(int i, string a, string filepath, bool fileExist)
        {
            StackTraceSettings settings = HQ.Settings.Get <StackTraceSettings>();
            Rect  r     = GUILayoutUtility.GetRect(0F, settings.height, settings.Style);
            float width = r.width;

            // Substract viewRect to avoid scrollbar.
            r.height = settings.height;

            // Display the stack trace.
            r.width = width - 16F;
            FrameBuilder.Clear();
            FrameBuilder.returnType    = "Void";
            FrameBuilder.namespaceName = "namespace";
            FrameBuilder.classType     = "class";
            FrameBuilder.methodName    = "func";
            FrameBuilder.fileName      = filepath;
            FrameBuilder.fileExist     = fileExist;
            FrameBuilder.line          = 1234;
            FrameBuilder.parameterTypes.Add("Rect");
            FrameBuilder.parameterNames.Add("r");
            FrameBuilder.parameterTypes.Add("int");
            FrameBuilder.parameterNames.Add("a");

            if (i == 0)
            {
                GUI.Button(r, FrameBuilder.ToString("→ ", settings), settings.Style);
            }
            else
            {
                GUI.Button(r, FrameBuilder.ToString("↑ ", settings), settings.Style);
            }

            r.x     = r.width;
            r.width = 16F;
            GUI.Button(r, "+", settings.Style);

            r.y += r.height;
        }
Ejemplo n.º 2
0
        private Frame   ParseStackFrame(string raw, int n)
        {
            Frame frame = new Frame();

            frame.raw = raw;

            FrameBuilder.Clear();

            StringBuilder buffer = Utility.GetBuffer();

            try
            {
                // Exception/Error log.
                if ((this.log.mode & (Mode.ScriptingException |
                                      Mode.ScriptingError |
                                      Mode.Error |
                                      Mode.Fatal |
                                      Mode.GraphCompileError)) != 0)
                {
                    buffer.Append(raw);

                    // For convenience, just convert it to a normal log, using the StringBuilder, also for convenience.
                    int lastDot = 0;
                    for (int i = 0; i < buffer.Length; ++i)
                    {
                        // Detect next symbol, skip constructors and static constructors. (".ctor" and ".cctor")
                        if (buffer[i] == '.' &&
                            i > 0 &&
                            buffer[i - 1] != '.' &&
                            buffer[i - 1] != ':')
                        {
                            lastDot = i;
                        }
                        else if (buffer[i] == ':')
                        {
                            lastDot = i;
                        }
                        // Delete any spaces before parameters.
                        else if (buffer[i] == ' ')
                        {
                            buffer.Remove(i, 1);
                            --i;
                        }

                        // Find start of method and avoid special prefix starting with a parenthese.
                        if (buffer[i] == '(' && i > 0)
                        {
                            buffer[lastDot] = ':';
                            break;
                        }
                    }

                    raw           = buffer.ToString();
                    buffer.Length = 0;
                }

                // Handle "Rethrow as Exception:"
                if (raw.StartsWith("Rethrow") == true)
                {
                    return(null);
                }

                // Too much stacks get truncated possibly anywhere.
                if (raw.EndsWith("<messagetruncated>") == true || raw.EndsWith("<message truncated>") == true || raw.EndsWith("<message truncated") == true)
                {
                    return(null);
                }

                //InternalNGDebug.LogFile("raw="+raw);

                StackTraceSettings stackTrace = HQ.Settings.Get <StackTraceSettings>();

                bool unreachableFrame = false;

                int endClass = raw.IndexOf(':');
                FrameBuilder.classType = raw.Substring(0, endClass);

                int endMethod = raw.IndexOf('(', endClass);
                FrameBuilder.methodName = raw.Substring(endClass + 1, endMethod - endClass - 1);

                int    endParameters = raw.IndexOf(')', endMethod);
                string allParameters = raw.Substring(endMethod + 1, endParameters - endMethod - 1);

                int startFilepath = raw.IndexOf("at ", endMethod);

                // Handle yield context, i.e. "Namespace.Class.<Method>c__Iterator23:MoveNext".
                if (FrameBuilder.classType.Contains("<") == true)
                {
                    unreachableFrame = true;
                    buffer.Append(FrameBuilder.classType);

                    int startYieldMethod = FrameBuilder.classType.IndexOf('<');
                    int endYieldMethod   = FrameBuilder.classType.IndexOf('>');

                    buffer.Remove(endYieldMethod, buffer.Length - endYieldMethod);
                    buffer.Remove(0, startYieldMethod + 1);

                    if (stackTrace.displayReturnValue == true)
                    {
                        FrameBuilder.returnType = "YieldInstruction";
                    }

                    FrameBuilder.classType  = "";
                    FrameBuilder.methodName = buffer.ToString();

                    buffer.Length = 0;
                }
                // Handle special prefix, i.e. "(wrapper remoting-invoke-with-check) Namespace.Class".
                else if (FrameBuilder.classType.Contains("(") == true)
                {
                    buffer.Append(FrameBuilder.classType);
                    buffer.Remove(0, FrameBuilder.classType.IndexOf(')') + 1);
                    FrameBuilder.classType = buffer.ToString();

                    buffer.Length = 0;
                }
                // Handle generic method, i.e. "Namespace.Class.Method[Type]".
                else if (FrameBuilder.methodName.Contains("[") == true)
                {
                    buffer.Append(FrameBuilder.methodName);

                    int startGenericType = FrameBuilder.methodName.IndexOf('[');
                    int endGenericType   = FrameBuilder.methodName.LastIndexOf(']');

                    buffer.Remove(startGenericType, endGenericType - startGenericType + 1);

                    FrameBuilder.methodName = buffer.ToString();

                    buffer.Length = 0;
                }

                // Split namespace from class.
                int m = FrameBuilder.classType.LastIndexOf('.');
                if (m != -1)
                {
                    FrameBuilder.namespaceName = FrameBuilder.classType.Substring(0, m);
                    FrameBuilder.classType     = FrameBuilder.classType.Substring(m + 1);
                }

                //InternalNGDebug.LogFile("class=" + FrameBuilder.classType);
                //InternalNGDebug.LogFile("method=" + FrameBuilder.methodName);
                //InternalNGDebug.LogFile("param=" + allParameters);

                if (startFilepath != -1)
                {
                    int    endFilepath = raw.LastIndexOf(':', raw.Length - 1);
                    string filepath    = raw.Substring(startFilepath + 3, endFilepath - startFilepath - 3);

                    int    endLine = raw.IndexOf(')', endFilepath);
                    string line    = raw.Substring(endFilepath + 1, endLine - endFilepath - 1);

                    // Skip non-editable frame.
                    frame.fileExist = ConsoleUtility.files.FileExist(filepath);
                    if (frame.fileExist == false &&
                        stackTrace.skipUnreachableFrame == true)
                    {
                        return(null);
                    }

                    frame.fileName         = filepath;
                    frame.line             = int.Parse(line);
                    FrameBuilder.fileExist = frame.fileExist;
                    //InternalNGDebug.LogFile("filepath="+filepath);
                    //InternalNGDebug.LogFile("line=" + int.Parse(line));
                }
                // It is not guaranteed that the fileName is the first frame. Use it in the only case of total failure. i.e. Debug.Log*()
                else if (string.IsNullOrEmpty(this.log.file) == true && n == 0)
                {
                    frame.fileName = this.log.file;
                    frame.line     = this.log.line;
                }
                else
                {
                    frame.fileName = string.Empty;
                }

                FrameBuilder.fileName = frame.fileName;
                FrameBuilder.line     = frame.line;

                if (FrameBuilder.classType == string.Empty &&
                    string.IsNullOrEmpty(frame.fileName) == true)
                {
                    return(null);
                }

                if (unreachableFrame == false &&
                    (stackTrace.displayReturnValue == true ||
                     stackTrace.displayArgumentName == true))
                {
                    FastClassCache.HashClass classType = ConsoleUtility.classes.GetType(FrameBuilder.namespaceName, FrameBuilder.classType);

                    if (classType != null)
                    {
                        if (FrameBuilder.methodName == ".cctor" ||                         // Static constructor.
                            FrameBuilder.methodName == ".ctor")                            // Normal constructor.
                        {
                            string[] parameters = allParameters.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                            // Many parameters includes ambiguity.
                            if (parameters.Length > 0 && classType.type != null)
                            {
                                ConstructorInfo ci = this.GetConstructorFromParameters(classType.type, parameters);

                                // Append data from the found constructor.
                                if (ci != null)
                                {
                                    FrameBuilder.namespaceName = ci.ReflectedType.Namespace;
                                    FrameBuilder.classType     = ci.ReflectedType.Name;

                                    if (stackTrace.displayArgumentType == true ||
                                        stackTrace.displayArgumentName == true)
                                    {
                                        this.AppendParameters(ci.GetParameters());
                                    }
                                }
                                // Append every data as we can from the condition.
                                else
                                {
                                    this.AddConditionParameters(parameters);
                                }
                            }
                        }
                        else if (classType.methods != null)
                        {
                            MethodInfo methodInfo = classType.methods.GetMethod(FrameBuilder.methodName, allParameters);

                            // Append data from the found method.
                            if (methodInfo != null)
                            {
                                FrameBuilder.isStaticMethod = methodInfo.IsStatic;

                                NGLoggerAttribute[] attributes = methodInfo.GetCustomAttributes(typeof(NGLoggerAttribute), false) as NGLoggerAttribute[];
                                if (attributes.Length > 0)
                                {
                                    frame.category = attributes[0].tag;
                                }

                                if (stackTrace.displayReturnValue == true)
                                {
                                    FrameBuilder.returnType = methodInfo.ReturnType.Name;
                                }

                                if (methodInfo.ReflectedType.IsGenericTypeDefinition == true)
                                {
                                    m = FrameBuilder.classType.IndexOf("[");

                                    if (m != -1)
                                    {
                                        string[] genericTypes = FrameBuilder.classType.Substring(m + 1, FrameBuilder.classType.Length - m - 2).Split(',');                                                // Removed the 2 brackets.

                                        for (int i = 0; i < genericTypes.Length; i++)
                                        {
                                            Type type = Utility.GetType(genericTypes[i]);

                                            if (type != null)
                                            {
                                                FrameBuilder.genericTypes.Add(type.Name);
                                            }
                                            else
                                            {
                                                FrameBuilder.genericTypes.Add(genericTypes[i]);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        foreach (var type in methodInfo.ReflectedType.GetGenericArguments())
                                        {
                                            FrameBuilder.genericTypes.Add(type.Name);
                                        }
                                    }
                                }

                                FrameBuilder.namespaceName = methodInfo.ReflectedType.Namespace;
                                FrameBuilder.classType     = methodInfo.ReflectedType.Name;
                                FrameBuilder.methodName    = methodInfo.Name;

                                if (stackTrace.displayArgumentType == true ||
                                    stackTrace.displayArgumentName == true)
                                {
                                    this.AppendParameters(methodInfo.GetParameters());
                                }
                            }
                            // Append every data as we can from the condition.
                            else
                            {
                                string[] parameters = allParameters.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                                this.AddConditionParameters(parameters);
                            }
                        }
                    }
                }

                // Get custom Category from NGSettings, it does not have priority over attribute!
                if (frame.category == null)
                {
                    string methodName = FrameBuilder.namespaceName + '.' + FrameBuilder.classType + ':' + FrameBuilder.methodName;

                    for (int i = 0; i < stackTrace.categories.Count; i++)
                    {
                        if (stackTrace.categories[i].method == methodName)
                        {
                            frame.category = stackTrace.categories[i].category;
                            break;
                        }
                    }
                }

                if (n == 0)
                {
                    frame.frameString = FrameBuilder.ToString("→ ", stackTrace);
                }
                else
                {
                    frame.frameString = FrameBuilder.ToString("↑ ", stackTrace);
                }

                //if (HQ.Settings.general.horizontalScrollbar == true)
                //{
                //	// Calcul max width
                //	Utility.content.text = frame.frameString;
                //	Vector2	size = HQ.Settings.stackTrace.style.CalcSize(Utility.content);
                //	if (this.maxWidthFrame < size.x)
                //		this.maxWidthFrame = size.x;
                //}
            }
            catch (Exception ex)
            {
                InternalNGDebug.LogFileException("Raw " + n + "=" + raw + Environment.NewLine + FrameBuilder.ToRawString(), ex);
                InternalNGDebug.LogFile(frame.frameString);
                return(null);
            }
            finally
            {
                Utility.RestoreBuffer(buffer);
            }

            return(frame);
        }