public FileInformation(string path) { var programText = File.ReadAllText(path); SyntaxTree tree = CSharpSyntaxTree.ParseText(programText); root = tree.GetCompilationUnitRoot(); UsedNamespaces = root.Usings.Select(x => x.Name.ToString()); //Console.WriteLine($"The tree is a {root.Kind()} node."); //Console.WriteLine($"The tree has {root.Members.Count} elements in it."); //Console.WriteLine($"The tree has {root.Usings.Count} using statements. They are:"); //foreach (UsingDirectiveSyntax element in root.Usings) // Console.WriteLine($"\t{element.Name}"); foreach (var item in root.DescendantTokens().Where(m => m.Kind() == SyntaxKind.IdentifierToken)) { SyntaxKind type = item.Parent.Kind(); if (type == SyntaxKind.IdentifierName) { type = item.Parent.Parent.Kind(); } HashSet <string> list; if (!pairs.TryGetValue(type, out list)) { list = new HashSet <string>(); pairs.Add(type, list); } list.Add(item.Text); } List <Type> types = root.DescendantNodes().Where(m => m.Kind() == SyntaxKind.IdentifierName).Select(x => x.Parent.GetType()).ToList(); UsedMembers = pairs.Select(x => x.Value).SelectMany(x => x); UsedAttributes = Consume(SyntaxKind.Attribute); DefinedClasses = Consume(SyntaxKind.ClassDeclaration); DefinedFunctions = Consume(SyntaxKind.MethodDeclaration, SyntaxKind.ConstructorDeclaration); DefinedVariables = Consume(SyntaxKind.VariableDeclarator, SyntaxKind.Parameter, SyntaxKind.PropertyDeclaration, SyntaxKind.ForEachStatement, SyntaxKind.Argument, SyntaxKind.SimpleAssignmentExpression); var nodes = root.DescendantNodes().Where(m => m.Kind() == SyntaxKind.Parameter); var available = nodes.SelectMany(x => { var children = x.ChildNodes(); if (children == null || children.FirstOrDefault() == null) { return(new List <SyntaxNode>()); } return(new List <SyntaxNode> { children.First() }); }); UsedTypes = available.Select(x => x.ToString().RemoveSpecialCharacters()); UsedTypes = UsedTypes.Concat(Consume(SyntaxKind.ObjectCreationExpression, SyntaxKind.VariableDeclaration, SyntaxKind.SimpleBaseType, SyntaxKind.ClassDeclaration)); UsedFunctions = Consume(SyntaxKind.MethodDeclaration, SyntaxKind.ConstructorDeclaration, SyntaxKind.InvocationExpression, SyntaxKind.Parameter, SyntaxKind.PropertyDeclaration, SyntaxKind.ForEachStatement); UsedGenerics = Consume(SyntaxKind.GenericName); }
public static List <MyToken> Parse(string code) { CompilationUnitSyntax tree = SyntaxFactory.ParseCompilationUnit(code); IEnumerable <SyntaxToken> rawTokens = tree.DescendantTokens(); var malFormedToken = rawTokens.FirstOrDefault(x => x.IsMissing); if (malFormedToken.Kind() == SyntaxKind.None) { malFormedToken = rawTokens.FirstOrDefault(t => t.GetAllTrivia().Any( x => x.Kind() == SyntaxKind.SkippedTokensTrivia)); } if (malFormedToken.Kind() != SyntaxKind.None) { throw new Exception($"Received code is malformed around: {malFormedToken}"); } int runningIndex = 0; var myTokens = new List <MyToken>(); foreach (var rawToken in rawTokens) { if (rawToken.HasLeadingTrivia) { foreach (var trivia in rawToken.LeadingTrivia) { if (trivia.Kind() == SyntaxKind.WhitespaceTrivia || trivia.Kind() == SyntaxKind.EndOfLineTrivia) { continue; } myTokens.Add(MyToken.Create(runningIndex++, trivia)); } } myTokens.Add(MyToken.Create(runningIndex++, rawToken)); if (rawToken.HasTrailingTrivia) { foreach (var trivia in rawToken.TrailingTrivia) { if (trivia.Kind() == SyntaxKind.WhitespaceTrivia || trivia.Kind() == SyntaxKind.EndOfLineTrivia) { continue; } myTokens.Add(MyToken.Create(runningIndex++, trivia)); } } } return(myTokens); }