Esempio n. 1
0
        private static ScriptStruct CreateInheritedStruct(ScriptStruct baseStruct, AutoCompleteParserState state)
        {
            ScriptStruct newStruct = new ScriptStruct(state.WordBeforeWordBeforeLast, state.InsideIfDefBlock, state.InsideIfNDefBlock, state.CurrentScriptCharacterIndex);

            foreach (ScriptFunction func in baseStruct.Functions)
            {
                if (!func.NoInherit)
                {
                    newStruct.Functions.Add(func);
                }
            }
            foreach (ScriptVariable var in baseStruct.Variables)
            {
                if (!var.NoInherit)
                {
                    newStruct.Variables.Add(var);
                }
            }
            return(newStruct);
        }
Esempio n. 2
0
        private static void AddVariableDeclaration(List <ScriptVariable> variables, ref FastString script, string thisWord, AutoCompleteParserState state)
        {
            if ((state.LastWord.Length > 0) && (state.WordBeforeLast.Length > 0))
            {
                if (!DoesCurrentLineHaveToken(script, AUTO_COMPLETE_IGNORE))
                {
                    bool   isArray = false, isPointer = false;
                    bool   isStatic = false, isStaticOnly = false;
                    bool   isNoInherit = false, isProtected = false;
                    string type    = state.WordBeforeLast;
                    string varName = state.LastWord;
                    if (thisWord == "[")
                    {
                        while ((script.Length > 0) && (GetNextWord(ref script) != "]"))
                        {
                            ;
                        }
                        isArray = true;
                    }
                    else if (state.DynamicArrayDefinition)
                    {
                        varName = state.WordBeforeLast;
                        type    = state.WordBeforeWordBeforeLast;
                        isArray = true;
                    }
                    if (type == "*")
                    {
                        isPointer = true;
                        if (state.DynamicArrayDefinition)
                        {
                            type = state.PreviousWords[3];
                        }
                        else
                        {
                            type = state.WordBeforeWordBeforeLast;
                        }
                    }
                    if (state.IsWordInPreviousList("static"))
                    {
                        isStatic = true;
                    }
                    if (state.IsWordInPreviousList("protected"))
                    {
                        isProtected = true;
                    }
                    if (DoesCurrentLineHaveToken(script, AUTO_COMPLETE_STATIC_ONLY))
                    {
                        isStaticOnly = true;
                    }
                    if (DoesCurrentLineHaveToken(script, AUTO_COMPLETE_NO_INHERIT))
                    {
                        isNoInherit = true;
                    }
                    // ignore "struct GUI;" prototypes
                    if (type != "struct")
                    {
                        //if (varName == "{") System.Diagnostics.Debugger.Break();
                        ScriptVariable newVar = new ScriptVariable(varName, type, isArray, isPointer, state.InsideIfDefBlock, state.InsideIfNDefBlock, isStatic, isStaticOnly, isNoInherit, isProtected, state.CurrentScriptCharacterIndex);

                        if (!string.IsNullOrEmpty(state.PreviousComment))
                        {
                            newVar.Description    = state.PreviousComment;
                            state.PreviousComment = null;
                        }

                        variables.Add(newVar);
                    }
                }
                state.DynamicArrayDefinition = false;
            }
        }
Esempio n. 3
0
        private static bool AddFunctionDeclaration(List <ScriptFunction> functions, ref FastString script, string thisWord, AutoCompleteParserState state, bool isExtenderMethod)
        {
            bool succeeded = false;

            if ((state.LastWord.Length > 0) && (state.WordBeforeLast.Length > 0))
            {
                if (!DoesCurrentLineHaveToken(script, AUTO_COMPLETE_IGNORE))
                {
                    string functionName = state.LastWord;
                    string type = state.WordBeforeLast;
                    bool   isPointer = false, isNoInherit = false;
                    bool   isStatic = false, isStaticOnly = false;
                    bool   isProtected = false;
                    if (type == "::")
                    {
                        functionName = state.WordBeforeWordBeforeLast + "::" + functionName;
                        type         = (state.PreviousWords.Length > 3) ? state.PreviousWords[3] : "unknown";
                    }
                    if (type == "*")
                    {
                        isPointer = true;
                        type      = state.WordBeforeWordBeforeLast;
                    }
                    if (state.DynamicArrayDefinition)
                    {
                        // get the type name and the []
                        type = state.WordBeforeWordBeforeLast + state.WordBeforeLast;
                    }
                    if (state.IsWordInPreviousList("static"))
                    {
                        isStatic = true;
                    }
                    if (state.IsWordInPreviousList("protected"))
                    {
                        isProtected = true;
                    }
                    if (DoesCurrentLineHaveToken(script, AUTO_COMPLETE_STATIC_ONLY))
                    {
                        isStaticOnly = true;
                    }
                    if (DoesCurrentLineHaveToken(script, AUTO_COMPLETE_NO_INHERIT))
                    {
                        isNoInherit = true;
                    }

                    int parameterListEndIndex = script.IndexOf(')');
                    if (parameterListEndIndex >= 0)
                    {
                        string parameterList = script.Substring(0, parameterListEndIndex);
                        script = script.Substring(parameterListEndIndex + 1);
                        ScriptFunction newFunc = new ScriptFunction(functionName, type, parameterList, state.InsideIfDefBlock, state.InsideIfNDefBlock, isPointer, isStatic, isStaticOnly, isNoInherit, isProtected, isExtenderMethod, state.CurrentScriptCharacterIndex - 1);
                        if (!string.IsNullOrEmpty(state.PreviousComment))
                        {
                            newFunc.Description   = state.PreviousComment;
                            state.PreviousComment = null;
                        }
                        functions.Add(newFunc);
                        succeeded = true;
                    }
                    state.DynamicArrayDefinition = false;
                }
            }

            return(succeeded);
        }
