private static bool AdjustFunctionListForExtenderFunction(List <ScriptStruct> structs, ref List <ScriptFunction> functionList, ref FastString script) { if (script.StartsWith("this ")) { GetNextWord(ref script); string structName = GetNextWord(ref script); while ((script.Length > 0) && (script[0] != ',') && (script[0] != ')')) { script = script.Substring(1); } if ((script.Length > 0) && script[0] == ',') { script = script.Substring(1); } script = script.Trim(); foreach (ScriptStruct struc in structs) { if (struc.Name == structName) { functionList = struc.Functions; return(true); } } ScriptStruct newStruct = new ScriptStruct(structName); functionList = newStruct.Functions; structs.Add(newStruct); return(true); } return(false); }
private ScriptToken FindTokenInScript(Script script, string structName, string memberName) { ScriptToken found = null; if (structName != null) { ScriptStruct struc = script.AutoCompleteData.FindStruct(structName); if (struc != null) { found = struc.FindMemberFunction(memberName); if (found == null) { found = struc.FindMemberVariable(memberName); } } else { found = script.AutoCompleteData.FindFunction(_goToDefinition.Replace(".", "::")); } } else { found = script.AutoCompleteData.FindFunction(memberName); if (found == null) { found = script.AutoCompleteData.FindVariable(memberName); } if (found == null) { found = script.AutoCompleteData.FindStruct(memberName); } } return(found); }
private static void AdjustFunctionListForExtenderFunction(List <ScriptStruct> structsLookup, ref List <ScriptFunction> functionList, ref ScriptStruct newStruct, ref FastString script) { GetNextWord(ref script); string structName = GetNextWord(ref script); while ((script.Length > 0) && (script[0] != ',') && (script[0] != ')')) { script = script.Substring(1); } if ((script.Length > 0) && script[0] == ',') { script = script.Substring(1); } script = script.Trim(); foreach (ScriptStruct struc in structsLookup) { if (struc.Name == structName) { functionList = struc.Functions; return; } } newStruct = new ScriptStruct(structName); functionList = newStruct.Functions; return; }
private ScriptFunction FindFunctionInAutocompleteData(string funcName) { ScriptFunction func = _script.AutoCompleteData.FindFunction(funcName); if ((func == null) && (funcName.Contains("::"))) { string[] structAndFuncNames = funcName.Split(new string[] { "::" }, StringSplitOptions.None); ScriptStruct struc = _script.AutoCompleteData.FindStruct(structAndFuncNames[0]); if (struc != null) { func = struc.FindMemberFunction(structAndFuncNames[1]); } } return func; }
private List <IScript> GetScriptsToSearch(string token, out int?startSearchAtLineIndex, out int?endSearchAtLineIndex) { List <IScript> scriptsToSearch = null; startSearchAtLineIndex = null; endSearchAtLineIndex = null; ScriptToken scriptToken = null; if (_scriptEditor != null && _scintilla != null) { scriptToken = _scriptEditor.FindTokenAsLocalVariable(token, true); } if (scriptToken != null) { ScriptFunction function = _scintilla.FindFunctionAtCurrentPosition(); if (function != null) { scriptsToSearch = new List <IScript> { _script }; startSearchAtLineIndex = _scintilla.FindLineNumberForCharacterIndex(function.StartsAtCharacterIndex); endSearchAtLineIndex = _scintilla.FindLineNumberForCharacterIndex(function.EndsAtCharacterIndex); } } if (scriptsToSearch == null) { ScriptStruct scriptStruct = null; if (_scriptEditor != null) { scriptStruct = _scriptEditor.FindGlobalVariableOrType(token); } if (scriptStruct == null) { scriptsToSearch = _agsEditor.GetAllScripts(); } else { scriptsToSearch = new List <IScript> { _script }; } } return(scriptsToSearch); }
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 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 bool AdjustFunctionListForExtenderFunction(List<ScriptStruct> structs, ref List<ScriptFunction> functionList, ref FastString script) { if (script.StartsWith("this ")) { GetNextWord(ref script); string structName = GetNextWord(ref script); while ((script[0] != ',') && (script[0] != ')') && (script.Length > 1)) { script = script.Substring(1); } if (script[0] == ',') { script = script.Substring(1); } script = script.Trim(); foreach (ScriptStruct struc in structs) { if (struc.Name == structName) { functionList = struc.Functions; return true; } } ScriptStruct newStruct = new ScriptStruct(structName); functionList = newStruct.Functions; structs.Add(newStruct); return true; } return false; }
/// <summary> /// Generates a script structure. /// </summary> /// <param name="scriptStructObj">The script structure object.</param> private async Task GenerateScriptStruct(GenericTypes.UEScriptStruct scriptStructObj) { var ss = new ScriptStruct { Name = await scriptStructObj.GetName(), FullName = await scriptStructObj.GetFullName() }; var logTask = Logger.Log($"Struct: {await GetName() + "." + ss.Name, -85} - instance: 0x{scriptStructObj.GetAddress().ToInt64():X8}"); ss.NameCpp = NameValidator.MakeValidName(await scriptStructObj.GetNameCpp()); ss.NameCppFull = "struct "; //some classes need special alignment var alignment = Generator.GetClassAlignas(ss.FullName); if (alignment == 0) { ss.NameCppFull += $"alignas({alignment}) "; } ss.NameCppFull += await NameValidator.MakeUniqueCppName(scriptStructObj); ss.Size = await scriptStructObj.GetPropertySize(); ss.InheritedSize = 0; int offset = 0; var super = await scriptStructObj.GetSuper(); if (super.IsValid() && super != scriptStructObj) { ss.InheritedSize = offset = await scriptStructObj.GetPropertySize(); ss.NameCppFull += $" : public {await NameValidator.MakeUniqueCppName(super.Cast<GenericTypes.UEScriptStruct>())}"; } var properties = new List <GenericTypes.UEProperty>(); for (var prop = (await scriptStructObj.GetChildren()).Cast <GenericTypes.UEProperty>(); prop.IsValid(); prop = (await prop.GetNext()).Cast <GenericTypes.UEProperty>()) { var isScriptStruct = prop.IsA <GenericTypes.UEScriptStruct>(); var isFunction = prop.IsA <GenericTypes.UEFunction>(); var isEnum = prop.IsA <GenericTypes.UEEnum>(); var isConst = prop.IsA <GenericTypes.UEConst>(); if (await prop.GetElementSize() > 0 && !await isScriptStruct && !await isFunction && !await isEnum && !await isConst) { properties.Add(prop); } } // As C# sort not same as C++ version, that's not work // Anyway after some testes it's not needed !! // properties.Sort((x, y) => ComparePropertyLess(x, y).Result ? 0 : 1); var memberT = GenerateMembers(scriptStructObj, offset, properties); if (Generator.SdkType == SdkType.External) { // ToDO: Add external Read/Write here for external } Generator.GetPredefinedClassMethods(await scriptStructObj.GetFullName(), ref ss.PredefinedMethods); ss.Members = await memberT; ScriptStructs.Add(ss); // wait logger await logTask; }
private void StartButton_Click(object sender, EventArgs e) { string sCfgFile; string sDatFile; string sSaveFile; // SaveFileDialog OpenFileDialog.InitialDirectory = Application.StartupPath; OpenFileDialog.FileName = ""; OpenFileDialog.Filter = "L2ScriptMaker Script Generator config file v2|*.ini"; if (OpenFileDialog.ShowDialog() == DialogResult.Cancel) { return; } sCfgFile = OpenFileDialog.FileName; // OpenFileDialog.InitialDirectory = Application.StartupPath OpenFileDialog.FileName = ""; OpenFileDialog.Filter = "Lineage II Client Dat text file (..-e.txt)|*.txt|All files|*.*"; if (OpenFileDialog.ShowDialog() == DialogResult.Cancel) { return; } sDatFile = OpenFileDialog.FileName; // SaveFileDialog.InitialDirectory = Application.StartupPath SaveFileDialog.FileName = ""; SaveFileDialog.Filter = "Lineage II Server Script file|*.txt|All files|*.*"; if (SaveFileDialog.ShowDialog() == DialogResult.Cancel) { return; } sSaveFile = SaveFileDialog.FileName; string sTemp; var aParams = new ScriptStruct[1]; var aUnique = new string[1]; var inFile = new System.IO.StreamReader(sCfgFile, System.Text.Encoding.Default, true, 1); if ((inFile.ReadLine() ?? "") != "L2ScriptMaker Visual Script Editor config file v2") { MessageBox.Show("Config file incompatible with this module." + Constants.vbNewLine + "Required 'L2ScriptMaker Script Generator config file v2'", "Incorrect config", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } while (inFile.EndOfStream != true) { sTemp = inFile.ReadLine().Trim(); if (!string.IsNullOrEmpty(sTemp) & sTemp.StartsWith("//") == false) { // Name if (sTemp.StartsWith("[") == true) { aParams[aParams.Length - 1].Name = sTemp.Substring(1, sTemp.Length - 2); Array.Resize(ref aParams, aParams.Length + 1); } if (sTemp.StartsWith("import") == true) { aParams[aParams.Length - 2].Import = sTemp.Replace("import", "").Replace("=", ""); } if (sTemp.StartsWith("defvalue") == true) { aParams[aParams.Length - 2].DefValue = sTemp.Replace("defvalue", "").Replace("=", ""); } if (sTemp.StartsWith("symbols") == true) { aParams[aParams.Length - 2].Symbols = sTemp.Replace("symbols", "").Replace("=", ""); } if (sTemp.StartsWith("autogenname") == true) { aParams[aParams.Length - 2].Autoname = sTemp.Replace("autogenname", "").Replace("=", ""); } if (sTemp.StartsWith("unique") == true) { aParams[aParams.Length - 2].Unique = sTemp.Replace("unique", "").Replace("=", ""); } if (sTemp.StartsWith("<") == true) { while (inFile.ReadLine().Trim().StartsWith(">") == false) { } } } } inFile.Close(); inFile = new System.IO.StreamReader(sDatFile, System.Text.Encoding.Default, true, 1); var outFile = new System.IO.StreamWriter(sSaveFile, false, System.Text.Encoding.Unicode, 1); // Dim aTemp() As String // Reading Npcdata-e config... // Dim Name As String // Dim Import As String // Dim DefValue As String // Dim Symbols As String int iTemp; string sTemp2; ToolStripProgressBar.Maximum = Conversions.ToInteger(inFile.BaseStream.Length); ToolStripProgressBar.Value = 0; while (inFile.EndOfStream != true) { sTemp = inFile.ReadLine(); ToolStripProgressBar.Value = Conversions.ToInteger(inFile.BaseStream.Position); var loopTo = aParams.Length - 1; for (iTemp = 0; iTemp <= loopTo; iTemp++) { if (!string.IsNullOrEmpty(aParams[iTemp].Name)) { outFile.Write(aParams[iTemp].Name + "="); } if (string.IsNullOrEmpty(aParams[iTemp].Import)) { if (!string.IsNullOrEmpty(aParams[iTemp].Symbols)) { outFile.Write(aParams[iTemp].Symbols[0]); } outFile.Write(aParams[iTemp].DefValue); if (!string.IsNullOrEmpty(aParams[iTemp].Symbols)) { outFile.Write(aParams[iTemp].Symbols[1]); } } else { sTemp2 = Libraries.GetNeedParamFromStr(sTemp, aParams[iTemp].Import).ToLower(); if (!string.IsNullOrEmpty(aParams[iTemp].Symbols)) { sTemp2 = sTemp2.Replace(Conversions.ToString(aParams[iTemp].Symbols[0]), "").Replace(Conversions.ToString(aParams[iTemp].Symbols[1]), ""); } sTemp2 = sTemp2.Replace(" ", "_").Replace("&", "").Replace(":", "").Replace("(", "").Replace(")", "").Replace("_-_", "_"); sTemp2 = sTemp2.Replace("_of_", "_").Replace("_the_", "_").Replace("!", "").Replace(".", "").Replace(",", ""); // Fix for Empty Npc names if (string.IsNullOrEmpty(sTemp2)) { sTemp2 = "npcid_" + Libraries.GetNeedParamFromStr(sTemp, aParams[iTemp].Autoname).ToLower(); } // Fix for Unique Name if ((aParams[iTemp].Unique ?? "") == "on") { if (Array.IndexOf(aUnique, sTemp2) != -1) { sTemp2 = sTemp2 + "_" + Libraries.GetNeedParamFromStr(sTemp, aParams[iTemp].Autoname).ToLower(); } aUnique[aUnique.Length - 1] = sTemp2; Array.Resize(ref aUnique, aUnique.Length + 1); } // Finishing of writing param if (!string.IsNullOrEmpty(aParams[iTemp].Symbols)) { outFile.Write(aParams[iTemp].Symbols[0]); } outFile.Write(sTemp2); if (!string.IsNullOrEmpty(aParams[iTemp].Symbols)) { outFile.Write(aParams[iTemp].Symbols[1]); } } if (iTemp < aParams.Length - 1) { outFile.Write(Constants.vbTab); } } outFile.Write(Constants.vbNewLine); } inFile.Close(); outFile.Close(); ToolStripProgressBar.Value = 0; MessageBox.Show("Generation complete", "Complete", MessageBoxButtons.OK); }
private static ScriptStruct ReadScriptStruct(out int defaultLength, GameBoxReader r) { var strc = new ScriptStruct(); var numMembers = r.ReadByte(); var structName = r.ReadString(); strc.StructName = structName; strc.Members = new ScriptVariable[numMembers]; defaultLength = 0; for (var i = 0; i < numMembers; i++) { ScriptVariable member; var memberName = r.ReadString(); var memberType = r.ReadByte(); switch ((ScriptType)memberType) { case ScriptType.Array: member = ReadScriptArray(r); break; case ScriptType.Struct: member = ReadScriptStruct(out int defLength, r); defaultLength += defLength; break; default: member = new ScriptVariable((ScriptType)memberType); break; } switch (member.Type) { case ScriptType.Integer: r.ReadInt32(); defaultLength += 4; break; case ScriptType.Real: r.ReadSingle(); defaultLength += 4; break; case ScriptType.Vec2: r.ReadVec2(); defaultLength += 8; break; case ScriptType.Vec3: r.ReadVec3(); defaultLength += 12; break; case ScriptType.Int3: r.ReadInt3(); defaultLength += 12; break; case ScriptType.Int2: r.ReadInt2(); defaultLength += 8; break; case ScriptType.Array: break; case ScriptType.Struct: break; default: r.ReadByte(); defaultLength += 1; break; } member.Name = memberName; strc.Members[i] = member; } int counter = 0; while (r.ReadByte() == 0) { counter++; } r.BaseStream.Position -= 1; //int counter = 0; //while (r.ReadByte() == 0) counter++; // probably size of the struct in byte count? //r.BaseStream.Position -= 1; strc.Size = defaultLength + counter; // strc.Unknown = counter; //Progress += defaultLength; return(strc); }
public void Read(GameBoxReader r) { var classId = r.ReadUInt32(); Version = r.ReadInt32(); var typeCount = r.ReadByte(); var types = new ScriptVariable[typeCount]; for (var i = 0; i < typeCount; i++) { var varType = r.ReadByte(); switch ((ScriptType)varType) { case ScriptType.Array: types[i] = ReadScriptArray(); break; case ScriptType.Struct: types[i] = ReadScriptStruct(out int defaultLength); break; default: types[i] = new ScriptVariable((ScriptType)varType); break; } } var varCount = r.ReadByte(); var metadata = new ScriptVariable[varCount]; for (var i = 0; i < varCount; i++) { var metadataVarName = r.ReadString(StringLengthPrefix.Byte); var typeIndex = r.ReadByte(); var type = types[typeIndex]; metadata[i] = ReadType(type.Clone()); metadata[i].Name = metadataVarName; } Metadata = metadata.ToList(); var facade = r.ReadUInt32(); ScriptArray ReadScriptArray() { ScriptVariable indexVar; var indexType = r.ReadByte(); // index if ((ScriptType)indexType == ScriptType.Struct) { indexVar = ReadScriptStruct(out int defaultLength); } else { indexVar = new ScriptVariable((ScriptType)indexType); } ScriptVariable valueVar; var arrayType = r.ReadByte(); // value if ((ScriptType)arrayType == ScriptType.Array) { valueVar = ReadScriptArray(); } else if ((ScriptType)arrayType == ScriptType.Struct) { valueVar = ReadScriptStruct(out int defaultLength); } else { valueVar = new ScriptVariable((ScriptType)arrayType); } ScriptArray array = new ScriptArray(new KeyValuePair <ScriptVariable, ScriptVariable>(indexVar, valueVar)); int counterArray = 0; while (r.ReadByte() == 0) { counterArray++; } r.BaseStream.Position -= 1; array.Unknown = counterArray; return(array); } ScriptStruct ReadScriptStruct(out int defaultLength) { var strc = new ScriptStruct(); var numMembers = r.ReadByte(); var structName = r.ReadString(); strc.StructName = structName; strc.Members = new ScriptVariable[numMembers]; defaultLength = 0; for (var i = 0; i < numMembers; i++) { ScriptVariable member; var memberName = r.ReadString(); var memberType = r.ReadByte(); switch ((ScriptType)memberType) { case ScriptType.Array: member = ReadScriptArray(); break; case ScriptType.Struct: member = ReadScriptStruct(out int defLength); defaultLength += defLength; break; default: member = new ScriptVariable((ScriptType)memberType); break; } switch (member.Type) { case ScriptType.Integer: r.ReadInt32(); defaultLength += 4; break; case ScriptType.Real: r.ReadSingle(); defaultLength += 4; break; case ScriptType.Vec2: r.ReadVec2(); defaultLength += 8; break; case ScriptType.Vec3: r.ReadVec3(); defaultLength += 12; break; case ScriptType.Int3: r.ReadInt3(); defaultLength += 12; break; case ScriptType.Int2: r.ReadInt2(); defaultLength += 8; break; case ScriptType.Array: break; case ScriptType.Struct: break; default: r.ReadByte(); defaultLength += 1; break; } member.Name = memberName; strc.Members[i] = member; } int counter = 0; while (r.ReadByte() == 0) { counter++; } r.BaseStream.Position -= 1; //int counter = 0; //while (r.ReadByte() == 0) counter++; // probably size of the struct in byte count? //r.BaseStream.Position -= 1; strc.Size = defaultLength + counter; // strc.Unknown = counter; //Progress += defaultLength; return(strc); } ScriptVariable ReadType(ScriptVariable type) { switch (type.Type) { case ScriptType.Boolean: type.Value = Convert.ToBoolean(r.ReadBoolean(true)); break; case ScriptType.Integer: type.Value = r.ReadInt32(); break; case ScriptType.Real: type.Value = r.ReadSingle(); break; case ScriptType.Text: type.Value = r.ReadString(StringLengthPrefix.Byte); break; case ScriptType.Vec2: type.Value = r.ReadVec2(); break; case ScriptType.Vec3: type.Value = r.ReadVec3(); break; case ScriptType.Int3: type.Value = r.ReadInt3(); break; case ScriptType.Int2: type.Value = r.ReadInt2(); break; case ScriptType.Array: var array = type as ScriptArray; var numElements = r.ReadByte(); if (numElements > 0) { ScriptVariable key; if (array.Reference.Key.Type == ScriptType.Void) { for (var i = 0; i < numElements; i++) { array.Elements[new ScriptVariable(ScriptType.Void) { Value = i }] = ReadType(array.Reference.Value.Clone()); } } else { key = ReadType(array.Reference.Key.Clone()); for (var i = 0; i < numElements; i++) { array.Elements[key] = ReadType(array.Reference.Value.Clone()); } } } break; case ScriptType.Struct: var strc = type as ScriptStruct; for (var i = 0; i < strc.Members.Length; i++) { strc.Members[i] = ReadType(strc.Members[i]); } break; default: throw new Exception(type.Type.ToString()); } return(type); } }
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; }