Inheritance: PythonContainerNode
        ICompletionDataList GenerateCompletionData(CodeCompletionContext completionContext, PythonModule module,
				TextEditorData editor, char completionChar)
        {
            var triggerWord = GetTriggerWord (editor, completionContext);

            // Its annoying when the data is poped up during an assignment such as:
            // abc = _
            if (completionChar == '=' && String.IsNullOrEmpty (triggerWord))
                return null;

            var triggerLine = editor.GetLineText (completionContext.TriggerLine);

            // if completionChar is ' ' and it is not a known completion type
            // that we can handle, return as early as possible
            if (completionChar == ' ') {
                if (!triggerWord.Contains ('.') &&
                    !triggerLine.StartsWith ("class") &&
                    !triggerLine.StartsWith ("def") &&
                    !triggerLine.StartsWith ("from") &&
                    !triggerLine.StartsWith ("import"))
                    return null;
            }

            // "self."
            if (module != null && triggerWord == "self" && completionChar == '.') {
                var klass = GetClass (module, completionContext.TriggerLine);
                if (klass == null)
                    return null; // nothing to complete, self not in a class

                return new CompletionDataList (SelfDotCompletionData (klass));
            }

            var inFrom = triggerLine.StartsWith ("from ");
            var inClass = triggerLine.StartsWith ("class ") || (triggerLine.StartsWith ("class") && completionChar == ' ');
            var inDef = triggerLine.StartsWith ("def ") || (triggerLine.StartsWith ("def") && completionChar == ' ');
            var parts = triggerLine.Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            // "from blah "
            if (inFrom && parts.Length == 2 && completionChar == ' ') {
                return new CompletionDataList (new CompletionData[] { new CompletionData ("import") });
            }
            // "from blah import "
            else if (inFrom && parts.Length > 2) {
                triggerWord = parts [1] + ".";
                return new CompletionDataList (
                    from ParserItem item in m_site.Database.Find (triggerWord)
                    where !item.FullName.Substring (triggerWord.Length).Contains ('.')
                    select CreateCompletionData (item, triggerWord))
                    ;
            }

            // if we are in a new class line and not to '(' yet
            // we cannot complete anything at this time, finish now
            if (inClass && parts.Length < 2)
                return null;

            // if we are in a new def line, the only time we can complete
            // is after an equal '='.  so ignore space trigger
            if (inDef && completionChar == ' ')
                return null;
            else if (inDef && completionChar == '=')
                triggerWord = "";

            if (inClass) {
                if (completionChar == '(')
                    triggerWord = "";
                else
                    triggerWord = triggerLine.Substring (triggerLine.LastIndexOf ('(') + 1);
            }

            // limit the depth of search to number of "." in trigger
            // "xml." has depth of 1 so anything matching ^xml. and no more . with match
            int depth = 0;
            foreach (var c in triggerWord)
                if (c == '.')
                    depth++;

            // anything in the sqlite store
            if (!String.IsNullOrEmpty (triggerWord)) {
                // todo: try to complete on class/module/func/attr data

                return new CompletionDataList (
                    from ParserItem item in m_site.Database.Find (triggerWord, ParserItemType.Any, depth)
                    select CreateCompletionData (item, triggerWord))
                    ;
            }

            ParserItemType itemType = String.IsNullOrEmpty (triggerWord) ? ParserItemType.Module : ParserItemType.Any;

            return new CompletionDataList (
                from ParserItem item in m_site.Database.Find ("", itemType, depth)
                select CreateCompletionData (item, triggerWord))
                ;
        }
        static PythonClass GetClass(PythonModule module, int line)
        {
            foreach (PythonClass pyClass in module.Classes)
                if (InRegion (pyClass.Region, line))
                    return pyClass;

            // todo: classes in functions?
            return null;
        }
 public void Reset()
 {
     module = new PythonModule ();
     containers.Clear ();
     containers.Push (module);
 }
        /// <summary>
        /// Walks the xml element tree to build a result. This expects
        /// rootElement to be a &lt;module /&gt; element.
        /// <param name="rootElement">
        /// A <see cref="XmlElement"/>
        /// </param>
        /// </summary>
        /// <param name="rootElement">
        /// A <see cref="XmlElement"/>
        /// </param>
        void BuildFromXmlElement(XmlElement rootElement, StringReader content)
        {
            Debug.Assert (rootElement.LocalName == "module");
            string moduleName = String.Empty;

            if (!String.IsNullOrEmpty (FileName))
                moduleName = PythonHelper.ModuleFromFilename (FileName);

            Module = new PythonModule () {
                FullName = moduleName,
                Region   = GetDomRegion (rootElement),
            };

            foreach (XmlElement child in rootElement) {
                switch (child.LocalName) {
                case "import":
                    BuildImport (child);
                    break;
                case "class":
                    BuildClass (child);
                    break;
                case "attribute":
                    BuildAttribute (child);
                    break;
                case "function":
                    BuildFunction (child);
                    break;
                case "warning":
                    BuildWarning (child);
                    break;
                default:
                    Debug.Assert (false, "Assert not reached");
                    break;
                }
            }
        }
 public CustomPythonWalker()
 {
     module = new PythonModule ();
     containers = new Stack<PythonContainerNode> ();
     containers.Push (module);
 }