Esempio n. 4
0
        private static void ProcessPreProcessorDirective(List <ScriptDefine> defines, ref FastString script, AutoCompleteParserState state)
        {
            script = script.Substring(1);
            string preProcessorDirective = GetNextWord(ref script);

            if (preProcessorDirective == "define")
            {
                string macroName = GetNextWord(ref script);
                if ((Char.IsLetter(macroName[0])) &&
                    (!DoesCurrentLineHaveToken(script, AUTO_COMPLETE_IGNORE)))
                {
                    defines.Add(new ScriptDefine(macroName, state.InsideIfDefBlock, state.InsideIfNDefBlock));
                }
            }
            else if (preProcessorDirective == "undef")
            {
                string macroName = GetNextWord(ref script);
                if (Char.IsLetter(macroName[0]))
                {
                    foreach (ScriptDefine define in defines)
                    {
                        if (define.Name == macroName)
                        {
                            defines.Remove(define);
                            break;
                        }
                    }
                }
            }
            else if (preProcessorDirective == "ifndef")
            {
                string macroName = GetNextWord(ref script);
                if (Char.IsLetter(macroName[0]))
                {
                    state.InsideIfNDefBlock = macroName;
                }
            }
            else if (preProcessorDirective == "ifdef")
            {
                string macroName = GetNextWord(ref script);
                if (Char.IsLetter(macroName[0]))
                {
                    state.InsideIfDefBlock = macroName;
                }
            }
            else if (preProcessorDirective == "endif")
            {
                state.InsideIfNDefBlock = null;
                state.InsideIfDefBlock  = null;
            }
            GoToNextLine(ref script);
            state.ClearPreviousWords();
        }
Esempio n. 5
0
 private static void ProcessPreProcessorDirective(List<ScriptDefine> defines, ref FastString script, AutoCompleteParserState state)
 {
     script = script.Substring(1);
     string preProcessorDirective = GetNextWord(ref script);
     if (preProcessorDirective == "define")
     {
         string macroName = GetNextWord(ref script);
         if ((Char.IsLetter(macroName[0])) &&
             (!DoesCurrentLineHaveToken(script, AUTO_COMPLETE_IGNORE)))
         {
             defines.Add(new ScriptDefine(macroName, state.InsideIfDefBlock, state.InsideIfNDefBlock));
         }
     }
     else if (preProcessorDirective == "undef")
     {
         string macroName = GetNextWord(ref script);
         if (Char.IsLetter(macroName[0]))
         {
             foreach (ScriptDefine define in defines)
             {
                 if (define.Name == macroName)
                 {
                     defines.Remove(define);
                     break;
                 }
             }
         }
     }
     else if (preProcessorDirective == "ifndef")
     {
         string macroName = GetNextWord(ref script);
         if (Char.IsLetter(macroName[0]))
         {
             state.InsideIfNDefBlock = macroName;
         }
     }
     else if (preProcessorDirective == "ifdef")
     {
         string macroName = GetNextWord(ref script);
         if (Char.IsLetter(macroName[0]))
         {
             state.InsideIfDefBlock = macroName;
         }
     }
     else if (preProcessorDirective == "endif")
     {
         state.InsideIfNDefBlock = null;
         state.InsideIfDefBlock = null;
     }
     GoToNextLine(ref script);
     state.ClearPreviousWords();
 }
Esempio n. 6
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;
        }
Esempio n. 7
0
 private static ScriptStruct CreateInheritedStruct(ScriptStruct baseStruct, AutoCompleteParserState state)
 {
     ScriptStruct newStruct = new ScriptStruct(state.WordBeforeWordBeforeLast, state.InsideIfDefBlock, state.InsideIfNDefBlock, state.CurrentScriptCharacterIndex);
     foreach (ScriptFunction func in baseStruct.Functions)
     {
         if (!func.NoInherit)
         {
             newStruct.Functions.Add(func);
         }
     }
     foreach (ScriptVariable var in baseStruct.Variables)
     {
         if (!var.NoInherit)
         {
             newStruct.Variables.Add(var);
         }
     }
     return newStruct;
 }
Esempio n. 8
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;
        }
