public override IEnumerable <string> GetQueryLines(string[] lines, DfmFencesToken token) { // NOTE: Parsing language and removing comment lines only do for tag name representation var lang = GetCodeLanguageOrExtension(token); if (!_codeLanguageExtractors.TryGetValue(lang, out List <ICodeSnippetExtractor> extractors)) { throw new DfmCodeExtractorException($"{lang} is not supported languaging name, alias or extension for parsing code snippet with tag name, you can use line numbers instead"); } _resolveResult = ResolveTagNamesFromPath(token.Path, lines, TagName, extractors); if (!string.IsNullOrEmpty(_resolveResult.ErrorMessage)) { Logger.LogWarning( DfmCodeExtractor.GenerateErrorMessage(token, _resolveResult.ErrorMessage), line: token.SourceInfo.LineNumber.ToString()); } var included = new List <string>(); for (int i = _resolveResult.StartLine; i <= Math.Min(_resolveResult.EndLine, lines.Length); i++) { if (_resolveResult.ExcludesLines == null || !_resolveResult.ExcludesLines.Contains(i)) { included.Add(lines[i - 1]); } } return(ProcessIncludedLines(included, token)); }
public Dictionary <string, DfmTagNameResolveResult> GetAll(string[] lines) { if (lines == null) { throw new ArgumentNullException(nameof(lines)); } var snippetTags = ResolveCodeSnippetTags(lines); var snippetTagGroups = from tag in snippetTags group tag by tag.Name; var excludedLines = new HashSet <int>(from tagGroup in snippetTagGroups from tag in tagGroup select tag.Line); var result = new Dictionary <string, DfmTagNameResolveResult>(); foreach (var snippetTagGroup in snippetTagGroups) { var tagResolveResult = new DfmTagNameResolveResult(); string tagName = snippetTagGroup.Key; var startTags = (from tag in snippetTagGroup where tag.Type == CodeSnippetTagType.Start select tag.Line).ToList(); var endTags = (from tag in snippetTagGroup where tag.Type == CodeSnippetTagType.End select tag.Line).ToList(); if (startTags.Count == 1 && endTags.Count == 1) { int startLine = startTags[0]; int endLine = endTags[0]; if (startLine < endLine) { tagResolveResult.IsSuccessful = true; tagResolveResult.StartLine = startLine + 1; tagResolveResult.EndLine = endLine - 1; tagResolveResult.ExcludesLines = excludedLines; tagResolveResult.IndentLength = DfmCodeExtractorHelper.GetIndentLength(lines[startLine - 1]); } else { tagResolveResult.IsSuccessful = false; tagResolveResult.ErrorMessage = $"Tag {tagName}'s start line '{startLine}' should be less than end line '{endLine}'"; } } else { tagResolveResult.IsSuccessful = false; tagResolveResult.ErrorMessage = $"Tag {tagName} is not paired or occurred just more than once, details: ({startTags.Count} start lines, {endTags.Count} end lines)"; } result.Add(tagName, tagResolveResult); } return(result); }
public Dictionary<string, DfmTagNameResolveResult> GetAll(string[] lines) { if (lines == null) { throw new ArgumentNullException(nameof(lines)); } var snippetTags = ResolveCodeSnippetTags(lines); var snippetTagGroups = from tag in snippetTags group tag by tag.Name; var excludedLines = new HashSet<int>(from tagGroup in snippetTagGroups from tag in tagGroup select tag.Line); var result = new Dictionary<string, DfmTagNameResolveResult>(); foreach (var snippetTagGroup in snippetTagGroups) { var tagResolveResult = new DfmTagNameResolveResult(); string tagName = snippetTagGroup.Key; var startTags = (from tag in snippetTagGroup where tag.Type == CodeSnippetTagType.Start select tag.Line).ToList(); var endTags = (from tag in snippetTagGroup where tag.Type == CodeSnippetTagType.End select tag.Line).ToList(); if (startTags.Count == 1 && endTags.Count == 1) { int startLine = startTags[0]; int endLine = endTags[0]; if (startLine < endLine) { tagResolveResult.IsSuccessful = true; tagResolveResult.StartLine = startLine + 1; tagResolveResult.EndLine = endLine - 1; tagResolveResult.ExcludesLines = excludedLines; } else { tagResolveResult.IsSuccessful = false; tagResolveResult.ErrorMessage = $"Tag {tagName}'s start line '{startLine}' should be less than end line '{endLine}'"; } } else { tagResolveResult.IsSuccessful = false; tagResolveResult.ErrorMessage = $"Tag {tagName} is not paired or occurred just more than once, details: ({startTags.Count} start lines, {endTags.Count} end lines)"; } result.Add(tagName, tagResolveResult); } return result; }
public override bool ValidateAndPrepare(string[] lines, DfmFencesToken token) { // NOTE: Parsing language and removing comment lines only do for tag name representation var lang = GetCodeLanguageOrExtension(token); if (!CodeLanguageExtractors.TryGetValue(lang, out List <ICodeSnippetExtractor> extractors)) { ErrorMessage = $"{lang} is not supported languaging name, alias or extension for parsing code snippet with tag name, you can use line numbers instead"; return(false); } _resolveResult = ResolveTagNamesFromPath(token.Path, lines, TagName, extractors); ErrorMessage = _resolveResult.ErrorMessage; return(_resolveResult.IsSuccessful); }
private DfmTagNameResolveResult ResolveTagNamesFromPath(string fencesPath, string[] fencesCodeLines, string tagName, Regex regexToExtractCode) { var lazyResolveResults = _dfmTagNameLineRangeCache.GetOrAdd(fencesPath, path => new Lazy <ConcurrentDictionary <string, DfmTagNameResolveResult> >( () => { var linesOfSnippetComment = new Dictionary <int, string>(); for (int i = 0; i < fencesCodeLines.Length; i++) { var match = regexToExtractCode.Match(fencesCodeLines[i]); if (match.Success) { linesOfSnippetComment.Add(i + 1, match.Groups[1].Value); } } var excludedLines = new HashSet <int>(linesOfSnippetComment.Keys); var dictionary = new ConcurrentDictionary <string, DfmTagNameResolveResult>(StringComparer.OrdinalIgnoreCase); foreach (var snippetCommentsInPair in linesOfSnippetComment.GroupBy(kvp => kvp.Value)) { DfmTagNameResolveResult tagResolveResult; var lineNumbers = snippetCommentsInPair.Select(line => line.Key).OrderBy(line => line).ToList(); if (lineNumbers.Count == 2) { tagResolveResult = new DfmTagNameResolveResult { IsSuccessful = true, StartLine = lineNumbers[0] + 1, EndLine = lineNumbers[1] - 1, ExcludesLines = excludedLines, IndentLength = GetIndentLength(fencesCodeLines[lineNumbers[0]]) }; } else { tagResolveResult = new DfmTagNameResolveResult { IsSuccessful = false, ErrorMessage = lineNumbers.Count == 1 ? $"Tag name {snippetCommentsInPair.Key} is not closed" : $"Tag name {snippetCommentsInPair.Key} occurs {lineNumbers.Count} times" }; } dictionary.TryAdd(snippetCommentsInPair.Key, tagResolveResult); } return(dictionary); })); DfmTagNameResolveResult resolveResult; var tagNamesDictionary = lazyResolveResults.Value; return((tagNamesDictionary.TryGetValue(tagName, out resolveResult) || tagNamesDictionary.TryGetValue($"snippet{tagName}", out resolveResult)) ? resolveResult : new DfmTagNameResolveResult { IsSuccessful = false, ErrorMessage = $"Tag name {tagName} is not found" }); }
public Dictionary <string, DfmTagNameResolveResult> GetAll(string[] lines) { if (lines == null) { throw new ArgumentNullException(nameof(lines)); } var snippetTags = ResolveCodeSnippetTags(lines); var snippetTagGroups = snippetTags.GroupBy(t => t.Name, StringComparer.OrdinalIgnoreCase); var excludedLines = new HashSet <int>(from tagGroup in snippetTagGroups from tag in tagGroup select tag.Line); var result = new Dictionary <string, DfmTagNameResolveResult>(); foreach (var snippetTagGroup in snippetTagGroups) { var tagResolveResult = new DfmTagNameResolveResult { IsSuccessful = true }; string tagName = snippetTagGroup.Key; var startTags = (from tag in snippetTagGroup where tag.Type == CodeSnippetTagType.Start select tag.Line).ToList(); var endTags = (from tag in snippetTagGroup where tag.Type == CodeSnippetTagType.End select tag.Line).ToList(); if (startTags.Count != 1 || endTags.Count != 1) { tagResolveResult.ErrorMessage = $"Tag {tagName} is not paired or occurred just more than once, details: ({startTags.Count} start lines, {endTags.Count} end lines)"; } if (startTags.Count == 0 || endTags.Count == 0) { tagResolveResult.IsSuccessful = false; } else { int startLine = startTags[startTags.Count - 1]; int endLine = endTags[0]; if (startLine < endLine) { tagResolveResult.StartLine = startLine + 1; tagResolveResult.EndLine = endLine - 1; tagResolveResult.ExcludesLines = excludedLines; } else { tagResolveResult.IsSuccessful = false; tagResolveResult.ErrorMessage = $"Tag {tagName}'s start line '{startLine}' should be less than end line '{endLine}'"; } } result.Add(tagName, tagResolveResult); } return(result); }
private DfmTagNameResolveResult ResolveTagNamesFromPath(string fencesPath, string[] fencesCodeLines, string tagName, Regex regexToExtractCode) { var lazyResolveResults = _dfmTagNameLineRangeCache.GetOrAdd(fencesPath, path => new Lazy<ConcurrentDictionary<string, DfmTagNameResolveResult>>( () => { var linesOfSnippetComment = new Dictionary<long, string>(); for (long i = 0; i < fencesCodeLines.Length; i++) { var match = regexToExtractCode.Match(fencesCodeLines[i]); if (match.Success) { linesOfSnippetComment.Add(i + 1, match.Groups[1].Value); } } var excludedLines = new HashSet<long>(linesOfSnippetComment.Keys); var dictionary = new ConcurrentDictionary<string, DfmTagNameResolveResult>(StringComparer.OrdinalIgnoreCase); foreach (var snippetCommentsInPair in linesOfSnippetComment.GroupBy(kvp => kvp.Value)) { DfmTagNameResolveResult tagResolveResult; var lineNumbers = snippetCommentsInPair.Select(line => line.Key).OrderBy(line => line).ToList(); if (lineNumbers.Count == 2) { tagResolveResult = new DfmTagNameResolveResult { IsSuccessful = true, StartLine = lineNumbers[0] + 1, EndLine = lineNumbers[1] - 1, ExcludesLines = excludedLines }; } else { tagResolveResult = new DfmTagNameResolveResult { IsSuccessful = false, ErrorMessage = lineNumbers.Count == 1 ? $"Tag name {snippetCommentsInPair.Key} is not closed" : $"Tag name {snippetCommentsInPair.Key} occurs {lineNumbers.Count} times" }; } dictionary.TryAdd(snippetCommentsInPair.Key, tagResolveResult); } return dictionary; })); DfmTagNameResolveResult resolveResult; var tagNamesDictionary = lazyResolveResults.Value; return (tagNamesDictionary.TryGetValue(tagName, out resolveResult) || tagNamesDictionary.TryGetValue($"snippet{tagName}", out resolveResult)) ? resolveResult : new DfmTagNameResolveResult { IsSuccessful = false, ErrorMessage = $"Tag name {tagName} is not found" }; }