private void AddMethod(string className, string methodName, Assign ass)
        {
            JSClassItem classItem = _classLookup[className] as JSClassItem;

            if (classItem == null)
            {
                // We haven't defined this type yet, do so here.
                classItem = new JSClassItem(className, className, _fileItem);
                //classItem.Icon = Properties.Resources.JSClassItem;
                _fileItem.Classes.Add(classItem);

                _classLookup.Add(className, classItem);
                _projectBrowser.AddLookup(classItem, classItem.GetID(), _invert);
            }

// TODO methods need parent method ids in their ids, e.g. Hierarchy.js is breaking

            JSMethodItem methodItem = new JSMethodItem(methodName + "()", classItem);

            //methodItem.Icon = Properties.Resources.JSMethodItem;
            methodItem.MethodInfo = ass.right;
            classItem.Methods.Add(methodItem);
            _projectBrowser.AddLookup(methodItem, methodItem.GetID(), _invert);
        }
        private void ParseAst(AST ast, string sp)
        {
            if (ast == null) return;

            //_logView.LogStr("JS->" + sp + ast.ToString() + "\t\t" + ast.GetType().Name);

            if (ast is Function)
            {
                Function func = ast as Function;

                JSMethodItem methodItem = new JSMethodItem(func.func_obj.name + "()", _fileItem);
                //methodItem.Icon = Properties.Resources.JSMethodItem;
                methodItem.MethodInfo = ast;

                _fileItem.Methods.Add(methodItem);
                _projectBrowser.AddLookup(methodItem, methodItem.GetID(), _invert);

                _currentMethodStack.Insert(0, func.func_obj.name);

                ParseAstList(func.func_obj.body.elems, sp + "  ");

                _currentMethodStack.RemoveAt(0);
            }
            else if (ast is Assign)
            {
                Assign ass = ast as Assign;

                if ((ass.left is Binary) && (ass.right is FunctionExpression))
                {
                    // Can't see useful properties on this, except ToString().
                    string[] parts = ass.left.ToString().Split('.');
                    if (parts.Length > 2 && parts[1] == "prototype")
                    {
                        // We've found a class method, prototype style.
                        string className = parts[0];
                        string methodName = parts[2];

                        AddMethod(className, methodName, ass);
                    }
                    else if (parts.Length > 2 && parts[2] == "This")
                    {
                        string className = _currentMethodStack[0];
                        string methodName = parts[3];

                        AddMethod(className, methodName, ass);
                    }

                }
            }
            else if (ast is Expression)
            {
                Expression expr = ast as Expression;
                ParseAstList(expr.exprs, sp + "  ");
            }
            else if (ast is FunctionExpression)
            {
            }
            else if (ast is If)
            {
                If expr = ast as If;
                ParseAst(expr.true_stm, sp + "t  ");
                ParseAst(expr.false_stm, sp + "f  ");
            }
            else if (ast is Block)
            {
                Block block = ast as Block;
                ParseAstList(block.elems, sp + "  ");
            }
        }
        private void AddMethod(string className, string methodName, Assign ass)
        {
            JSClassItem classItem = _classLookup[className] as JSClassItem;
            if (classItem == null)
            {
                // We haven't defined this type yet, do so here.
                classItem = new JSClassItem(className, className, _fileItem);
                //classItem.Icon = Properties.Resources.JSClassItem;
                _fileItem.Classes.Add(classItem);

                _classLookup.Add(className, classItem);
                _projectBrowser.AddLookup(classItem, classItem.GetID(), _invert);
            }

            // TODO methods need parent method ids in their ids, e.g. Hierarchy.js is breaking

            JSMethodItem methodItem = new JSMethodItem(methodName + "()", classItem);
            //methodItem.Icon = Properties.Resources.JSMethodItem;
            methodItem.MethodInfo = ass.right;
            classItem.Methods.Add(methodItem);
            _projectBrowser.AddLookup(methodItem, methodItem.GetID(), _invert);
        }
        private void ParseAst(AST ast, string sp)
        {
            if (ast == null)
            {
                return;
            }

            //_logView.LogStr("JS->" + sp + ast.ToString() + "\t\t" + ast.GetType().Name);

            if (ast is Function)
            {
                Function func = ast as Function;

                JSMethodItem methodItem = new JSMethodItem(func.func_obj.name + "()", _fileItem);
                //methodItem.Icon = Properties.Resources.JSMethodItem;
                methodItem.MethodInfo = ast;

                _fileItem.Methods.Add(methodItem);
                _projectBrowser.AddLookup(methodItem, methodItem.GetID(), _invert);

                _currentMethodStack.Insert(0, func.func_obj.name);

                ParseAstList(func.func_obj.body.elems, sp + "  ");

                _currentMethodStack.RemoveAt(0);
            }
            else if (ast is Assign)
            {
                Assign ass = ast as Assign;

                if ((ass.left is Binary) && (ass.right is FunctionExpression))
                {
                    // Can't see useful properties on this, except ToString().
                    string[] parts = ass.left.ToString().Split('.');
                    if (parts.Length > 2 && parts[1] == "prototype")
                    {
                        // We've found a class method, prototype style.
                        string className  = parts[0];
                        string methodName = parts[2];

                        AddMethod(className, methodName, ass);
                    }
                    else if (parts.Length > 2 && parts[2] == "This")
                    {
                        string className  = _currentMethodStack[0];
                        string methodName = parts[3];

                        AddMethod(className, methodName, ass);
                    }
                }
            }
            else if (ast is Expression)
            {
                Expression expr = ast as Expression;
                ParseAstList(expr.exprs, sp + "  ");
            }
            else if (ast is FunctionExpression)
            {
            }
            else if (ast is If)
            {
                If expr = ast as If;
                ParseAst(expr.true_stm, sp + "t  ");
                ParseAst(expr.false_stm, sp + "f  ");
            }
            else if (ast is Block)
            {
                Block block = ast as Block;
                ParseAstList(block.elems, sp + "  ");
            }
        }