示例#1
0
        private static void ConstructCache(Script scriptToCache, bool isBackgroundThread)
        {
            string originalText = scriptToCache.Text;
            ScriptAutoCompleteData newCache = new ScriptAutoCompleteData();
            List<ScriptVariable> variables = newCache.Variables;
            List<ScriptFunction> functions = newCache.Functions;
            List<ScriptDefine> defines = newCache.Defines;
            List<ScriptEnum> enums = newCache.Enums;
            List<ScriptStruct> structs = newCache.Structs;
            variables.Clear();
            functions.Clear();
            defines.Clear();
            enums.Clear();
            structs.Clear();
            FastString script = originalText;
            AutoCompleteParserState state = new AutoCompleteParserState();
            ScriptFunction lastFunction = null;
            int counter = 0;

            while (script.Length > 0)
            {
                if (isBackgroundThread)
                {
                    counter++;
                    if (counter % 20 == 0)
                    {
                        Thread.Sleep(2);
                    }
                }
                SkipWhitespace(ref script);
                state.CurrentScriptCharacterIndex = originalText.Length - script.Length;

                if (script.Length == 0)
                {
                    break;
                }
                if (script.StartsWith("//"))
                {
                    FastString scriptAtComment = script;
                    GoToNextLine(ref script);

                    if (scriptAtComment.StartsWith("///"))
                    {
                        FastString commentText = scriptAtComment.Substring(3, (scriptAtComment.Length - script.Length) - 4);
                        state.PreviousComment = commentText.ToString().Trim();
                    }
                    continue;
                }
                if (script.StartsWith("/*"))
                {
                    int endOfComment = script.IndexOf("*/");
                    if (endOfComment < 0)
                    {
                        break;
                    }
                    script = script.Substring(endOfComment + 2);
                    continue;
                }
                if (script.StartsWith("#"))
                {
                    ProcessPreProcessorDirective(defines, ref script, state);
                    continue;
                }
                if (script.StartsWith("{"))
                {
                    if (state.WordBeforeLast == "enum")
                    {
                        state.InsideEnumDefinition = new ScriptEnum(state.LastWord, state.InsideIfDefBlock, state.InsideIfNDefBlock);
                    }
                    else if (state.WordBeforeLast == "extends")
                    {
                        // inherited struct
                        foreach (ScriptStruct baseStruct in structs)
                        {
                            if (baseStruct.Name == state.LastWord)
                            {
                                state.InsideStructDefinition = CreateInheritedStruct(baseStruct, state);
                                functions = state.InsideStructDefinition.Functions;
                                variables = state.InsideStructDefinition.Variables;
                                break;
                            }
                        }
                    }
                    else if (state.WordBeforeLast == "struct")
                    {
                        state.InsideStructDefinition = new ScriptStruct(state.LastWord, state.InsideIfDefBlock, state.InsideIfNDefBlock, state.CurrentScriptCharacterIndex);
                        functions = state.InsideStructDefinition.Functions;
                        variables = state.InsideStructDefinition.Variables;
                    }
                    else
                    {
                        state.ClearPreviousWords();

                        SkipUntilMatchingClosingBrace(ref script);

                        if ((lastFunction != null) && (lastFunction.EndsAtCharacterIndex == 0))
                        {
                            lastFunction.EndsAtCharacterIndex = originalText.Length - script.Length;
                        }
                        continue;
                    }
                }

                string thisWord = GetNextWord(ref script);
                if (thisWord == "(")
                {
                    List<ScriptFunction> functionList = functions;
                    bool isExtenderMethod = AdjustFunctionListForExtenderFunction(structs, ref functionList, ref script);
                    if (AddFunctionDeclaration(functionList, ref script, thisWord, state, isExtenderMethod))
                    {
                        lastFunction = functionList[functionList.Count - 1];
                    }
                    state.ClearPreviousWords();
                }
                else if ((thisWord == "[") && (PeekNextWord(script) == "]"))
                {
                    GetNextWord(ref script);
                    state.DynamicArrayDefinition = true;
                    state.AddNextWord("[]");
                }
                else if ((thisWord == "=") || (thisWord == ";") ||
                         (thisWord == ",") || (thisWord == "["))
                {
                    if (state.InsideEnumDefinition != null)
                    {
                        AddEnumValue(state.InsideEnumDefinition, script, state.LastWord);

                        if (thisWord == "=")
                        {
                            // skip whatever the value of the enum is
                            GetNextWord(ref script);
                        }
                    }
                    else
                    {
                        AddVariableDeclaration(variables, ref script, thisWord, state);
                        if (thisWord == "=")
                        {
                            while ((thisWord != ";") && (thisWord != ",") && (script.Length > 0))
                            {
                                thisWord = GetNextWord(ref script);
                            }
                        }
                        if (thisWord == ",")
                        {
                            // eg. "int x,y"; ensure "y" gets recorded next time round
                            state.UndoLastWord();
                            continue;
                        }
                        if (thisWord == "[")
                        {
                            // eg. "int a[10], b[10], c[10];"
                            SkipWhitespace(ref script);
                            if (script.StartsWith(","))
                            {
                                GetNextWord(ref script);
                                state.UndoLastWord();
                                continue;
                            }
                        }
                    }
                    state.ClearPreviousWords();
                    state.DynamicArrayDefinition = false;
                }
                else if ((thisWord == "}") && (state.InsideEnumDefinition != null))
                {
                    // add the last value (unless it's an empty enum)
                    if (state.LastWord != "{")
                    {
                        AddEnumValue(state.InsideEnumDefinition, script, state.LastWord);
                    }
                    enums.Add(state.InsideEnumDefinition);
                    state.InsideEnumDefinition = null;
                    state.ClearPreviousWords();
                }
                else if ((thisWord == "}") && (state.InsideStructDefinition != null))
                {
                    structs.Add(state.InsideStructDefinition);
                    functions = newCache.Functions;
                    variables = newCache.Variables;
                    state.InsideStructDefinition = null;
                    state.ClearPreviousWords();
                }
                else
                {
                    state.AddNextWord(thisWord);
                }
            }
            scriptToCache.AutoCompleteData.CopyFrom(newCache);
            scriptToCache.AutoCompleteData.Populated = true;
        }
