コード例 #1
0
        /// <summary>
        /// Gets a source fragment
        /// </summary>
        /// <param name="sourceCode">Source code</param>
        /// <param name="nodeCoordinates">Node coordinates</param>
        /// <param name="tabSize">Number of spaces in the tab</param>
        /// <param name="maxFragmentLength">Maximum length of the source fragment</param>
        /// <returns>Source fragment</returns>
        internal static string GetSourceFragment(string sourceCode,
                                                 SourceCodeNodeCoordinates nodeCoordinates, byte tabSize = DEFAULT_TAB_SIZE,
                                                 int maxFragmentLength = DEFAULT_MAX_FRAGMENT_LENGTH)
        {
            string sourceFragment = string.Empty;
            int    lineNumber     = nodeCoordinates.LineNumber;
            int    columnNumber   = nodeCoordinates.ColumnNumber;

            if (!string.IsNullOrEmpty(sourceCode))
            {
                int previousLineNumber = lineNumber - 1;
                int currentLineNumber  = lineNumber;
                int nextLineNumber     = lineNumber + 1;

                string previousLine = string.Empty;
                string currentLine  = string.Empty;
                string nextLine     = string.Empty;

                int lineCount         = 0;
                int lineBreakPosition = int.MinValue;
                int lineBreakLength   = 0;

                do
                {
                    string line;
                    int    startLinePosition = lineBreakPosition == int.MinValue ? 0 : lineBreakPosition + lineBreakLength;

                    FindNextLineBreak(sourceCode, startLinePosition, out lineBreakPosition, out lineBreakLength);

                    if (lineBreakPosition != -1)
                    {
                        line = sourceCode.Substring(startLinePosition, lineBreakPosition - startLinePosition);
                    }
                    else
                    {
                        line = sourceCode.Substring(startLinePosition);
                    }

                    lineCount++;

                    if (lineCount == previousLineNumber)
                    {
                        previousLine = line;
                    }
                    else if (lineCount == currentLineNumber)
                    {
                        currentLine = line;
                    }
                    else if (lineCount == nextLineNumber)
                    {
                        nextLine = line;
                    }
                }while (lineBreakPosition != -1 && lineCount <= nextLineNumber);

                int lineNumberSize = nextLineNumber.ToString(CultureInfo.InvariantCulture).Length;
                if (currentLineNumber == lineCount)
                {
                    lineNumberSize = currentLineNumber.ToString(CultureInfo.InvariantCulture).Length;
                }

                int fragmentStartPosition;
                int fragmentLength;

                CalculateCutPositions(currentLine, columnNumber, maxFragmentLength,
                                      out fragmentStartPosition, out fragmentLength);

                var           stringBuilderPool     = StringBuilderPool.Shared;
                StringBuilder sourceFragmentBuilder = stringBuilderPool.Rent();

                if (currentLine.Length > 0)
                {
                    if (previousLine.Length > 0)
                    {
                        sourceFragmentBuilder.AppendLine(FormatSourceCodeLine(previousLine,
                                                                              new SourceCodeNodeCoordinates(previousLineNumber, 0),
                                                                              lineNumberSize, fragmentStartPosition, fragmentLength, tabSize));
                    }

                    sourceFragmentBuilder.AppendLine(FormatSourceCodeLine(currentLine,
                                                                          new SourceCodeNodeCoordinates(currentLineNumber, columnNumber),
                                                                          lineNumberSize, fragmentStartPosition, fragmentLength, tabSize));

                    if (nextLine.Length > 0)
                    {
                        sourceFragmentBuilder.AppendLine(FormatSourceCodeLine(nextLine,
                                                                              new SourceCodeNodeCoordinates(nextLineNumber, 0),
                                                                              lineNumberSize, fragmentStartPosition, fragmentLength, tabSize));
                    }

                    sourceFragmentBuilder.TrimEnd();
                }

                sourceFragment = sourceFragmentBuilder.ToString();
                stringBuilderPool.Return(sourceFragmentBuilder);
            }

            return(sourceFragment);
        }
コード例 #2
0
        /// <summary>
        /// Formats a line of source code
        /// </summary>
        /// <param name="line">Line content</param>
        /// <param name="nodeCoordinates">Node coordinates</param>
        /// <param name="lineNumberSize">Number of symbols in the line number caption</param>
        /// <param name="fragmentStartPosition">Start position of source fragment</param>
        /// <param name="fragmentLength">Length of source fragment</param>
        /// <param name="tabSize">Number of spaces in the tab</param>
        /// <returns>Formatted line</returns>
        private static string FormatSourceCodeLine(string line, SourceCodeNodeCoordinates nodeCoordinates,
                                                   int lineNumberSize, int fragmentStartPosition = 0, int fragmentLength = 0, byte tabSize = 4)
        {
            const string ellipsisSymbol  = "…";
            const byte   leftPaddingSize = 7;

            int lineNumber   = nodeCoordinates.LineNumber;
            int columnNumber = nodeCoordinates.ColumnNumber;
            int lineLength   = line.Length;

            string processedLine;

            if (fragmentStartPosition == 0 && fragmentLength == lineLength)
            {
                processedLine = line;
            }
            else if (fragmentStartPosition >= lineLength)
            {
                processedLine = string.Empty;
            }
            else
            {
                int fragmentEndPosition = fragmentStartPosition + fragmentLength - 1;

                bool beginningCutOff = fragmentStartPosition > 0;
                bool endingCutOff    = fragmentEndPosition <= lineLength;
                if (fragmentEndPosition + 1 == lineLength)
                {
                    endingCutOff = false;
                }

                if (fragmentEndPosition >= lineLength)
                {
                    endingCutOff        = false;
                    fragmentEndPosition = lineLength - 1;
                    fragmentLength      = fragmentEndPosition - fragmentStartPosition + 1;
                }

                processedLine = line.Substring(fragmentStartPosition, fragmentLength);
                if (beginningCutOff)
                {
                    processedLine = ellipsisSymbol + processedLine;
                }
                if (endingCutOff)
                {
                    processedLine = processedLine + ellipsisSymbol;
                }
            }

            string result = string.Format("Line {0}: {1}",
                                          lineNumber.ToString(CultureInfo.InvariantCulture).PadLeft(lineNumberSize),
                                          processedLine.TabsToSpaces(tabSize));

            if (columnNumber > 0)
            {
                int cursorOffset = columnNumber - fragmentStartPosition;
                if (fragmentStartPosition > 0)
                {
                    cursorOffset++;
                }

                result += Environment.NewLine + string.Empty
                          .PadRight(
                    (cursorOffset < processedLine.Length ?
                     processedLine.Substring(0, cursorOffset - 1) : processedLine
                    ).TabsToSpaces(tabSize).Length + lineNumberSize + leftPaddingSize
                    )
                          .Replace(" ", "-") + "^"
                ;
            }

            return(result);
        }