/// <summary> /// Compute positions in the target document corresponding to a list of tokens. /// </summary> /// <param name="tokens">The list of token to compute positions</param> /// <param name="from">Output of the from position</param> /// <param name="to">Output of the to position</param> public Tuple <int, int, int, List <int>, List <int> > ComputePositions(IList <Token> tokens, out Position from, out Position to) { Tuple <int, int, int, List <int>, List <int> > positions = FromToPositions(tokens); SourceDocument.SourceLine firstLine = TargetDocument[positions.Item4[0] - 1]; SourceDocument.SourceLine lastLine = TargetDocument[positions.Item4[positions.Item4.Count - 1] - 1]; from = new Position(firstLine.From + positions.Item1 - 1); to = new Position(lastLine.From + positions.Item2); return(positions); }
/// <summary> /// Try to determine what can be erased after a copy instruction /// </summary> public Position ComputeErasureAfterCopyInstructionAction(TypeCobol.Compiler.Scanner.Token copyToken, TypeCobol.Compiler.Scanner.Token lastToken, out bool bAddNewLine) { bAddNewLine = false; Position cfrom = null; Position cto = null; Tuple <int, int, int, List <int>, List <int> > positions = ComputePositions(new List <TypeCobol.Compiler.Scanner.Token>() { copyToken, lastToken }, out cfrom, out cto); TargetDocument.Source.AddPosition(cfrom);//from position if (this.Layout == ColumnsLayout.FreeTextFormat) { return(cfrom); } SourceDocument.SourceLine sourceLine = TargetDocument[positions.Item4[positions.Item4.Count - 1] - 1]; int lineLen = -1; int lineStartOffset = -1; int lineEndOffset = -1; int from = sourceLine.From; int to = sourceLine.To; lineLen = TargetDocument.Source.GetLineInfo(from, out lineStartOffset, out lineEndOffset); if (lineLen > LEGAL_COBOL_LINE_LENGTH) { //Delete all characters in column 72-80 int replace_len = lineLen - LEGAL_COBOL_LINE_LENGTH; Position efrom = new Position(from + LEGAL_COBOL_LINE_LENGTH); Position eto = new Position(from + lineLen); TargetDocument.Source.AddPosition(efrom); TargetDocument.Source.AddPosition(eto); Compiler.Source.StringSourceText del_buffer = new Compiler.Source.StringSourceText(new string(' ', replace_len)); Action action = new Action() { Kind = ActionKind.Insert, From = efrom, To = eto, Text = del_buffer }; Actions.Add(action); } bAddNewLine = true; return(sourceLine.End); }
/// <summary> /// Get the From and To Positions of this Node based on the consumed Token, if no ConsumedTokens the return value is NULL. /// In the consumed tokens span over several lines then the size of the newline sequence is included for each line. /// The method also calculate the ending span offset from the beginning of the last line. /// It also get the list of Line numbers occupated by this node, and the offset of each line. /// </summary> public Tuple <int, int, int, List <int>, List <int> > FromToPositions(Node node) { if (node.CodeElement == null || node.CodeElement.ConsumedTokens == null || node is ParameterEntry) { return(null); } if (node.CodeElement.ConsumedTokens.Count > 0) { int ln_size = System.Environment.NewLine.Length; int from = -1; int to = 0; int i = 0; int span = 0; List <int> lineNumbers = new List <int>(); List <int> lineOffsets = new List <int>(); SourceDocument.SourceLine srcFirstLine = null; do { var token = node.CodeElement.ConsumedTokens[i]; if (!(token is TypeCobol.Compiler.Preprocessor.ImportedToken)) {//Don't take in account imported tokens -> This avoid including lines that come from COPYs files. int curLineIndex = node.CodeElement.ConsumedTokens[i].Line; if (curLineIndex == 0) { //Very bizarre ??? It happens with some COBOL85 samples like: //CCC1B045.PGM, CCTF0011.PGM, CCTZ015B, CCTZ0300B, etc.. return(null); } if (lineNumbers.Count > 0) {//Add lines between int lastLine = lineNumbers[lineNumbers.Count - 1]; while (++lastLine < curLineIndex) { lineNumbers.Add(lastLine); SourceDocument.SourceLine srcLine = TargetDocument[lastLine - 1]; if (srcFirstLine != null) { lineOffsets.Add(srcLine.From - srcFirstLine.From); } } } SourceDocument.SourceLine curLine = TargetDocument[curLineIndex - 1]; if (srcFirstLine == null) { srcFirstLine = curLine; } lineNumbers.Add(curLineIndex); lineOffsets.Add(curLine.From - srcFirstLine.From); span = 0; while ((i < node.CodeElement.ConsumedTokens.Count) && ((curLineIndex == node.CodeElement.ConsumedTokens[i].Line) || (node.CodeElement.ConsumedTokens[i] is TypeCobol.Compiler.Preprocessor.ImportedToken))) { if (!(node.CodeElement.ConsumedTokens[i] is TypeCobol.Compiler.Preprocessor.ImportedToken)) { if (from == -1) { from = node.CodeElement.ConsumedTokens[i].Column; } span = node.CodeElement.ConsumedTokens[i].EndColumn; } i++; } to = (curLine.From + span) - srcFirstLine.From; } else { i++; } } while (i < node.CodeElement.ConsumedTokens.Count); lineNumbers.TrimExcess(); lineOffsets.TrimExcess(); return(new Tuple <int, int, int, List <int>, List <int> >(from, to, span, lineNumbers, lineOffsets)); } return(null); }
/// <summary> /// Get the From and To Positions of this Node based on the consumed Token, if no ConsumedTokens the return value is NULL. /// In the consumed tokens span over several lines then the size of the newline sequence is included for each line. /// The method also calculate the ending span offset from the beginning of the last line. /// It also get the list of Line numbers occupated by this node, and the offset of each line. /// Item1 is the start column /// Item2 is the en column /// Item3 is the span /// Item4 is the list of line numbers /// Item5 is the list of offset inside the line numbers. /// /// </summary> public Tuple <int, int, int, List <int>, List <int> > FromToPositions(IList <Token> ConsumedTokens) { if (ConsumedTokens.Count > 0) { int ln_size = System.Environment.NewLine.Length; int from = -1; int to = 0; int i = 0; int span = 0; List <int> lineNumbers = new List <int>(); List <int> lineOffsets = new List <int>(); SourceDocument.SourceLine srcFirstLine = null; do { var token = ConsumedTokens[i]; if (!(token is TypeCobol.Compiler.Preprocessor.ImportedToken)) {//Don't take in account imported tokens -> This avoid including lines that come from COPYs files. int curLineIndex = ConsumedTokens[i].Line; if (curLineIndex == 0) { return(null); } if (lineNumbers.Count > 0) {//Add lines between int lastLine = lineNumbers[lineNumbers.Count - 1]; while (++lastLine < curLineIndex) { lineNumbers.Add(lastLine); SourceDocument.SourceLine srcLine = TargetDocument[lastLine - 1]; if (srcFirstLine != null) { lineOffsets.Add(srcLine.From - srcFirstLine.From); } } } SourceDocument.SourceLine curLine = TargetDocument[curLineIndex - 1]; if (srcFirstLine == null) { srcFirstLine = curLine; } lineNumbers.Add(curLineIndex); lineOffsets.Add(curLine.From - srcFirstLine.From); span = 0; while ((i < ConsumedTokens.Count) && ((curLineIndex == ConsumedTokens[i].Line) || (ConsumedTokens[i] is TypeCobol.Compiler.Preprocessor.ImportedToken))) { if (!(ConsumedTokens[i] is TypeCobol.Compiler.Preprocessor.ImportedToken)) { if (from == -1) { from = ConsumedTokens[i].Column; } span = ConsumedTokens[i].EndColumn; } i++; } to = (curLine.From + span) - srcFirstLine.From; } else { i++; } } while (i < ConsumedTokens.Count); lineNumbers.TrimExcess(); lineOffsets.TrimExcess(); return(new Tuple <int, int, int, List <int>, List <int> >(from, to, span, lineNumbers, lineOffsets)); } return(null); }