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); }
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; } }
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); }
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(); }
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(); }
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; }
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; }
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; }
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; } }
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; }
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; }