diff --git a/src/DocNet/App.config b/src/DocNet/App.config
index 5893e9a..4e41c21 100644
--- a/src/DocNet/App.config
+++ b/src/DocNet/App.config
@@ -7,11 +7,11 @@
-
+
-
+
diff --git a/src/DocNet/Docnet.csproj b/src/DocNet/Docnet.csproj
index 062811f..ff52d74 100644
--- a/src/DocNet/Docnet.csproj
+++ b/src/DocNet/Docnet.csproj
@@ -33,11 +33,15 @@
4
-
- ..\..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll
+
+ ..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
True
+
+ ..\..\packages\System.Collections.Immutable.1.3.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll
+ True
+
@@ -72,6 +76,9 @@
MarkdownDeep
+
+
+
-
\ No newline at end of file
diff --git a/src/Projbook.Extension.CSharpExtractor/Projbook/Extension/CSharp/CSharpExtractionMode.cs b/src/Projbook.Extension.CSharpExtractor/Projbook/Extension/CSharp/CSharpExtractionMode.cs
deleted file mode 100644
index 1cb6291..0000000
--- a/src/Projbook.Extension.CSharpExtractor/Projbook/Extension/CSharp/CSharpExtractionMode.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-namespace Projbook.Extension.CSharpExtractor
-{
- ///
- /// Represents the extraction mode.
- ///
- public enum CSharpExtractionMode
- {
- ///
- /// Full member: Do not process the snippet and print it as it.
- ///
- FullMember,
-
- ///
- /// Content only: Extract the code block and print this part only.
- ///
- ContentOnly,
-
- ///
- /// Block structure only: Remove the block content and print the code structure only.
- ///
- BlockStructureOnly
- }
-}
\ No newline at end of file
diff --git a/src/Projbook.Extension.CSharpExtractor/Projbook/Extension/CSharp/CSharpMatchingRule.cs b/src/Projbook.Extension.CSharpExtractor/Projbook/Extension/CSharp/CSharpMatchingRule.cs
deleted file mode 100644
index 6d6c221..0000000
--- a/src/Projbook.Extension.CSharpExtractor/Projbook/Extension/CSharp/CSharpMatchingRule.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-using Projbook.Extension.Exception;
-using System;
-using System.Collections.Generic;
-using System.Text.RegularExpressions;
-
-namespace Projbook.Extension.CSharpExtractor
-{
- ///
- /// Represents a matching rule for referencing a C# member.
- ///
- public class CSharpMatchingRule
- {
- ///
- /// The matching chunk to identify which member are the snippet targets.
- ///
- public string[] MatchingChunks { get; private set; }
-
- ///
- /// The snippet extraction mode.
- ///
- public CSharpExtractionMode ExtractionMode { get; private set; }
-
- ///
- /// Defines rule regex used to parse the snippet into chunks.
- /// Expected input format: Path/File.cs [My.Name.Space.Class.Method][(string, string)]
- /// * The first chunk is the file name and will be loaded in
- /// * The optional second chunks are all full qualified name to the member separated by "."
- /// * The optional last chunk is the method parameters if matching a method.
- ///
- private static Regex ruleRegex = new Regex(@"^([-=])?([^(]+)?\s*(\([^)]*\s*\))?\s*$", RegexOptions.Compiled);
-
- ///
- /// Parses the token
- ///
- ///
- ///
- 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 matchingChunks = new List();
- 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
- };
- }
- }
-}
\ No newline at end of file
diff --git a/src/Projbook.Extension.CSharpExtractor/Projbook/Extension/CSharp/CSharpSnippetExtractor.cs b/src/Projbook.Extension.CSharpExtractor/Projbook/Extension/CSharp/CSharpSnippetExtractor.cs
deleted file mode 100644
index bca6ae1..0000000
--- a/src/Projbook.Extension.CSharpExtractor/Projbook/Extension/CSharp/CSharpSnippetExtractor.cs
+++ /dev/null
@@ -1,368 +0,0 @@
-using EnsureThat;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-using Microsoft.CodeAnalysis.Text;
-using Projbook.Extension.Exception;
-using Projbook.Extension.Spi;
-using System;
-using System.IO.Abstractions;
-using System.Linq;
-using System.Text;
-
-namespace Projbook.Extension.CSharpExtractor
-{
- ///
- /// Extractor in charge of browsing source directories. load file content and extract requested member.
- ///
- [Syntax(name: "csharp")]
- public class CSharpSnippetExtractor : DefaultSnippetExtractor
- {
- ///
- /// Represents the matching trie used for member matching.
- /// Because of the cost of building the Trie, this value is lazy loaded and kept for future usages.
- ///
- private CSharpSyntaxMatchingNode syntaxTrie;
-
- ///
- /// Extracts a snippet from a given rule pattern.
- ///
- /// The file system info.
- /// The member pattern to extract.
- /// The extracted snippet.
- public override Model.Snippet Extract(FileSystemInfoBase fileSystemInfo, string memberPattern)
- {
- // Return the entire code if no member is specified
- if (string.IsNullOrWhiteSpace(memberPattern))
- {
- return base.Extract(fileSystemInfo, memberPattern);
- }
-
- // Parse the matching rule from the pattern
- CSharpMatchingRule rule = CSharpMatchingRule.Parse(memberPattern);
-
- // Load the trie for pattern matching
- if (null == this.syntaxTrie)
- {
- // Load file content
- string sourceCode = base.LoadFile(this.ConvertToFile(fileSystemInfo));
-
- // Build a syntax tree from the source code
- SyntaxTree tree = CSharpSyntaxTree.ParseText(sourceCode);
- SyntaxNode root = tree.GetRoot();
-
- // Visit the syntax tree for generating a Trie for pattern matching
- CSharpSyntaxWalkerMatchingBuilder syntaxMatchingBuilder = new CSharpSyntaxWalkerMatchingBuilder();
- syntaxMatchingBuilder.Visit(root);
-
- // Retrieve the Trie root
- this.syntaxTrie = syntaxMatchingBuilder.Root;
- }
-
- // Match the rule from the syntax matching Trie
- CSharpSyntaxMatchingNode matchingTrie = syntaxTrie.Match(rule.MatchingChunks);
- if (null == matchingTrie)
- {
- throw new SnippetExtractionException("Cannot find member", memberPattern);
- }
-
- // Build a snippet for extracted syntax nodes
- return this.BuildSnippet(matchingTrie.MatchingSyntaxNodes, rule.ExtractionMode);
- }
-
- ///
- /// Builds a snippet from extracted syntax nodes.
- ///
- /// The exctracted nodes.
- /// The extraction mode.
- /// The built snippet.
- 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());
- }
-
- ///
- /// Determines the content's block position depending on the node type.
- ///
- /// The node to extract the content position from.
- /// The determined content position or 0 if not found.
- private int DetermineContentPosition(SyntaxNode node)
- {
- // Data validation
- Ensure.That(() => node).IsNotNull();
-
- // Select the content node element depending on the node type
- TextSpan? contentTextSpan = null;
- switch (node.Kind())
- {
- // Accessor list content
- case SyntaxKind.PropertyDeclaration:
- case SyntaxKind.IndexerDeclaration:
- case SyntaxKind.EventDeclaration:
- AccessorListSyntax accessorList = node.DescendantNodes().OfType().FirstOrDefault();
- if (null != accessorList)
- {
- contentTextSpan = accessorList.FullSpan;
- }
- break;
-
- // Contains children
- case SyntaxKind.NamespaceDeclaration:
- case SyntaxKind.InterfaceDeclaration:
- case SyntaxKind.ClassDeclaration:
- SyntaxToken token = node.ChildTokens().Where(x => x.Kind() == SyntaxKind.OpenBraceToken).FirstOrDefault();
- if (null != token)
- {
- contentTextSpan = token.FullSpan;
- }
- break;
-
- // Block content
- case SyntaxKind.ConstructorDeclaration:
- case SyntaxKind.DestructorDeclaration:
- case SyntaxKind.MethodDeclaration:
- case SyntaxKind.GetAccessorDeclaration:
- case SyntaxKind.SetAccessorDeclaration:
- case SyntaxKind.AddAccessorDeclaration:
- case SyntaxKind.RemoveAccessorDeclaration:
- BlockSyntax block = node.DescendantNodes().OfType().FirstOrDefault();
- if (null != block)
- {
- contentTextSpan = block.FullSpan;
- }
- break;
-
- // Not processed by projbook csharp extractor
- default:
- break;
- }
-
- // Compute a line break insensitive position based on the fetched content text span if any is found
- if (null != contentTextSpan)
- {
- int relativeTextSpanStart = contentTextSpan.Value.Start - node.FullSpan.Start;
- return node
- .ToFullString()
- .Substring(0, relativeTextSpanStart)
- .Replace("\r\n", "")
- .Replace("\n", "").Length;
- }
-
- // Otherwise return 0 as default value
- return 0;
- }
-
- ///
- /// 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.
- ///
- /// The string builder used as output.
- /// The lines to process.
- /// The extraction mode.
- /// The content position.
- private void WriteAndCleanupSnippet(StringBuilder stringBuilder, string[] lines, CSharpExtractionMode extractionMode, int contentPosition)
- {
- // 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;
- 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;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Projbook.Extension.CSharpExtractor/Projbook/Extension/CSharp/CSharpSyntaxMatchingNode.cs b/src/Projbook.Extension.CSharpExtractor/Projbook/Extension/CSharp/CSharpSyntaxMatchingNode.cs
deleted file mode 100644
index 9f1b33a..0000000
--- a/src/Projbook.Extension.CSharpExtractor/Projbook/Extension/CSharp/CSharpSyntaxMatchingNode.cs
+++ /dev/null
@@ -1,201 +0,0 @@
-using EnsureThat;
-using Microsoft.CodeAnalysis;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Projbook.Extension.CSharpExtractor
-{
- ///
- /// Represents a syntax matching node.
- /// Thie node is used to build a Trie representing possible matching.
- /// Each node contians children and matching syntax nodes.
- ///
- public class CSharpSyntaxMatchingNode
- {
- ///
- /// The public Matching SyntaxNodes.
- ///
- public SyntaxNode[] MatchingSyntaxNodes
- {
- get
- {
- // Return empty array id the nodes are empty
- if (null == this.matchingSyntaxNodes)
- {
- return new SyntaxNode[0];
- }
-
- // Return the matching syntax nodes
- return this.matchingSyntaxNodes.ToArray();
- }
- }
-
- ///
- /// The node's children.
- ///
- private Dictionary children;
-
- ///
- /// The node's maching syntax node.
- ///
- private List matchingSyntaxNodes;
-
- ///
- /// Finds a node from syntax chunk.
- ///
- /// The chunks to match.
- ///
- public CSharpSyntaxMatchingNode Match(string[] chunks)
- {
- // Data validation
- Ensure.That(() => chunks).IsNotNull();
-
- // Browse the Trie until finding a matching
- CSharpSyntaxMatchingNode matchingNode = this;
- foreach (string fragment in chunks)
- {
- // Could not find any matching
- if (null == matchingNode.children || !matchingNode.children.TryGetValue(fragment, out matchingNode))
- {
- return null;
- }
- }
-
- // Return the matching node
- return matchingNode;
- }
-
- ///
- /// Lookup a node from children and return it. if the node doesn't exist, a new one will be created and added to the children.
- ///
- /// The node name.
- /// The node matching the requested name.
- public CSharpSyntaxMatchingNode EnsureNode(string name)
- {
- // Data validation
- Ensure.That(() => name).IsNotNullOrWhiteSpace();
-
- // Fetch a node from existing children and return it if any is found
- CSharpSyntaxMatchingNode firstLevelNode;
- if (null != this.children && this.children.TryGetValue(name, out firstLevelNode))
- {
- return firstLevelNode;
- }
-
- // Otherwise create a new node and return it
- else
- {
- // Lazu create the dictionary for storing children
- if (null == this.children)
- {
- this.children = new Dictionary();
- }
-
- // Assign and return the new node
- return this.children[name] = new CSharpSyntaxMatchingNode();
- }
- }
-
- ///
- /// Adds a syntax node as matching node.
- ///
- ///
- public void AddSyntaxNode(SyntaxNode node)
- {
- // Data validation
- Ensure.That(() => node).IsNotNull();
-
- // Lazy create the syntax node list
- if (null == this.matchingSyntaxNodes)
- {
- this.matchingSyntaxNodes = new List();
- }
-
- // Add the node to the known matching node
- this.matchingSyntaxNodes.Add(node);
- }
-
- ///
- /// Copies to a given node.
- ///
- /// The node wherer to copy.
- /// The node name.
- public void CopyTo(CSharpSyntaxMatchingNode targetNode, string name)
- {
- // Data validation
- Ensure.That(() => name).IsNotNullOrWhiteSpace();
- Ensure.That(() => targetNode).IsNotNull();
-
- // Ensure and retrieve a node the the copy
- CSharpSyntaxMatchingNode newNode = targetNode.EnsureNode(name);
-
- // Add syntax node to the created node
- if (null != this.matchingSyntaxNodes)
- {
- // Lazy create the syntax nodes
- if (null == newNode.matchingSyntaxNodes)
- {
- newNode.matchingSyntaxNodes = new List();
- }
-
- // Merge syntax nodes
- int[] indexes = newNode.matchingSyntaxNodes.Select(x => x.Span.Start).ToArray();
- newNode.matchingSyntaxNodes.AddRange(this.matchingSyntaxNodes.Where(x => !indexes.Contains(x.Span.Start)));
- }
-
- // Recurse for applying copy to the children
- if (null != this.children && this.children.Count > 0)
- {
- string[] childrenName = this.children.Keys.ToArray();
- foreach (string childName in childrenName)
- {
- this.children[childName].CopyTo(newNode, childName);
- }
- }
- }
-
- ///
- /// Overrides ToString to renger the internal Trie to a string.
- ///
- /// The rendered Trie as string.
- public override string ToString()
- {
- StringBuilder strinbBuilder = new StringBuilder();
- this.Write(strinbBuilder, null, 0);
- return strinbBuilder.ToString();
- }
-
- ///
- /// Writes a node to a string builder and recurse to the children.
- ///
- /// The string builder used as output.
- /// The node name.
- /// The node level.
- private void Write(StringBuilder stringBuilder, string name, int level)
- {
- // Print the node only if the name is not null in order to ignore the root node for more clarity
- int nextLevel = level;
- if (null != name)
- {
- ++nextLevel;
- stringBuilder.AppendLine(string.Format("{0}{1}", new string('-', level), name));
- }
-
- // Print each matching syntax node
- foreach (var matchingSyntaxNode in this.MatchingSyntaxNodes)
- {
- stringBuilder.AppendLine(string.Format("{0}[{1}]", new string('-', level), matchingSyntaxNode.GetType().Name));
- }
-
- // Recurse to children
- if (null != this.children)
- {
- foreach (string childName in this.children.Keys)
- {
- this.children[childName].Write(stringBuilder, childName, nextLevel);
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Projbook.Extension.CSharpExtractor/Projbook/Extension/CSharp/CSharpSyntaxWalkerMatchingBuilder.cs b/src/Projbook.Extension.CSharpExtractor/Projbook/Extension/CSharp/CSharpSyntaxWalkerMatchingBuilder.cs
deleted file mode 100644
index d6a72f1..0000000
--- a/src/Projbook.Extension.CSharpExtractor/Projbook/Extension/CSharp/CSharpSyntaxWalkerMatchingBuilder.cs
+++ /dev/null
@@ -1,329 +0,0 @@
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-using System;
-using System.Linq;
-
-namespace Projbook.Extension.CSharpExtractor
-{
- ///
- /// Implements a syntax walker generating a Trie for pattern matching.
- ///
- public class CSharpSyntaxWalkerMatchingBuilder : CSharpSyntaxWalker
- {
- ///
- /// The current Trie root available from the outside.
- ///
- public CSharpSyntaxMatchingNode Root { get; private set; }
-
- ///
- /// The Trie root referencing the root without any reference change.
- ///
- private CSharpSyntaxMatchingNode internalInvariantRoot;
-
- ///
- /// Initializes a new instance of .
- ///
- public CSharpSyntaxWalkerMatchingBuilder()
- {
- this.internalInvariantRoot = new CSharpSyntaxMatchingNode();
- this.Root = this.internalInvariantRoot;
- }
-
- ///
- /// Visits a namespace declaration.
- /// A namespace may be composed with different segment dot separated, each segment has to be represented by a different node.
- /// However the syntax node is attached to the last node only.
- ///
- /// The namespace declaration node to visit.
- public override void VisitNamespaceDeclaration(NamespaceDeclarationSyntax node)
- {
- // Retrieve the namespace name and split segments
- string name = node.Name.ToString();
- string[] namespaces = name.Split('.');
-
- // Keep track of the initial node the restore the root after the visit
- CSharpSyntaxMatchingNode initialNode = this.Root;
-
- // Browse all namespaces and generate intermediate node for each segment for the copy to the root
- CSharpSyntaxMatchingNode firstNamespaceNode = null;
- foreach (string currentNamespace in namespaces)
- {
- // Create the node and keep track of the first one
- this.Root = this.Root.EnsureNode(currentNamespace);
- if (null == firstNamespaceNode)
- {
- firstNamespaceNode = this.Root;
- }
- }
-
- // Add the syntax node the last segment
- this.Root.AddSyntaxNode(node);
-
- // Triger member visiting
- base.VisitNamespaceDeclaration(node);
-
- // Copy the generated sub tree to the Trie root
- firstNamespaceNode.CopyTo(this.internalInvariantRoot, namespaces[0]);
-
- // Restore the initial root
- this.Root = initialNode;
- }
-
- ///
- /// Visits a class declaration.
- ///
- /// The class declaration to visit.
- public override void VisitClassDeclaration(ClassDeclarationSyntax node)
- {
- // Visit
- this.Visit(
- node: node,
- typeParameterList: node.TypeParameterList,
- exctractName: n => node.Identifier.ValueText,
- targetNode: n => n,
- visit: base.VisitClassDeclaration);
- }
-
- ///
- /// Visits an interface declaration.
- ///
- /// The class declaration to visit.
- public override void VisitInterfaceDeclaration(InterfaceDeclarationSyntax node)
- {
- // Visit
- this.Visit(
- node: node,
- typeParameterList: node.TypeParameterList,
- exctractName: n => node.Identifier.ValueText,
- targetNode: n => n,
- visit: base.VisitInterfaceDeclaration);
- }
-
- ///
- /// Visits an enum declaration.
- ///
- /// The enum declaration to visit.
- public override void VisitEnumDeclaration(EnumDeclarationSyntax node)
- {
- // Visit
- this.Visit(
- node: node,
- typeParameterList: null,
- exctractName: n => node.Identifier.ValueText,
- targetNode: n => n,
- visit: base.VisitEnumDeclaration);
- }
-
-
- ///
- /// Visits an enum member declaration.
- ///
- /// The enum member declaration to visit.
- public override void VisitEnumMemberDeclaration(EnumMemberDeclarationSyntax node)
- {
- // Visit
- this.Visit(
- node: node,
- typeParameterList: null,
- exctractName: n => node.Identifier.ValueText,
- targetNode: n => n,
- visit: base.VisitEnumMemberDeclaration);
- }
-
- ///
- /// Visits a property declaration.
- ///
- /// The property declaration to visit.
- public override void VisitPropertyDeclaration(PropertyDeclarationSyntax node)
- {
- // Visit
- this.Visit(
- node: node,
- typeParameterList: null,
- exctractName: n => n.Identifier.ValueText,
- targetNode: n => n,
- visit: base.VisitPropertyDeclaration);
- }
-
- ///
- /// Visits a field declaration.
- ///
- /// The field declaration to visit.
- public override void VisitFieldDeclaration(FieldDeclarationSyntax node)
- {
- // Visit each variable declaration
- foreach(VariableDeclaratorSyntax variableDeclarationSyntax in node.Declaration.Variables)
- {
- this.Visit(
- node: node,
- typeParameterList: null,
- exctractName: n => variableDeclarationSyntax.Identifier.ValueText,
- targetNode: n => n,
- visit: base.VisitFieldDeclaration);
- }
- }
-
- ///
- /// Visits an indexter declaration.
- ///
- /// The indexter declaration to visit.
- public override void VisitIndexerDeclaration(IndexerDeclarationSyntax node)
- {
- // Compute suffix for representing generics
- string memberName = string.Empty;
- if (null != node.ParameterList)
- {
- memberName = string.Format(
- "[{0}]",
- string.Join(",", node.ParameterList.Parameters.Select(x => x.Type.ToString())));
- }
-
- // Visit
- this.Visit(
- node: node,
- typeParameterList: null,
- exctractName: n => memberName,
- targetNode: n => n,
- visit: base.VisitIndexerDeclaration);
- }
-
- ///
- /// Visits an event declaration.
- ///
- /// The event declaration to visit.
- public override void VisitEventDeclaration(EventDeclarationSyntax node)
- {
- // Visit
- this.Visit(
- node: node,
- typeParameterList: null,
- exctractName: n => n.Identifier.ValueText,
- targetNode: n => n,
- visit: base.VisitEventDeclaration);
- }
-
- ///
- /// Visits an accessor declaration.
- ///
- /// The accessor declaration to visit.
- public override void VisitAccessorDeclaration(AccessorDeclarationSyntax node)
- {
- // Visit
- this.Visit(
- node: node,
- typeParameterList: null,
- exctractName: n => n.Keyword.ValueText,
- targetNode: n => n,
- visit: base.VisitAccessorDeclaration);
- }
-
- ///
- /// Visits a method declaration.
- ///
- /// The method declaration to visit.
- public override void VisitMethodDeclaration(MethodDeclarationSyntax node)
- {
- // Visit
- this.Visit(
- node: node,
- typeParameterList: node.TypeParameterList,
- exctractName: n => n.Identifier.ValueText,
- targetNode: n => n,
- visit: base.VisitMethodDeclaration);
- }
-
- ///
- /// Visits a constructor declaration.
- ///
- /// The constructor declaration to visit.
- public override void VisitConstructorDeclaration(ConstructorDeclarationSyntax node)
- {
- // Visit
- this.Visit(
- node: node,
- typeParameterList: null,
- exctractName: n => "",
- targetNode: n => n,
- visit: base.VisitConstructorDeclaration);
- }
-
- ///
- /// Visits a destructor declaration.
- ///
- /// The destructor declaration to visit.
- public override void VisitDestructorDeclaration(DestructorDeclarationSyntax node)
- {
- // Visit
- this.Visit(
- node: node,
- typeParameterList: null,
- exctractName: n => "",
- targetNode: n => n,
- visit: base.VisitDestructorDeclaration);
- }
-
- ///
- /// Visits parameter list.
- ///
- /// The parameter list to visit.
- public override void VisitParameterList(ParameterListSyntax node)
- {
- // Skip parameter list when the parent is a lambda
- if (
- SyntaxKind.SimpleLambdaExpression == node.Parent.Kind() ||
- SyntaxKind.ParenthesizedLambdaExpression == node.Parent.Kind())
- {
- return;
- }
-
- // Visit
- this.Visit(
- node: node,
- typeParameterList: null,
- exctractName: n => string.Format("({0})", string.Join(",", node.Parameters.Select(x => x.Type.ToString()))),
- targetNode: n => n.Parent,
- visit: base.VisitParameterList);
- }
-
- ///
- /// Visits a member.
- ///
- /// The syntax node type to visit.
- /// The node to visit.
- /// Extract the node name.
- /// The type parameter list.
- /// Resolved the target node.
- /// Visit sub nodes.
- private void Visit(T node, Func exctractName, TypeParameterListSyntax typeParameterList , Func targetNode, Action visit) where T : CSharpSyntaxNode
- {
- // Retrieve the accessor name
- string name = exctractName(node);
-
- // Compute suffix for representing generics
- if (null != typeParameterList)
- {
- name = string.Format(
- "{0}{{{1}}}",
- name,
- string.Join(",", typeParameterList.Parameters.Select(x => x.ToString())));
- }
-
- // Keep track of the initial node the restore the root after the visit
- CSharpSyntaxMatchingNode initialNode = this.Root;
-
- // Create and add the node
- this.Root = this.Root.EnsureNode(name);
- this.Root.AddSyntaxNode(targetNode(node));
-
- // Trigger member visiting
- visit(node);
-
- // Copy the class sub tree to the Trie root
- this.Root.CopyTo(this.internalInvariantRoot, name);
-
- // Restore the initial root
- this.Root = initialNode;
- }
- }
-}
\ No newline at end of file
diff --git a/src/Projbook.Extension.CSharpExtractor/Properties/AssemblyInfo.cs b/src/Projbook.Extension.CSharpExtractor/Properties/AssemblyInfo.cs
deleted file mode 100644
index d9a7916..0000000
--- a/src/Projbook.Extension.CSharpExtractor/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Projbook.Extension.CSharpExtractor")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Projbook.Extension.CSharpExtractor")]
-[assembly: AssemblyCopyright("Copyright © 2016")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("f5431901-29ac-46d4-a717-de2a9114e82d")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/Projbook.Extension.CSharpExtractor/packages.config b/src/Projbook.Extension.CSharpExtractor/packages.config
deleted file mode 100644
index ecf5663..0000000
--- a/src/Projbook.Extension.CSharpExtractor/packages.config
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Projbook.Extension.XmlExtractor/Projbook.Extension.XmlExtractor.csproj b/src/Projbook.Extension.XmlExtractor/Projbook.Extension.XmlExtractor.csproj
deleted file mode 100644
index 1e600b5..0000000
--- a/src/Projbook.Extension.XmlExtractor/Projbook.Extension.XmlExtractor.csproj
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- {BC3E43EB-2263-49B4-883A-B720EDDF9298}
- Library
- Properties
- Projbook.Extension.XmlExtractor
- Projbook.Extension.XmlExtractor
- v4.6.1
- 512
-
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
-
-
- ..\packages\System.IO.Abstractions.2.0.0.136\lib\net40\System.IO.Abstractions.dll
- True
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {8338b756-0519-4d20-ba04-3a8f4839237a}
- Projbook.Extension
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Projbook.Extension.XmlExtractor/Projbook/Extension/Xml/XmlSnippetExtractor.cs b/src/Projbook.Extension.XmlExtractor/Projbook/Extension/Xml/XmlSnippetExtractor.cs
deleted file mode 100644
index 71fd51a..0000000
--- a/src/Projbook.Extension.XmlExtractor/Projbook/Extension/Xml/XmlSnippetExtractor.cs
+++ /dev/null
@@ -1,159 +0,0 @@
-using System;
-using Projbook.Extension.Exception;
-using Projbook.Extension.Spi;
-using System.IO.Abstractions;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Xml;
-
-namespace Projbook.Extension.XmlExtractor
-{
- ///
- /// Extractor in charge of browsing source directories. load file content and extract requested member.
- ///
- [Syntax(name: "xml")]
- public class XmlSnippetExtractor : DefaultSnippetExtractor
- {
- ///
- /// The regex extracting the document namespaces
- ///
- private Regex regex = new Regex(@"xmlns:([^=]+)=""([^""]*)""", RegexOptions.Compiled);
-
- ///
- /// The lazy loaded xml document.
- ///
- private XmlDocument xmlDocument;
-
- ///
- /// The lazy loaded namespace manager.
- ///
- private XmlNamespaceManager xmlNamespaceManager;
-
- ///
- /// Extracts a snippet from a given rule pattern.
- ///
- /// The file system info.
- /// The member pattern to extract.
- /// The extracted snippet.
- public override Extension.Model.Snippet Extract(FileSystemInfoBase fileSystemInfo, string memberPattern)
- {
- // Return the entire code if no member is specified
- if (string.IsNullOrWhiteSpace(memberPattern))
- {
- return base.Extract(fileSystemInfo, memberPattern);
- }
-
- // Load the xml document for xpath execution
- if (null == this.xmlDocument)
- {
- // Load file content
- string sourceCode = base.LoadFile(this.ConvertToFile(fileSystemInfo));
-
- // Remove default avoiding to define and use a prefix for the default namespace
- // This is not strictly correct in a xml point of view but it's closest to most needs
- sourceCode = Regex.Replace(sourceCode, @"xmlns\s*=\s*""[^""]*""", string.Empty);
-
- // Parse the file as xml
- this.xmlDocument = new XmlDocument();
- try
- {
- // Initialize the document and the namespace manager
- this.xmlDocument.LoadXml(sourceCode);
- this.xmlNamespaceManager = new XmlNamespaceManager(this.xmlDocument.NameTable);
-
- // Match namespace declaration for filling the namespace manager
- Match match = this.regex.Match(sourceCode);
- while (match.Success)
- {
- // Collect prefix and namespace value
- string prefix = match.Groups[1].Value.Trim();
- string ns = match.Groups[2].Value.Trim();
-
- // Add namespace declaration to the namespace manager
- xmlNamespaceManager.AddNamespace(prefix, ns);
-
- // Mode to the next matching
- match = match.NextMatch();
- }
- }
-
- // Throw an exception is the file is not loadable as xml document
- catch (System.Exception exception)
- {
- throw new SnippetExtractionException("Cannot parse xml file", exception.Message);
- }
- }
-
- // Execute Xpath query
- XmlNodeList xmlNodeList = null;
- try
- {
- xmlNodeList = this.xmlDocument.SelectNodes(memberPattern, this.xmlNamespaceManager);
- }
- catch
- {
- throw new SnippetExtractionException("Invalid extraction rule", memberPattern);
- }
-
- // Ensure we found a result
- if (xmlNodeList.Count <= 0)
- {
- throw new SnippetExtractionException("Cannot find member", memberPattern);
- }
-
- // Build a snippet for extracted nodes
- return this.BuildSnippet(xmlNodeList);
- }
-
- ///
- /// Builds a snippet from xml node.
- ///
- /// The xml node list.
- /// The built snippet.
- private Extension.Model.Snippet BuildSnippet(XmlNodeList xmlNodeList)
- {
- // Data validation
- if(xmlNodeList == null)
- {
- throw new ArgumentNullException(nameof(xmlNodeList));
- }
-
- // Extract code from each snippets
- StringBuilder stringBuilder = new StringBuilder();
- bool firstSnippet = true;
- for (int i = 0; i < xmlNodeList.Count; ++i)
- {
- // Get the current node
- XmlNode node = xmlNodeList.Item(i);
-
- // Write line return between each snippet
- if (!firstSnippet)
- {
- stringBuilder.AppendLine();
- stringBuilder.AppendLine();
- }
-
- // Write each snippet
- XmlWriterSettings settings = new XmlWriterSettings();
- settings.Indent = true;
- settings.OmitXmlDeclaration = true;
- settings.NewLineOnAttributes = true;
- using (XmlWriter xmlWriter = XmlWriter.Create(stringBuilder, settings))
- {
- node.WriteTo(xmlWriter);
- }
-
- // Flag the first snippet as false
- firstSnippet = false;
- }
-
- // Remove all generate namespace declaration
- // This is produce some output lacking of namespace declaration but it's what is relevant for a xml document extraction
- string output = stringBuilder.ToString();
- output = Regex.Replace(output, @" ?xmlns\s*(:[^=]+)?\s*=\s*""[^""]*""", string.Empty);
-
- // Create the snippet from the extracted code
- return new Model.PlainTextSnippet(output);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Projbook.Extension.XmlExtractor/Properties/AssemblyInfo.cs b/src/Projbook.Extension.XmlExtractor/Properties/AssemblyInfo.cs
deleted file mode 100644
index 35cf6c0..0000000
--- a/src/Projbook.Extension.XmlExtractor/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Projbook.Extension.XmlExtractor")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Projbook.Extension.XmlExtractor")]
-[assembly: AssemblyCopyright("Copyright © 2016")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("bc3e43eb-2263-49b4-883a-b720eddf9298")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/Projbook.Extension.XmlExtractor/packages.config b/src/Projbook.Extension.XmlExtractor/packages.config
deleted file mode 100644
index 0ff97ab..0000000
--- a/src/Projbook.Extension.XmlExtractor/packages.config
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Projbook.Extension/Exception/SnippetExtractionException.cs b/src/Projbook.Extension/Exception/SnippetExtractionException.cs
index e1ded67..3f04cd3 100644
--- a/src/Projbook.Extension/Exception/SnippetExtractionException.cs
+++ b/src/Projbook.Extension/Exception/SnippetExtractionException.cs
@@ -11,9 +11,9 @@
public string Pattern { get; private set; }
///
- /// Initializes a new instance of .
+ /// Initializes a new instance of .
///
- /// Initializes the required .
+ /// Initializes the required message.
/// Initializes the required .
public SnippetExtractionException(string message, string pattern)
: base(message)
diff --git a/src/Projbook.Extension/Extractors/CSharp/CSharpMatchingRule.cs b/src/Projbook.Extension/Extractors/CSharp/CSharpMatchingRule.cs
index 6d6c221..5c94083 100644
--- a/src/Projbook.Extension/Extractors/CSharp/CSharpMatchingRule.cs
+++ b/src/Projbook.Extension/Extractors/CSharp/CSharpMatchingRule.cs
@@ -23,7 +23,7 @@ namespace Projbook.Extension.CSharpExtractor
///
/// Defines rule regex used to parse the snippet into chunks.
/// Expected input format: Path/File.cs [My.Name.Space.Class.Method][(string, string)]
- /// * The first chunk is the file name and will be loaded in
+ /// * The first chunk is the file name and will be loaded in TargetFile
/// * The optional second chunks are all full qualified name to the member separated by "."
/// * The optional last chunk is the method parameters if matching a method.
///
diff --git a/src/Projbook.Extension/Projbook.Extension.csproj b/src/Projbook.Extension/Projbook.Extension.csproj
index c5757f9..47be8d1 100644
--- a/src/Projbook.Extension/Projbook.Extension.csproj
+++ b/src/Projbook.Extension/Projbook.Extension.csproj
@@ -21,6 +21,7 @@
DEBUG;TRACE
prompt
4
+ bin\Debug\Projbook.Extension.XML
pdbonly
@@ -40,14 +41,15 @@
True
-
- ..\..\packages\System.Collections.Immutable.1.1.37\lib\dotnet\System.Collections.Immutable.dll
+
+ ..\..\packages\System.Collections.Immutable.1.3.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll
True
+
-
- ..\..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll
+
+ ..\..\packages\System.Reflection.Metadata.1.4.1\lib\portable-net45+win8\System.Reflection.Metadata.dll
True
diff --git a/src/Projbook.Extension/app.config b/src/Projbook.Extension/app.config
index a11801f..a165e54 100644
--- a/src/Projbook.Extension/app.config
+++ b/src/Projbook.Extension/app.config
@@ -1,15 +1,15 @@
-
+
-
-
+
+
-
-
+
+
-
+
diff --git a/src/Projbook.Extension/packages.config b/src/Projbook.Extension/packages.config
index b851084..258b0f6 100644
--- a/src/Projbook.Extension/packages.config
+++ b/src/Projbook.Extension/packages.config
@@ -3,14 +3,14 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file