示例#2
0
        private static void ConstructCache(Script scriptToCache, bool isBackgroundThread)
        {
            string originalText              = scriptToCache.Text;
            ScriptAutoCompleteData newCache  = new ScriptAutoCompleteData();
            List <ScriptVariable>  variables = newCache.Variables;
            List <ScriptFunction>  functions = newCache.Functions;
            List <ScriptDefine>    defines   = newCache.Defines;
            List <ScriptEnum>      enums     = newCache.Enums;
            List <ScriptStruct>    structs   = newCache.Structs;

            variables.Clear();
            functions.Clear();
            defines.Clear();
            enums.Clear();
            structs.Clear();
            FastString script                    = originalText;
            AutoCompleteParserState state        = new AutoCompleteParserState();
            ScriptFunction          lastFunction = null;
            int counter = 0;

            while (script.Length > 0)
            {
                if (isBackgroundThread)
                {
                    counter++;
                    if (counter % 20 == 0)
                    {
                        Thread.Sleep(2);
                    }
                }
                SkipWhitespace(ref script);
                state.CurrentScriptCharacterIndex = originalText.Length - script.Length;

                if (script.Length == 0)
                {
                    break;
                }
                if (script.StartsWith("//"))
                {
                    FastString scriptAtComment = script;
                    GoToNextLine(ref script);

                    if (scriptAtComment.StartsWith("///"))
                    {
                        FastString commentText = scriptAtComment.Substring(3, (scriptAtComment.Length - script.Length) - 4);
                        state.PreviousComment = commentText.ToString().Trim();
                    }
                    continue;
                }
                if (script.StartsWith("/*"))
                {
                    int endOfComment = script.IndexOf("*/");
                    if (endOfComment < 0)
                    {
                        break;
                    }
                    script = script.Substring(endOfComment + 2);
                    continue;
                }
                if (script.StartsWith("#"))
                {
                    ProcessPreProcessorDirective(defines, ref script, state);
                    continue;
                }
                if (script.StartsWith("{"))
                {
                    if (state.WordBeforeLast == "enum")
                    {
                        state.InsideEnumDefinition = new ScriptEnum(state.LastWord, state.InsideIfDefBlock, state.InsideIfNDefBlock);
                    }
                    else if (state.WordBeforeLast == "extends")
                    {
                        // inherited struct
                        foreach (ScriptStruct baseStruct in structs)
                        {
                            if (baseStruct.Name == state.LastWord)
                            {
                                state.InsideStructDefinition = CreateInheritedStruct(baseStruct, state);
                                functions = state.InsideStructDefinition.Functions;
                                variables = state.InsideStructDefinition.Variables;
                                break;
                            }
                        }
                    }
                    else if (state.WordBeforeLast == "struct")
                    {
                        state.InsideStructDefinition = new ScriptStruct(state.LastWord, state.InsideIfDefBlock, state.InsideIfNDefBlock, state.CurrentScriptCharacterIndex);
                        functions = state.InsideStructDefinition.Functions;
                        variables = state.InsideStructDefinition.Variables;
                    }
                    else
                    {
                        state.ClearPreviousWords();

                        SkipUntilMatchingClosingBrace(ref script);

                        if ((lastFunction != null) && (lastFunction.EndsAtCharacterIndex == 0))
                        {
                            lastFunction.EndsAtCharacterIndex = originalText.Length - script.Length;
                        }
                        continue;
                    }
                }

                string thisWord = GetNextWord(ref script);
                if (thisWord == "(")
                {
                    List <ScriptFunction> functionList = functions;
                    bool isExtenderMethod = AdjustFunctionListForExtenderFunction(structs, ref functionList, ref script);
                    if (AddFunctionDeclaration(functionList, ref script, thisWord, state, isExtenderMethod))
                    {
                        lastFunction = functionList[functionList.Count - 1];
                    }
                    state.ClearPreviousWords();
                }
                else if ((thisWord == "[") && (PeekNextWord(script) == "]"))
                {
                    GetNextWord(ref script);
                    state.DynamicArrayDefinition = true;
                    state.AddNextWord("[]");
                }
                else if ((thisWord == "=") || (thisWord == ";") ||
                         (thisWord == ",") || (thisWord == "["))
                {
                    if (state.InsideEnumDefinition != null)
                    {
                        AddEnumValue(state.InsideEnumDefinition, script, state.LastWord);

                        if (thisWord == "=")
                        {
                            // skip whatever the value of the enum is
                            GetNextWord(ref script);
                        }
                    }
                    else
                    {
                        AddVariableDeclaration(variables, ref script, thisWord, state);
                        if (thisWord == "=")
                        {
                            while ((thisWord != ";") && (thisWord != ",") && (script.Length > 0))
                            {
                                thisWord = GetNextWord(ref script);
                            }
                        }
                        if (thisWord == ",")
                        {
                            // eg. "int x,y"; ensure "y" gets recorded next time round
                            state.UndoLastWord();
                            continue;
                        }
                        if (thisWord == "[")
                        {
                            // eg. "int a[10], b[10], c[10];"
                            SkipWhitespace(ref script);
                            if (script.StartsWith(","))
                            {
                                GetNextWord(ref script);
                                state.UndoLastWord();
                                continue;
                            }
                        }
                    }
                    state.ClearPreviousWords();
                    state.DynamicArrayDefinition = false;
                }
                else if ((thisWord == "}") && (state.InsideEnumDefinition != null))
                {
                    // add the last value (unless it's an empty enum)
                    if (state.LastWord != "{")
                    {
                        AddEnumValue(state.InsideEnumDefinition, script, state.LastWord);
                    }
                    enums.Add(state.InsideEnumDefinition);
                    state.InsideEnumDefinition = null;
                    state.ClearPreviousWords();
                }
                else if ((thisWord == "}") && (state.InsideStructDefinition != null))
                {
                    structs.Add(state.InsideStructDefinition);
                    functions = newCache.Functions;
                    variables = newCache.Variables;
                    state.InsideStructDefinition = null;
                    state.ClearPreviousWords();
                }
                else
                {
                    state.AddNextWord(thisWord);
                }
            }
            scriptToCache.AutoCompleteData.CopyFrom(newCache);
            scriptToCache.AutoCompleteData.Populated = true;
        }