Esempio n. 9
0
        private static void AddVariableDeclaration(List<ScriptVariable> variables, ref FastString script, string thisWord, AutoCompleteParserState state)
        {
            if ((state.LastWord.Length > 0) && (state.WordBeforeLast.Length > 0))
            {
                if (!DoesCurrentLineHaveToken(script, AUTO_COMPLETE_IGNORE))
                {
                    bool isArray = false, isPointer = false;
                    bool isStatic = false, isStaticOnly = false;
                    bool isNoInherit = false, isProtected = false;
                    string type = state.WordBeforeLast;
                    string varName = state.LastWord;
                    if (thisWord == "[")
                    {
                        while ((script.Length > 0) && (GetNextWord(ref script) != "]")) ;
                        isArray = true;
                    }
                    else if (state.DynamicArrayDefinition)
                    {
                        varName = state.WordBeforeLast;
                        type = state.WordBeforeWordBeforeLast;
                        isArray = true;
                    }
                    if (type == "*")
                    {
                        isPointer = true;
                        if (state.DynamicArrayDefinition)
                        {
                            type = state.PreviousWords[3];
                        }
                        else
                        {
                            type = state.WordBeforeWordBeforeLast;
                        }
                    }
                    if (state.IsWordInPreviousList("static"))
                    {
                        isStatic = true;
                    }
                    if (state.IsWordInPreviousList("protected"))
                    {
                        isProtected = true;
                    }
                    if (DoesCurrentLineHaveToken(script, AUTO_COMPLETE_STATIC_ONLY))
                    {
                        isStaticOnly = true;
                    }
                    if (DoesCurrentLineHaveToken(script, AUTO_COMPLETE_NO_INHERIT))
                    {
                        isNoInherit = true;
                    }
                    // ignore "struct GUI;" prototypes
                    if (type != "struct")
                    {
                        //if (varName == "{") System.Diagnostics.Debugger.Break();
                        ScriptVariable newVar = new ScriptVariable(varName, type, isArray, isPointer, state.InsideIfDefBlock, state.InsideIfNDefBlock, isStatic, isStaticOnly, isNoInherit, isProtected, state.CurrentScriptCharacterIndex);

                        if (!string.IsNullOrEmpty(state.PreviousComment))
                        {
                            newVar.Description = state.PreviousComment;
                            state.PreviousComment = null;
                        }

                        variables.Add(newVar);
                    }
                }
                state.DynamicArrayDefinition = false;
            }
        }
Esempio n. 10
0
        private static bool AddFunctionDeclaration(List<ScriptFunction> functions, ref FastString script, string thisWord, AutoCompleteParserState state, bool isExtenderMethod)
        {
            bool succeeded = false;

            if ((state.LastWord.Length > 0) && (state.WordBeforeLast.Length > 0))
            {
                if (!DoesCurrentLineHaveToken(script, AUTO_COMPLETE_IGNORE))
                {
                    string functionName = state.LastWord;
                    string type = state.WordBeforeLast;
                    bool isPointer = false, isNoInherit = false;
                    bool isStatic = false, isStaticOnly = false;
                    bool isProtected = false;
                    if (type == "::")
                    {
                        functionName = state.WordBeforeWordBeforeLast + "::" + functionName;
                        type = (state.PreviousWords.Length > 3) ? state.PreviousWords[3] : "unknown";
                    }
                    if (type == "*")
                    {
                        isPointer = true;
                        type = state.WordBeforeWordBeforeLast;
                    }
                    if (state.DynamicArrayDefinition)
                    {
                        // get the type name and the []
                        type = state.WordBeforeWordBeforeLast + state.WordBeforeLast;
                    }
                    if (state.IsWordInPreviousList("static"))
                    {
                        isStatic = true;
                    }
                    if (state.IsWordInPreviousList("protected"))
                    {
                        isProtected = true;
                    }
                    if (DoesCurrentLineHaveToken(script, AUTO_COMPLETE_STATIC_ONLY))
                    {
                        isStaticOnly = true;
                    }
                    if (DoesCurrentLineHaveToken(script, AUTO_COMPLETE_NO_INHERIT))
                    {
                        isNoInherit = true;
                    }

                    int parameterListEndIndex = script.IndexOf(')');
                    if (parameterListEndIndex >= 0)
                    {
                        string parameterList = script.Substring(0, parameterListEndIndex);
                        script = script.Substring(parameterListEndIndex + 1);
                        ScriptFunction newFunc = new ScriptFunction(functionName, type, parameterList, state.InsideIfDefBlock, state.InsideIfNDefBlock, isPointer, isStatic, isStaticOnly, isNoInherit, isProtected, isExtenderMethod, state.CurrentScriptCharacterIndex - 1);
                        if (!string.IsNullOrEmpty(state.PreviousComment))
                        {
                            newFunc.Description = state.PreviousComment;
                            state.PreviousComment = null;
                        }
                        functions.Add(newFunc);
                        succeeded = true;
                    }
                    state.DynamicArrayDefinition = false;
                }
            }

            return succeeded;
        }
Esempio n. 11
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;
        }