static FunctionInfo _parseFunction(string line, Globals globals)
        {
            int firstParen = line.IndexOf('(');
            int lastParen = line.LastIndexOf(')');
            string baseDecl = line.Substring(0, firstParen);
            string paramDecl = line.Substring(firstParen, lastParen - firstParen + 1); //-1 for the ;
            string[] nameParts = baseDecl.Split(' ');
            if (nameParts.Length > 1)
            {
                if (nameParts[0].ToLower().Equals("const")) // Tolerate const type returns
                    nameParts = nameParts.SubArray(1, nameParts.Length - 1);
            }
            TypeInfo retType = null;

            //TODO: split the name parts
            if (globals.ContainsTypeInfo(nameParts[0])) {
                retType = globals.GetTypeInfo(nameParts[0]);
            } else if (nameParts[0].Contains('<')) {
                string wrappedType = nameParts[0].Extract('<', '>');
                string templateType = nameParts[0].Replace(string.Format("<{0}>", wrappedType), "");
                TypeInfo wrapped = globals.GetTypeInfo(wrappedType);
                TemplateInst ti = new TemplateInst() { Name = nameParts[0], IsTemplate = true, WrappedType = wrapped != null ? wrapped : new TypeInfo { Name = wrappedType, IsComplete = false } };
                retType = ti;
            } else {
                retType = new TypeInfo() { Name = nameParts[0], IsPrimitive = false };
            }
            return new FunctionInfo {Name = nameParts[1], ReturnType = retType, Inner = paramDecl};
        }
        public BaseTypeInfo GetClassType(TextDocument aDoc, int line, string text)
        {
            if (globals_ == null)
                return null;
            --line; //subtract one for how AvalonEdit stores text versus reports its position
            int startLine = line;
            if (text.Equals("this")) { //easy case
                int depth = scanner_.GetBraceDepth(line);
                do {
                    string lineCode = aDoc.GetText(aDoc.Lines[line]);
                    if (lineCode.Contains("class ")) {
                        string[] parts = lineCode.Trim().Split(SPACECHAR, StringSplitOptions.RemoveEmptyEntries);
                        if (parts[0].Equals("shared") && globals_.ContainsTypeInfo(parts[2]))
                            return globals_.GetTypeInfo(parts[2]);
                        else if (globals_.ContainsTypeInfo(parts[1]))
                            return globals_.GetTypeInfo(parts[1]);
                        else
                            break;
                    }
                    depth = scanner_.GetBraceDepth(line);
                    --line;
                } while (depth > 0 && line > 0); //class def may be on last line

                //unkonwn class
                int curDepth = depth;
                string[] nameparts = aDoc.GetText(aDoc.Lines[line]).Trim().Split(SPACECHAR, StringSplitOptions.RemoveEmptyEntries);
                string className = "";
                if (nameparts[0].Equals("shared"))
                    className = nameparts[2];
                else if (nameparts[0].Equals("abstract"))
                    className = nameparts[2];
                else
                    className = nameparts[1];
                //TODO get baseclasses
                if (globals_.ContainsTypeInfo(className))
                    return globals_.GetTypeInfo(className);
                TypeInfo tempType = new TypeInfo() { Name = className };
                ++line;
                do {
                    depth = scanner_.GetBraceDepth(line);
                    if (depth == curDepth+1) {
                        string lineCode = aDoc.GetText(aDoc.Lines[line]);
                        string[] words = aDoc.GetText(aDoc.Lines[line]).Trim().Split(SPACECHAR, StringSplitOptions.RemoveEmptyEntries);
                        if (words != null && words.Length > 1) {
                            if (words[1].Contains("(")) { //function
                                if (globals_.ContainsTypeInfo(words[0])) {

                                }
                            } else {
                                string rettype = FilterTypeName(words[0]);
                                string propname = FilterTypeName(words[1]);
                                if (globals_.ContainsTypeInfo(rettype)) {
                                    tempType.Properties[propname] = globals_.GetTypeInfo(rettype);
                                }
                            }
                        }
                    }
                    ++line;
                } while (line < startLine);
                return tempType;
            }

            //SCOPE block for depth
            {
                int depth = scanner_.GetBraceDepth(line);
                bool indexType = false;
                if (text.Contains('[')) {
                    indexType = true;
                    text = text.Substring(0, text.IndexOf('['));
                }
                do {
                    string lineCode = aDoc.GetText(aDoc.Lines[line]).Trim();
                    if (lineCode.Contains(text)) {

                        // Prevent partial matches as false positives, ie. "sceneFile" passing as "scene"
                        string[] lineTokens = lineCode.Split(BREAKCHARS, StringSplitOptions.RemoveEmptyEntries);
                        if (!lineTokens.Contains(text))
                        {
                            --line;
                            depth = scanner_.GetBraceDepth(line);
                            continue;
                        }

                        int endidx = lineCode.IndexOf(text);
                        int idx = endidx;
                        bool okay = true;
                        bool hitSpace = false;
                        while (idx > 0) { //scan backwards to find the typename
                            if (!char.IsLetterOrDigit(lineCode[idx]) && !BACKSCAN_ALLOW.Contains(lineCode[idx])) {
                                okay = false;
                                ++idx;
                                break;
                            }
                            if (!hitSpace && lineCode[idx] == ' ')
                                hitSpace = true;
                            else if (lineCode[idx] == ' ')
                            {
                                break;
                            }
                            --idx;
                        }
                        if (idx < 0) idx = 0;
                        string substr = endidx - idx > 0 ? FilterTypeName(lineCode.Substring(idx, endidx - idx).Trim()) : "";
                        if (substr.Length > 0) { //not empty
                            if (substr.Contains(">")) {//TEMPLATE DEFINITION
                                try
                                {
                                    if (!indexType)
                                        substr = lineCode.Substring(0, lineCode.IndexOf('<'));
                                    else
                                    {
                                        int start = lineCode.IndexOf('<');
                                        int end = lineCode.IndexOf('>');
                                        substr = lineCode.Substring(start + 1, end - start - 1);
                                        substr = substr.Replace("@", "");
                                    }
                                }
                                catch (Exception) { /* silently eat */}
                            }
                            if (globals_.ContainsTypeInfo(substr)) {
                                //Found a class
                                if (indexType)
                                {
                                    TypeInfo ti = globals_.GetTypeInfo(substr);
                                    //HACK for Map types
                                    if (ti.Properties.ContainsKey("values"))
                                    {
                                        TypeInfo valueType = ti.Properties["values"];
                                        if (valueType is TemplateInst)
                                            return ((TemplateInst)valueType).WrappedType;
                                    }
                                }
                                return globals_.GetTypeInfo(substr);
                            } else if (substr.Contains(':'))
                            {
                                string[] words = substr.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
                                if (words.Length > 1 && globals_.ContainsNamespace(words[0]))
                                {
                                    Globals g = globals_;
                                    for (int i = 0; i < words.Length - 1; ++i)
                                    {
                                        g = globals_.GetNamespace(words[i]);
                                    }
                                    if (g.ContainsTypeInfo(words[words.Length - 1]))
                                        return g.GetTypeInfo(words[words.Length - 1]);
                                }
                            }
                        }
                    }
                    --line;
                    depth = scanner_.GetBraceDepth(line);
                } while (depth >= 0 && line > 0);
                return null;
            }
        }
 public OverloadProvider(TypeInfo source, params FunctionInfo[] funcs)
 {
     functions_ = new List<FunctionInfo>(funcs);
     this.source = source;
 }
 public void ResolveIncompletion(Globals globs)
 {
     if (!Type.IsComplete && globs.ContainsTypeInfo(Type.Name))
         Type = globs.GetTypeInfo(Type.Name);
     if (WrappedType != null && !WrappedType.IsComplete && globs.ContainsTypeInfo(WrappedType.Name))
         WrappedType = globs.GetTypeInfo(WrappedType.Name);
 }
 public void AddTypeInfo(string name, TypeInfo ti)
 {
     Classes[name] = ti;
 }
 public void AddProperty(string name, TypeInfo ti, int line, string file)
 {
     Properties[name] = ti;
     PropertyLines[name] = line;
     PropertyFiles[name] = file;
 }
        public Globals(bool createPrimitives)
        {
            Properties = new Dictionary<string, TypeInfo>();
            Functions = new List<FunctionInfo>();
            Classes = new Dictionary<string, TypeInfo>();
            Namespaces = new Dictionary<string, Globals>();
            ReadonlyProperties = new List<string>();
            PropertyLines = new Dictionary<string, int>();
            PropertyFiles = new Dictionary<string, string>();

            if (createPrimitives)
            {
                Classes["void"] = new TypeInfo() { Name = "void", IsPrimitive = true };
                Classes["int"] = new TypeInfo() { Name = "int", IsPrimitive = true };
                Classes["uint"] = new TypeInfo() { Name = "uint", IsPrimitive = true };
                Classes["float"] = new TypeInfo() { Name = "float", IsPrimitive = true };
                Classes["double"] = new TypeInfo() { Name = "double", IsPrimitive = true };
                Classes["bool"] = new TypeInfo() { Name = "bool", IsPrimitive = true };

                //extended types
                Classes["int8"] = new TypeInfo() { Name = "int8", IsPrimitive = true };
                Classes["int16"] = new TypeInfo() { Name = "int16", IsPrimitive = true };
                Classes["int64"] = new TypeInfo() { Name = "int64", IsPrimitive = true };
                Classes["uint8"] = new TypeInfo() { Name = "uint8", IsPrimitive = true };
                Classes["uint16"] = new TypeInfo() { Name = "uint16", IsPrimitive = true };
                Classes["uint64"] = new TypeInfo() { Name = "uint64", IsPrimitive = true };
            }
        }
        void ParseDumpClass(string line, StringReader rdr, Globals globals)
        {
            bool isTemplate = false;
            if (line.Contains("template <class T> "))
                isTemplate = true;
            string[] nameparts = line.Replace(",","").Replace("template <class T> ","").Split(' '); //dump the commas
            string classname = nameparts[1]; //class is first
            string classtype = nameparts[0]; //it might be an interface

            TypeInfo classInfo = new TypeInfo() { IsTemplate = isTemplate };
            classInfo.Name = classname;
            globals.AddTypeInfo(classInfo.Name, classInfo);

            for (int i = 3; i < nameparts.Length; ++i) { //list bases 2 would be :, 3 will be first basetype
                classInfo.BaseTypeStr.Add(nameparts[i]); //add a base class
            }

            bool inprops = false;
            bool nextReadOnly = false;
            bool nextProtected = false;
            while ((line = rdr.ReadLine()) != null) {
                if (line.Length == 0) //empty line
                    continue;
                if (line.StartsWith("{"))
                    continue;
                if (line.Equals("};")) {
                    //TODO: push our class
                    return;
                } else if (line.StartsWith("/* readonly */")) {
                    nextReadOnly = true;
                    continue;
                } else if (line.StartsWith("/* protected */")) {
                    nextProtected = true;
                    continue;
                } else if (line.StartsWith("/*")) {
                    continue;
                } else if (line.Contains("// Properties:")) {
                    inprops = true;
                } else if (line.StartsWith("//")) { // // Methods:
                    continue;
                } else if (inprops) { //property
                    string[] parts = line.Replace(";", "").Split(' '); //[TypeName] [PropertyName]
                    if (parts[0].Contains('<')) {
                        string templateType = parts[0].Substring(0, parts[0].IndexOf('<'));
                        string containedType = parts[0].Extract('<', '>');
                        TypeInfo wrapped = globals.GetTypeInfo(containedType);
                        TemplateInst ti = new TemplateInst() { Name = templateType, IsTemplate = true, WrappedType = wrapped != null ? wrapped : new TypeInfo { Name = containedType, IsComplete = false } };
                        classInfo.Properties[parts[1]] = ti;
                        classInfo.PropertyLines[parts[1]] = -1;
                        if (nextReadOnly)
                            classInfo.ReadonlyProperties.Add(parts[1]);
                        else if (nextProtected)
                            classInfo.ProtectedProperties.Add(parts[1]);
                    } else {
                        string pname = parts[0].EndsWith("@") ? parts[0].Substring(0, parts[0].Length - 1) : parts[0]; //handle
                        TypeInfo pType = null;
                        if (globals.ContainsTypeInfo(pname))
                            pType = globals.GetTypeInfo(pname);
                        if (pType == null) { //create temp type to resolve later
                            pType = new TypeInfo() { Name = pname, IsComplete = false };
                        }
                        classInfo.Properties[parts[1]] = pType;
                        classInfo.PropertyLines[parts[1]] = -1;
                        if (nextReadOnly)
                            classInfo.ReadonlyProperties.Add(parts[1]);
                        else if (nextProtected)
                            classInfo.ProtectedProperties.Add(parts[1]);
                    }
                    nextReadOnly = false;
                    nextProtected = false;

                } else { //function
                    classInfo.Functions.Add(_parseFunction(line, globals));
                    nextReadOnly = false;
                    nextProtected = false;
                }
            }
        }
 void ParseDumpGlobProps(string line, StringReader rdr, Globals globals)
 {
     while ((line = rdr.ReadLine()) != null) {
         if (line.Length == 0)
             return;
         if (line.StartsWith("/*") || line.StartsWith("//"))
             continue;
         else {
             string[] parts = line.Replace(";", "").Split(' '); //[TypeName] [PropertyName]
             string pname = parts[0].EndsWith("@") ? parts[0].Substring(0, parts[0].Length - 1) : parts[0]; //handle
             TypeInfo pType = null;
             string myname = parts[1];
             if (globals.ContainsTypeInfo(pname))
                 pType = globals.GetTypeInfo(pname);
             if (pType == null) { //create temp type to resolve
                 pType = new TypeInfo() { Name = pname, IsComplete = false };
             }
             globals.AddProperty(myname, pType, -1, null);
         }
     }
 }
 public PropertyCompletionData(TypeInfo aType, string desc, PropertyAccess aPropertyAccess = PropertyAccess.Public)
     : base(aPropertyAccess == PropertyAccess.Readonly ? 
         "roproperty.png" : 
         (aPropertyAccess == PropertyAccess.Protected ? "proproperty.png" : "property.png"), 
         desc, aType.Name)
 {
     classType_ = aType;
 }
 public ClassCompletionData(TypeInfo aType)
     : base("class.png", aType.Name, "")
 {
     classType_ = aType;
     if (aType is EnumInfo)
         img_ = "enum.png";
 }