/// <summary> /// Получить номера строк для региона деклараций /// </summary> public static ProcedureBlock GetRegionDeclaration(string text, int endLine) { bufferSSLCode = text.Split(new char[] { '\n' }, endLine + 1); int lenBuff = bufferSSLCode.Length - 1; int _comm = 0; bool ret = false; bool check = false; ProcedureBlock procBlock = new ProcedureBlock() { begin = 0, end = -1 }; for (int i = 0; i < lenBuff; i++) { bufferSSLCode[i] = bufferSSLCode[i].Trim(); if (ret) { if (bufferSSLCode[i].Length == 0) { check = false; continue; } else { procBlock.begin = (check) ? i - 1 : i; // found begin declaration break; } } check = (bufferSSLCode[i].Length > 0); if (CommentBlockParse(ref bufferSSLCode[i], ref _comm)) { continue; } ret = true; } for (int i = endLine - 1; i > procBlock.begin; i--) { if (bufferSSLCode[i].Trim().Length > 0) { procBlock.end = i; // found end declaration break; } } return(procBlock); }
public List <FoldMarker> GenerateFoldMarkers(IDocument document, string fileName, object parseInformation) { Procedure[] procs = (Procedure[])parseInformation; List <FoldMarker> list = new List <FoldMarker>(procs.Length); int minStart = -1; fileName = fileName.ToLowerInvariant(); for (int i = 0; i < procs.Length; i++) { string fstart = Path.GetFileName(procs[i].fstart ?? string.Empty).ToLowerInvariant(); if (fstart != fileName || procs[i].d.start >= procs[i].d.end) { continue; } int dstart = procs[i].d.start - 1; if (minStart > dstart || minStart == -1) { minStart = dstart; } int len = document.GetLineSegment(procs[i].d.end - 1).Length; list.Add(new FoldMarker(document, dstart, 0, procs[i].d.end - 1, len, FoldType.MemberBody, " " + procs[i].name.ToUpperInvariant() + " ")); } if (list.Count > 0 && Path.GetExtension(fileName) == ".ssl") { ProcedureBlock dRegion = ParserInternal.GetRegionDeclaration(document.TextContent, minStart); if (dRegion.end < 0) { dRegion.end = minStart - 2; } if (dRegion.end > dRegion.begin) { list.Add(new FoldMarker(document, dRegion.begin, 0, dRegion.end, 1000, FoldType.Region, " - Declaration Region - ")); } } // Get variable and #if foldings block List <ProcedureBlock> blockList = ParserInternal.GetFoldingBlock(document.TextContent); foreach (ProcedureBlock block in blockList) { string str = block.copy ? TextUtilities.GetLineAsString(document, block.begin) + " " : " - Variables - "; list.Add(new FoldMarker(document, block.begin, 0, block.end, 1000, FoldType.TypeBody, str)); } return(list); }
/// <summary> /// Получает список номеров строк для variable и #if блоков /// </summary> /// <param name="text"></param> /// <param name="start"></param> /// <returns></returns> public static List <ProcedureBlock> GetFoldingBlock(string text, int start = 0) { List <ProcedureBlock> list = new List <ProcedureBlock>(); ProcedureBlock procBlock = new ProcedureBlock() { begin = -1, end = -1 }; ProcedureBlock ifBlock = new ProcedureBlock() { begin = -1, end = -1, copy = true }; int _comm = 0; bufferSSLCode = text.Split(new char[] { '\n' }); int lenBuff = bufferSSLCode.Length; for (int i = start; i < lenBuff; i++) { string buffer = bufferSSLCode[i].TrimStart().ToLowerInvariant(); if (CommentBlockParse(ref buffer, ref _comm)) { continue; } RemoveCommentLine(ref buffer, 0); if (ifBlock.begin == -1 && buffer.StartsWith("#if ")) { ifBlock.begin = i; continue; } else if (ifBlock.begin > -1 && buffer.StartsWith("#endif")) { ifBlock.end = i; list.Add(ifBlock); ifBlock = new ProcedureBlock() { begin = -1, end = -1, copy = true }; continue; } if (procBlock.begin == -1 && buffer.StartsWith(VARIABLE)) { int boffset = buffer.IndexOf(" " + BEGIN) + 1; if (boffset > 0) { int len = boffset + BEGIN.Length; if (buffer.Length > len) { buffer = buffer.Remove(len); } int z = buffer.IndexOf(" ", 8); if (z > 0) { buffer = RemoveDoubleWhiteSpaces(buffer, z, boffset); } if (buffer.StartsWith(VARIABLE + BEGIN)) { procBlock.begin = i; continue; } } } else if (procBlock.begin > -1 && buffer.StartsWith(END) && (buffer.Length == 3 || (buffer.Length > 3 && !TextUtilities.IsLetterDigitOrUnderscore(buffer[3])))) { procBlock.end = i; list.Add(procBlock); procBlock = new ProcedureBlock() { begin = -1, end = -1 }; } else if (procBlock.begin > -1 && (buffer.StartsWith(VARIABLE) || buffer.StartsWith(PROCEDURE))) { procBlock.begin = -1; } } return(list); }
/// <summary> /// Получить для указанной процедуры номера ее строк Begin...End блока /// </summary> /// <param name="pName">Имя процедуры</param> /// <param name="startline">Строка в коде с которой необходимо начать поиск</param> /// <param name="procedureLine">procBegin=True - получить номер строки процедуры, а не строки Begin блока</param> public static ProcedureBlock GetProcedureBlock(string pName, int startline = 0, bool procedureLine = false) { int _begin = 0, _proc = 0, _comm = 0, lineProc = 0; ProcedureBlock procBlock = new ProcedureBlock() { declar = -1 }; pName = pName.ToLowerInvariant(); int pLen = pName.Length; if (startline < 0) { startline = 0; } for (int i = startline; i < bufferSSLCode.Length; i++) { bufferSSLCode[i] = bufferSSLCode[i].Trim(); if (CommentBlockParse(ref bufferSSLCode[i], ref _comm)) { continue; } bufferSSLCode[i] = bufferSSLCode[i].Replace('\t', ' '); ProcedureRemoveSpec(ref bufferSSLCode[i]); // ищем начало процедуры с искомым именем if (_proc == 0 && IsProcedure(ref bufferSSLCode[i], pName)) { // нашли procedure name, проверяем 100% совпадает c искомым? procBlock.declar = i; string s = " "; if (bufferSSLCode[i].Length > PROC_LEN + pLen) { s = bufferSSLCode[i].Substring(PROC_LEN + pLen, 1); } if (s != " " && s != "(") { continue; //не совпадает, ищем дальше } _proc++; // совпадает, проверяем это процедура или ее объявление // убираем лишнее RemoveCommentLine(ref bufferSSLCode[i], PROC_LEN + pLen); if (bufferSSLCode[i].EndsWith(BEGIN)) { procBlock.begin = i; //да это процедура, присваеваем значение строки в begin _begin++; continue; } else // нет, продолжаем искать begin { lineProc = i; // save for procBegin, строка Procedure name continue; } } // ищем begin от процедуры. else if (_proc > 0 && _begin == 0) { if (bufferSSLCode[i].StartsWith(BEGIN)) { _begin++; // нашли begin procBlock.begin = (procedureLine) ? lineProc : i; // возвращаем номер строки с процедурой continue; } // в процессе проверяем и любое объявление процедур if (bufferSSLCode[i].StartsWith(PROCEDURE)) { // нашли - откат назад, будем продолжать искать нашу "procedure Name" _proc--; i--; continue; } } // нашли begin, теперь ищем начало следующей процедуры // и от ее позиции будем искать 'END' принадлежащий к искомой "procedure Name" if (_proc > 0 && _begin > 0 && bufferSSLCode[i].StartsWith(PROCEDURE)) { // нашли следующую процедуру for (int j = i - 1; j > 0; j--) // back find { if (bufferSSLCode[j].StartsWith(END)) { // found "end" procBlock.end = j; return(procBlock); // return } else if (j <= procBlock.begin) { procBlock.end = -1; //i - scrptEditor.intParserPrint(String.Format("[Error] <Internal Parser> Line: {0} : When parsing of procedure '{1}'" + " of the keyword 'end' was not found.\r\n", procBlock.begin + 1, GetCaseCorrectProcedureName(pName))); return(procBlock); // procedure block end is broken } } } } // обработка вслучае последней процедуры в скрипте if (procBlock.end == 0 && _proc > 0 && _begin > 0) { for (int i = bufferSSLCode.Length - 1; i > 0; i--) // back find { if (bufferSSLCode[i].StartsWith(END)) { procBlock.end = i; return(procBlock); } } } procBlock.begin = -1; procBlock.end = -1; scrptEditor.intParserPrint(String.Format("[Warning] <Internal Parser> Line: {0} : When parsing the procedure '{1}' an unexpected error occurred," + " the construction of the code was not determined.\r\n", procBlock.declar + 1, GetCaseCorrectProcedureName(pName))); return(procBlock); }
/// <summary> /// Получает список блоков с номерами строк для всех процедур скрипта /// </summary> /// <param name="procNameLst"></param> /// <returns></returns> private static List <ProcedureBlock> GetAllProceduresBlock(out List <string> procNameLst) { procNameLst = new List <string>(); List <ProcedureBlock> procBlockLst = new List <ProcedureBlock>(); Dictionary <string, int> declarLst = new Dictionary <string, int>(); int declarLine, beginLine, commFlag = 0; for (int i = 0; i < bufferSSLCode.Length; i++) { bufferSSLCode[i] = bufferSSLCode[i].TrimStart(); // буфер должен быть в нижнем регистре if (CommentBlockParse(ref bufferSSLCode[i], ref commFlag)) { continue; } bufferSSLCode[i] = bufferSSLCode[i].Replace('\t', ' '); ProcedureRemoveSpec(ref bufferSSLCode[i]); if (bufferSSLCode[i].StartsWith(PROCEDURE)) { // get name procedure string pName = bufferSSLCode[i].Substring(PROC_LEN, bufferSSLCode[i].Length - PROC_LEN).TrimStart(); if (pName.Length == 0) { continue; } RemoveCommentLine(ref pName, 0); // удаляем комментарии с конца строки declarLine = -1; beginLine = -1; // delete Begin or other information from procedure name int z = pName.IndexOf(';'); if (z > 0) { pName = pName.Remove(z); declarLine = i; // это строка обявления } else { beginLine = i; // это начало блока процедуры z = pName.IndexOf(" " + BEGIN); if (z > 0) { pName = pName.Remove(z); //beginLine = i; // это начало блока процедуры }/* else { * while (++i < bufferSSLCode.Length) * { * if (CommentBlockParse(ref bufferSSLCode[i], ref commFlag)) continue; * // в процессе проверяем и любое объявление процедур * if (bufferSSLCode[i].StartsWith(PROCEDURE)) break; * if (bufferSSLCode[i].TrimStart().StartsWith(BEGIN)) { * beginLine = i; // это начало блока процедуры * break; * } * } * }*/ } z = pName.IndexOf('('); if (z > 0) { pName = pName.Remove(z); } pName = pName.TrimEnd(); if (declarLine != -1) { if (!declarLst.ContainsKey(pName)) { declarLst.Add(pName, declarLine); } continue; } int lstIndex = -1; for (int j = 0; j < procNameLst.Count; j++) { if (pName == procNameLst[j]) { lstIndex = j; break; } } if (lstIndex == -1) { procNameLst.Add(pName); ProcedureBlock block = new ProcedureBlock() { begin = beginLine, end = -1 }; block.declar = (declarLst.ContainsKey(pName)) ? declarLst[pName] : -1; procBlockLst.Add(block); } else if (beginLine != -1) { ProcedureBlock block = procBlockLst[lstIndex]; block.begin = beginLine; procBlockLst[lstIndex] = block; } } } // получаем строки конца блока процедур for (int i = 0; i < procBlockLst.Count; i++) { beginLine = procBlockLst[i].begin; if (beginLine != -1) { int nextBegin; if (i == procBlockLst.Count - 1) { nextBegin = bufferSSLCode.Length - 1; // для последней процедуры в скрипте } else { nextBegin = procBlockLst[i + 1].begin; } if (nextBegin == -1) { ProcedureBlock block = procBlockLst[i]; block.end = beginLine + 1; // +2 ?? procBlockLst[i] = block; } else { for (int j = nextBegin; j > beginLine; j--) // back find { if (bufferSSLCode[j].StartsWith(END)) // found "end" { if (bufferSSLCode[j].Length > 3 && !char.IsWhiteSpace(bufferSSLCode[j][3])) { continue; } ProcedureBlock block = procBlockLst[i]; block.end = j; procBlockLst[i] = block; break; } } if (procBlockLst[i].end == -1) // procedure block end is broken { scrptEditor.intParserPrint(String.Format("[Error] <Internal Parser> Line: {0} : When parsing of procedure '{1}' of the keyword 'end' was not found.\r\n", beginLine + 1, GetCaseCorrectProcedureName(procNameLst[i]))); } } } } // добавить процедуры не имеющие блока кода foreach (var el in declarLst) { if (!procNameLst.Contains(el.Key)) { procNameLst.Add(el.Key); procBlockLst.Add(new ProcedureBlock() { begin = -1, end = -1, declar = el.Value }); scrptEditor.intParserPrint(String.Format("[Warning] <Internal Parser> Line: {0} : When parsing the procedure '{1}' an unexpected error occurred," + " the construction of the code was not determined.\r\n", el.Value + 1, GetCaseCorrectProcedureName(el.Key))); } } return(procBlockLst); }