示例#3
0
        public static void ConstructCache(Script scriptToCache, IEnumerable <Script> importScripts)
        {
            string originalText              = scriptToCache.Text;
            ScriptAutoCompleteData newCache  = new ScriptAutoCompleteData();
            List <ScriptVariable>  variables = newCache.Variables;
            List <ScriptFunction>  functions = newCache.Functions;
            List <ScriptDefine>    defines   = newCache.Defines;
            List <ScriptEnum>      enums     = newCache.Enums;
            List <ScriptStruct>    structs   = newCache.Structs;

            variables.Clear();
            functions.Clear();
            defines.Clear();
            enums.Clear();
            structs.Clear();
            FastString script                    = originalText;
            AutoCompleteParserState state        = new AutoCompleteParserState();
            ScriptFunction          lastFunction = null;
            // Struct lookup will have both local and imported types
            List <ScriptStruct> structsLookup = new List <ScriptStruct>();

            if (importScripts != null)
            {
                foreach (var import in importScripts)
                {
                    structsLookup.AddRange(import.AutoCompleteData.Structs);
                }
            }

            while (script.Length > 0)
            {
                SkipWhitespace(ref script);
                state.CurrentScriptCharacterIndex = originalText.Length - script.Length;

                if (script.Length == 0)
                {
                    break;
                }
                if (script.StartsWith("//"))
                {
                    FastString scriptAtComment = script;
                    GoToNextLine(ref script);

                    if (scriptAtComment.StartsWith("///"))
                    {
                        FastString commentText = scriptAtComment.Substring(3, (scriptAtComment.Length - script.Length) - 3);
                        state.PreviousComment = commentText.ToString().Trim();
                    }
                    continue;
                }
                if (script.StartsWith("/*"))
                {
                    int endOfComment = script.IndexOf("*/");
                    if (endOfComment < 0)
                    {
                        break;
                    }
                    script = script.Substring(endOfComment + 2);
                    continue;
                }
                if (script.StartsWith("#"))
                {
                    ProcessPreProcessorDirective(defines, ref script, state);
                    continue;
                }
                if (script.StartsWith("{"))
                {
                    if (state.WordBeforeLast == "enum")
                    {
                        state.InsideEnumDefinition = new ScriptEnum(state.LastWord, state.InsideIfDefBlock, state.InsideIfNDefBlock);
                    }
                    else if (state.WordBeforeLast == "extends")
                    {
                        // inherited struct
                        foreach (ScriptStruct baseStruct in structsLookup)
                        {
                            if (baseStruct.Name == state.LastWord)
                            {
                                state.InsideStructDefinition = CreateInheritedStruct(baseStruct, state);
                                functions = state.InsideStructDefinition.Functions;
                                variables = state.InsideStructDefinition.Variables;
                                break;
                            }
                        }
                    }
                    else if (state.WordBeforeLast == "struct")
                    {
                        state.InsideStructDefinition = new ScriptStruct(state.LastWord, state.InsideIfDefBlock, state.InsideIfNDefBlock, state.CurrentScriptCharacterIndex);
                        functions = state.InsideStructDefinition.Functions;
                        variables = state.InsideStructDefinition.Variables;
                    }
                    else
                    {
                        state.ClearPreviousWords();

                        SkipUntilMatchingClosingBrace(ref script);

                        if ((lastFunction != null) && (lastFunction.EndsAtCharacterIndex == 0))
                        {
                            lastFunction.EndsAtCharacterIndex = originalText.Length - script.Length;
                        }
                        continue;
                    }
                }

                string thisWord = GetNextWord(ref script);
                if (thisWord == "(")
                {
                    List <ScriptFunction> functionList = functions;
                    bool isStaticExtender = script.StartsWith("static ");
                    bool isExtenderMethod = isStaticExtender || script.StartsWith("this ");
                    if (isExtenderMethod)
                    {
                        ScriptStruct newStruct = null;
                        // NOTE: for extenders we DO NOT look up the global struct list;
                        // the reason is a bit complicated, but in a nutshell:
                        // we need to have a list of extender functions bound to the
                        // struct defs in the *local* script's autocomplete cache, not the
                        // imported script's cache. The struct defs may be duplicated this
                        // way, but that's mostly fine, as these may be merged together;
                        // e.g. see ScintillaWrapper.GetAllStructsWithMatchingName().
                        AdjustFunctionListForExtenderFunction(structs, ref functionList, ref newStruct, ref script);
                        if (newStruct != null)
                        {
                            structs.Add(newStruct);
                            structsLookup.Add(newStruct);
                        }
                    }
                    if (AddFunctionDeclaration(functionList, ref script, thisWord, state, isExtenderMethod, isStaticExtender, isStaticExtender))
                    {
                        lastFunction = functionList[functionList.Count - 1];
                    }
                    state.ClearPreviousWords();
                }
                else if ((thisWord == "[") && (PeekNextWord(script) == "]"))
                {
                    GetNextWord(ref script);
                    state.DynamicArrayDefinition = true;
                    state.AddNextWord("[]");
                }
                else if ((thisWord == "=") || (thisWord == ";") ||
                         (thisWord == ",") || (thisWord == "["))
                {
                    if (state.InsideEnumDefinition != null)
                    {
                        AddEnumValue(state.InsideEnumDefinition, script, state.LastWord);

                        if (thisWord == "=")
                        {
                            // skip whatever the value of the enum is
                            GetNextWord(ref script);
                        }
                    }
                    else
                    {
                        AddVariableDeclaration(variables, ref script, thisWord, state);
                        if (thisWord == "=")
                        {
                            while ((thisWord != ";") && (thisWord != ",") && (script.Length > 0))
                            {
                                thisWord = GetNextWord(ref script);
                            }
                        }
                        if (thisWord == ",")
                        {
                            // eg. "int x,y"; ensure "y" gets recorded next time round
                            state.UndoLastWord();
                            continue;
                        }
                        if (thisWord == "[")
                        {
                            // eg. "int a[10], b[10], c[10];"
                            SkipWhitespace(ref script);
                            if (script.StartsWith(","))
                            {
                                GetNextWord(ref script);
                                state.UndoLastWord();
                                continue;
                            }
                        }
                    }
                    state.ClearPreviousWords();
                    state.DynamicArrayDefinition = false;
                }
                else if ((thisWord == "}") && (state.InsideEnumDefinition != null))
                {
                    // add the last value (unless it's an empty enum)
                    if (state.LastWord != "{")
                    {
                        AddEnumValue(state.InsideEnumDefinition, script, state.LastWord);
                    }
                    enums.Add(state.InsideEnumDefinition);
                    state.InsideEnumDefinition = null;
                    state.ClearPreviousWords();
                }
                else if ((thisWord == "}") && (state.InsideStructDefinition != null))
                {
                    structs.Add(state.InsideStructDefinition);
                    structsLookup.Add(state.InsideStructDefinition);
                    // Restore struct member references to global script ones
                    functions = newCache.Functions;
                    variables = newCache.Variables;
                    state.InsideStructDefinition = null;
                    state.ClearPreviousWords();
                }
                else
                {
                    state.AddNextWord(thisWord);
                }
            }
            scriptToCache.AutoCompleteData.CopyFrom(newCache);
            scriptToCache.AutoCompleteData.Populated = true;
        }