/// <summary> /// Builds a snippet from extracted syntax nodes. /// </summary> /// <param name="nodes">The exctracted nodes.</param> /// <param name="extractionMode">The extraction mode.</param> /// <returns>The built snippet.</returns> private string BuildSnippet(SyntaxNode[] nodes, CSharpExtractionMode extractionMode) { if (nodes == null || !nodes.Any()) { throw new ArgumentException("'nodes' is null or empty"); } // Extract code from each snippets StringBuilder stringBuilder = new StringBuilder(); bool firstSnippet = true; foreach (SyntaxNode node in nodes) { // Write line return between each snippet if (!firstSnippet) { stringBuilder.AppendLine(); stringBuilder.AppendLine(); } // Write each snippet line string[] lines = node.GetText().Lines.Select(x => x.ToString()).ToArray(); int contentPosition = this.DetermineContentPosition(node); this.WriteAndCleanupSnippet(stringBuilder, lines, extractionMode, contentPosition); // Flag the first snippet as false firstSnippet = false; } // Create the snippet from the exctracted code return(stringBuilder.ToString()); }
/// <summary> /// Builds a snippet from extracted syntax nodes. /// </summary> /// <param name="nodes">The exctracted nodes.</param> /// <param name="extractionMode">The extraction mode.</param> /// <returns>The built snippet.</returns> private string BuildSnippet(SyntaxNode[] nodes, CSharpExtractionMode extractionMode) { if(nodes == null || !nodes.Any()) { throw new ArgumentException("'nodes' is null or empty"); } // Extract code from each snippets StringBuilder stringBuilder = new StringBuilder(); bool firstSnippet = true; foreach (SyntaxNode node in nodes) { // Write line return between each snippet if (!firstSnippet) { stringBuilder.AppendLine(); stringBuilder.AppendLine(); } // Write each snippet line string[] lines = node.GetText().Lines.Select(x => x.ToString()).ToArray(); int contentPosition = this.DetermineContentPosition(node); this.WriteAndCleanupSnippet(stringBuilder, lines, extractionMode, contentPosition); // Flag the first snippet as false firstSnippet = false; } // Create the snippet from the exctracted code return stringBuilder.ToString(); }
/// <summary> /// Builds a snippet from extracted syntax nodes. /// </summary> /// <param name="nodes">The exctracted nodes.</param> /// <param name="extractionMode">The extraction mode.</param> /// <returns>The built snippet.</returns> private Model.Snippet BuildSnippet(SyntaxNode[] nodes, CSharpExtractionMode extractionMode) { // Data validation Ensure.That(() => nodes).IsNotNull(); Ensure.That(() => nodes).HasItems(); // Extract code from each snippets StringBuilder stringBuilder = new StringBuilder(); bool firstSnippet = true; foreach (SyntaxNode node in nodes) { // Write line return between each snippet if (!firstSnippet) { stringBuilder.AppendLine(); stringBuilder.AppendLine(); } // Write each snippet line string[] lines = node.GetText().Lines.Select(x => x.ToString()).ToArray(); int contentPosition = this.DetermineContentPosition(node); this.WriteAndCleanupSnippet(stringBuilder, lines, extractionMode, contentPosition); // Flag the first snippet as false firstSnippet = false; } // Create the snippet from the exctracted code return(new Model.PlainTextSnippet(stringBuilder.ToString())); }
/// <summary> /// Parses the token /// </summary> /// <param name="pattern"></param> /// <returns></returns> public static CSharpMatchingRule Parse(string pattern) { // Try to match the regex pattern = Regex.Replace(pattern, @"\s", string.Empty); Match match = CSharpMatchingRule.ruleRegex.Match(pattern); if (!match.Success || string.IsNullOrWhiteSpace(match.Groups[0].Value)) { throw new SnippetExtractionException("Invalid extraction rule", pattern); } // Retrieve values from the regex matching string extractionOption = match.Groups[1].Value; string rawMember = match.Groups[2].Value.Trim(); string rawParameters = match.Groups[3].Value.Trim(); // Build The matching chunk with extracted data List <string> matchingChunks = new List <string>(); matchingChunks.AddRange(rawMember.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries)); if (rawParameters.Length >= 1) { matchingChunks.Add(rawParameters); } // Read extraction mode CSharpExtractionMode extractionMode = CSharpExtractionMode.FullMember; switch (extractionOption) { case "-": extractionMode = CSharpExtractionMode.ContentOnly; break; case "=": extractionMode = CSharpExtractionMode.BlockStructureOnly; break; } // Build the matching rule based on the regex matching return(new CSharpMatchingRule { MatchingChunks = matchingChunks.ToArray(), ExtractionMode = extractionMode }); }
/// <summary> /// Writes and cleanup line snippets. /// Snippets are moved out of their context, for this reason we need to trim lines aroung and remove a part of the indentation. /// </summary> /// <param name="stringBuilder">The string builder used as output.</param> /// <param name="lines">The lines to process.</param> /// <param name="extractionMode">The extraction mode.</param> /// <param name="contentPosition">The content position.</param> private void WriteAndCleanupSnippet(StringBuilder stringBuilder, string[] lines, CSharpExtractionMode extractionMode, int contentPosition) { // Do not process if lines are empty if (0 >= lines.Length) { return; } // Compute the index of the first selected line int startPos = 0; int skippedCharNumber = 0; if (CSharpExtractionMode.ContentOnly == extractionMode) { // Compute the content position index in the first processed line int contentPositionFirstLineIndex = 0; for (int totalLinePosition = 0; startPos < lines.Length; ++startPos) { // Compute the content position in the current line string line = lines[startPos]; int relativePosition = contentPosition - totalLinePosition; int contentPositionInLine = relativePosition < line.Length ? relativePosition: -1; // In expected in the current line if (contentPositionInLine >= 0) { // Look for the relative index in the current line // Save the found index and break the iteration if any open bracket is found int indexOf = line.IndexOf('{', contentPositionInLine); if (0 <= indexOf) { contentPositionFirstLineIndex = indexOf; break; } } // Move the total line position after the processed line totalLinePosition += lines[startPos].Length; } // Extract block code if any opening bracket has been found if (startPos < lines.Length) { int openingBracketPos = lines[startPos].IndexOf('{', contentPositionFirstLineIndex); if (openingBracketPos >= 0) { // Extract the code before the curly bracket if (lines[startPos].Length > openingBracketPos) { lines[startPos] = lines[startPos].Substring(openingBracketPos + 1); } // Skip the current line if empty if (string.IsNullOrWhiteSpace(lines[startPos]) && lines.Length > 1 + startPos) { ++startPos; } } } } else { // Skip leading whitespace lines and keep track of the amount of skipped char for (; startPos < lines.Length; ++startPos) { // Break on non whitespace line string line = lines[startPos]; if (line.Trim().Length > 0) { break; } // Record skipped char number skippedCharNumber += line.Length; } } // Compute the index of the lastselected line int endPos = -1 + lines.Length; if (CSharpExtractionMode.ContentOnly == extractionMode) { for (; 0 <= endPos && !lines[endPos].ToString().Contains('}'); --endPos) { ; } // Extract block code if any closing bracket has been found if (0 <= endPos) { int closingBracketPos = lines[endPos].IndexOf('}'); if (closingBracketPos >= 0) { // Extract the code before the curly bracket if (lines[endPos].Length > closingBracketPos) { lines[endPos] = lines[endPos].Substring(0, closingBracketPos).TrimEnd(); } } // Skip the current line if empty if (string.IsNullOrWhiteSpace(lines[endPos]) && lines.Length > -1 + endPos) { --endPos; } } } else { for (; 0 <= endPos && lines[endPos].ToString().Trim().Length == 0; --endPos) { ; } } // Compute the padding to remove for removing a part of the indentation int leftPadding = int.MaxValue; for (int i = startPos; i <= endPos; ++i) { // Ignore empty lines in the middle of the snippet if (!string.IsNullOrWhiteSpace(lines[i])) { // Adjust the left padding with the available whitespace at the beginning of the line leftPadding = Math.Min(leftPadding, lines[i].ToString().TakeWhile(Char.IsWhiteSpace).Count()); } } // Write selected lines to the string builder bool firstLine = true; for (int i = startPos; i <= endPos; ++i) { // Write line return between each line if (!firstLine) { stringBuilder.AppendLine(); } // Remove a part of the indentation padding if (lines[i].Length > leftPadding) { string line = lines[i].Substring(leftPadding); // Process the snippet depending on the extraction mode switch (extractionMode) { // Extract the block structure only case CSharpExtractionMode.BlockStructureOnly: // Compute the content position in the current line int relativePosition = contentPosition - skippedCharNumber; int contentPositionInLine = relativePosition < line.Length + leftPadding ? relativePosition : -1; // Look for open bracket from the content position in line int openingBracketPos = -1; if (contentPositionInLine >= 0) { openingBracketPos = line.IndexOf('{', Math.Max(0, contentPositionInLine - leftPadding)); } // Anonymize code content if an open bracket is found if (openingBracketPos >= 0) { // Extract the code before the curly bracket if (line.Length > openingBracketPos) { line = line.Substring(0, 1 + openingBracketPos); } // Replace the content and close the block line += string.Format("{0} // ...{0}}}", Environment.NewLine); // Stop the iteration endPos = i; } break; } // Append the line stringBuilder.Append(line); skippedCharNumber += lines[i].Length; } // Flag the first line as false firstLine = false; } }
/// <summary> /// Writes and cleanup line snippets. /// Snippets are moved out of their context, for this reason we need to trim lines aroung and remove a part of the indentation. /// </summary> /// <param name="stringBuilder">The string builder used as output.</param> /// <param name="lines">The lines to process.</param> /// <param name="extractionMode">The extraction mode.</param> /// <param name="contentPosition">The content position.</param> private void WriteAndCleanupSnippet(StringBuilder stringBuilder, string[] lines, CSharpExtractionMode extractionMode, int contentPosition) { // Do not process if lines are empty if (0 >= lines.Length) { return; } // Compute the index of the first selected line int startPos = 0; int skippedCharNumber = 0; if (CSharpExtractionMode.ContentOnly == extractionMode) { // Compute the content position index in the first processed line int contentPositionFirstLineIndex = 0; for (int totalLinePosition = 0; startPos < lines.Length; ++startPos) { // Compute the content position in the current line string line = lines[startPos]; int relativePosition = contentPosition - totalLinePosition; int contentPositionInLine = relativePosition < line.Length ? relativePosition: -1; // In expected in the current line if (contentPositionInLine >= 0) { // Look for the relative index in the current line // Save the found index and break the iteration if any open bracket is found int indexOf = line.IndexOf('{', contentPositionInLine); if (0 <= indexOf) { contentPositionFirstLineIndex = indexOf; break; } } // Move the total line position after the processed line totalLinePosition += lines[startPos].Length; } // Extract block code if any opening bracket has been found if (startPos < lines.Length) { int openingBracketPos = lines[startPos].IndexOf('{', contentPositionFirstLineIndex); if (openingBracketPos >= 0) { // Extract the code before the curly bracket if (lines[startPos].Length > openingBracketPos) { lines[startPos] = lines[startPos].Substring(openingBracketPos + 1); } // Skip the current line if empty if (string.IsNullOrWhiteSpace(lines[startPos]) && lines.Length > 1 + startPos) { ++startPos; } } } } else { // Skip leading whitespace lines and keep track of the amount of skipped char for (; startPos < lines.Length; ++startPos) { // Break on non whitespace line string line = lines[startPos]; if (line.Trim().Length > 0) { break; } // Record skipped char number skippedCharNumber += line.Length; } } // Compute the index of the lastselected line int endPos = -1 + lines.Length; if (CSharpExtractionMode.ContentOnly == extractionMode) { for (; 0 <= endPos && !lines[endPos].ToString().Contains('}'); --endPos); // Extract block code if any closing bracket has been found if (0 <= endPos) { int closingBracketPos = lines[endPos].IndexOf('}'); if (closingBracketPos >= 0) { // Extract the code before the curly bracket if (lines[endPos].Length > closingBracketPos) lines[endPos] = lines[endPos].Substring(0, closingBracketPos).TrimEnd(); } // Skip the current line if empty if (string.IsNullOrWhiteSpace(lines[endPos]) && lines.Length > -1 + endPos) { --endPos; } } } else { for (; 0 <= endPos && lines[endPos].ToString().Trim().Length == 0; --endPos); } // Compute the padding to remove for removing a part of the indentation int leftPadding = int.MaxValue; for (int i = startPos; i <= endPos; ++i) { // Ignore empty lines in the middle of the snippet if (!string.IsNullOrWhiteSpace(lines[i])) { // Adjust the left padding with the available whitespace at the beginning of the line leftPadding = Math.Min(leftPadding, lines[i].ToString().TakeWhile(Char.IsWhiteSpace).Count()); } } // Write selected lines to the string builder bool firstLine = true; for (int i = startPos; i <= endPos; ++i) { // Write line return between each line if (!firstLine) { stringBuilder.AppendLine(); } // Remove a part of the indentation padding if (lines[i].Length > leftPadding) { string line = lines[i].Substring(leftPadding); // Process the snippet depending on the extraction mode switch (extractionMode) { // Extract the block structure only case CSharpExtractionMode.BlockStructureOnly: // Compute the content position in the current line int relativePosition = contentPosition - skippedCharNumber; int contentPositionInLine = relativePosition < line.Length + leftPadding ? relativePosition : -1; // Look for open bracket from the content position in line int openingBracketPos = -1; if (contentPositionInLine >= 0) { openingBracketPos = line.IndexOf('{', Math.Max(0, contentPositionInLine - leftPadding)); } // Anonymize code content if an open bracket is found if (openingBracketPos >= 0) { // Extract the code before the curly bracket if (line.Length > openingBracketPos) line = line.Substring(0, 1 + openingBracketPos); // Replace the content and close the block line += string.Format("{0} // ...{0}}}", Environment.NewLine); // Stop the iteration endPos = i; } break; } // Append the line stringBuilder.Append(line); skippedCharNumber += lines[i].Length; } // Flag the first line as false firstLine = false; } }
/// <summary> /// Writes and cleanup line snippets. /// Snippets are moved out of their context, for this reasong we need to trim lines aroung and remove a part of the indentation. /// </summary> /// <param name="stringBuilder">The string builder used as output.</param> /// <param name="lines">The lines to process.</param> /// <param name="extractionMode">The extraction mode.</param> private void WriteAndCleanupSnippet(StringBuilder stringBuilder, string[] lines, CSharpExtractionMode extractionMode) { // Data validation Ensure.That(() => stringBuilder).IsNotNull(); Ensure.That(() => lines).IsNotNull(); // Do not process if lines are empty if (0 >= lines.Length) { return; } // Compute the index of the first selected line int startPos = 0; if (CSharpExtractionMode.ContentOnly == extractionMode) { for (; startPos < lines.Length && !lines[startPos].ToString().Contains('{'); ++startPos) ; // Extract block code if any opening bracket has been found if (startPos < lines.Length) { int openingBracketPos = lines[startPos].IndexOf('{'); if (openingBracketPos >= 0) { // Extract the code before the curly bracket if (lines[startPos].Length > openingBracketPos) { lines[startPos] = lines[startPos].Substring(openingBracketPos + 1); } // Skip the current line if empty if (string.IsNullOrWhiteSpace(lines[startPos]) && lines.Length > 1 + startPos) { ++startPos; } } } } else { for (; startPos < lines.Length && lines[startPos].ToString().Trim().Length == 0; ++startPos) ; } // Compute the index of the lastselected line int endPos = -1 + lines.Length; if (CSharpExtractionMode.ContentOnly == extractionMode) { for (; 0 <= endPos && !lines[endPos].ToString().Contains('}'); --endPos) ; // Extract block code if any closing bracket has been found if (0 <= endPos) { int closingBracketPos = lines[endPos].IndexOf('}'); if (closingBracketPos >= 0) { // Extract the code before the curly bracket if (lines[endPos].Length > closingBracketPos) lines[endPos] = lines[endPos].Substring(0, closingBracketPos).TrimEnd(); } // Skip the current line if empty if (string.IsNullOrWhiteSpace(lines[endPos]) && lines.Length > -1 + endPos) { --endPos; } } } else { for (; 0 <= endPos && lines[endPos].ToString().Trim().Length == 0; --endPos) ; } // Compute the padding to remove for removing a part of the indentation int leftPadding = int.MaxValue; for (int i = startPos; i <= endPos; ++i) { // Ignore empty lines in the middle of the snippet if (!string.IsNullOrWhiteSpace(lines[i])) { // Adjust the left padding with the available whitespace at the beginning of the line leftPadding = Math.Min(leftPadding, lines[i].ToString().TakeWhile(Char.IsWhiteSpace).Count()); } } // Write selected lines to the string builder bool firstLine = true; for (int i = startPos; i <= endPos; ++i) { // Write line return between each line if (!firstLine) { stringBuilder.AppendLine(); } // Remove a part of the indentation padding if (lines[i].Length > leftPadding) { string line = lines[i].Substring(leftPadding); // Process the snippet depending on the extraction mode switch (extractionMode) { // Extract the block structure only case CSharpExtractionMode.BlockStructureOnly: int openingBracketPos = line.IndexOf('{'); if (openingBracketPos >= 0) { // Extract the code before the curly bracket if (line.Length > openingBracketPos) line = line.Substring(0, 1 + openingBracketPos); // Replace the content and close the block line += string.Format("{0} // ...{0}}}", Environment.NewLine); // Stop the iteration endPos = i; } break; } // Append the line stringBuilder.Append(line); } // Flag the first line as false firstLine = false; } }
/// <summary> /// Builds a snippet from extracted syntax nodes. /// </summary> /// <param name="nodes">The exctracted nodes.</param> /// <param name="extractionMode">The extraction mode.</param> /// <returns>The built snippet.</returns> private Model.Snippet BuildSnippet(SyntaxNode[] nodes, CSharpExtractionMode extractionMode) { // Data validation Ensure.That(() => nodes).IsNotNull(); Ensure.That(() => nodes).HasItems(); // Extract code from each snippets StringBuilder stringBuilder = new StringBuilder(); bool firstSnippet = true; foreach (SyntaxNode node in nodes) { // Write line return between each snippet if (!firstSnippet) { stringBuilder.AppendLine(); stringBuilder.AppendLine(); } // Write each snippet line string[] lines = node.GetText().Lines.Select(x => x.ToString()).ToArray(); this.WriteAndCleanupSnippet(stringBuilder, lines, extractionMode); // Flag the first snippet as false firstSnippet = false; } // Create the snippet from the exctracted code return new Model.Snippet(stringBuilder.ToString()); }