public void BeforeCompile(IBeforeCompileContext context) { // Firstly, I need to resolve the namespace of the ModuleProvider instance in this current compilation. string ns = GetModuleProviderNamespace(context.Compilation.SyntaxTrees); // Next, get all the available modules in assembly and compilation references. var modules = GetAvailableModules(context.Compilation).ToList(); // Map them to a collection of statements var statements = modules.Select(m => F.ParseStatement("AddModule<" + module + ">();")).ToList(); // Now, I'll create the dynamic implementation as a private class. var cu = F.CompilationUnit() .AddMembers( F.NamespaceDeclaration(F.IdentifierName(ns)) .AddMembers( F.ClassDeclaration("ModuleProvider") .WithModifiers(F.TokenList(F.Token(K.PartialKeyword))) .AddMembers( F.MethodDeclaration(F.PredefinedType(F.Token(K.VoidKeyword)), "Setup") .WithModifiers( F.TokenList( F.Token(K.ProtectedKeyword), F.Token(K.OverrideKeyword))) .WithBody(F.Block(statements)) ) ) ) .NormalizeWhitespace(indentation("\t")); var tree = T.Create(cu); context.Compilation = context.Compilation.AddSyntaxTrees(tree); }
public static DoctestWithoutNamespaceOrError SplitHeaderBody(Code code) { var tree = CSharpSyntaxTree.ParseText(code.Text); var root = (CompilationUnitSyntax)tree.GetRoot(); int headerEnd = 0; // exclusive string body = code.Text; foreach (var trivia in root.DescendantTrivia()) { if (SplitLineRe.IsMatch(trivia.ToString())) { headerEnd = trivia.SpanStart; body = code.Text.Substring(trivia.Span.End).Trim(); break; } } // A work-around to skip descending into children if the parent node has been accepted int acceptedEnd = 0; var usings = new List <UsingDirective>(); foreach (var node in root.DescendantNodes()) { if (node.SpanStart < acceptedEnd || node.SpanStart >= headerEnd) { break; } switch (node) { case Syntax.UsingDirectiveSyntax usingDirectiveSyntax: usings.Add(new UsingDirective( usingDirectiveSyntax.Name.ToString(), usingDirectiveSyntax.Alias?.Name.ToString())); acceptedEnd = usingDirectiveSyntax.Span.End; break; default: var location = node.SyntaxTree.GetLineSpan(node.Span); return(new DoctestWithoutNamespaceOrError( null, new Error( $"Expected only using directives in the header, but got: {node.Kind()}", location.StartLinePosition.Line, location.StartLinePosition.Character))); } } return(new DoctestWithoutNamespaceOrError( new DoctestWithoutNamespace(usings, body, code.Line, code.Column), null)); }
public static bool HasUsingDirective(this CS.CSharpSyntaxTree tree, string fullName) { if (tree == null) { throw new ArgumentNullException(nameof(tree)); } if (string.IsNullOrWhiteSpace(fullName)) { throw new ArgumentException("given namespace cannot be null or empty.", nameof(fullName)); } fullName = fullName.Trim(); return(tree.GetRoot() .DescendantNodes(MatchesNamespaceOrRoot) .OfType <CS.Syntax.UsingDirectiveSyntax>() .Any(u => u.Name.ToString().Equals(fullName, StringComparison.OrdinalIgnoreCase))); }
public static VisualBasicSyntaxNode ConvertCompilationTree(CS.CSharpCompilation compilation, CS.CSharpSyntaxTree tree) { var visualBasicSyntaxVisitor = new NodesVisitor(compilation.GetSemanticModel(tree, true)); return(tree.GetRoot().Accept(visualBasicSyntaxVisitor.TriviaConvertingVisitor)); }
public override SyntaxTree CreateSyntaxTree(string filePath, ParseOptions options, Encoding encoding, SyntaxNode root) { options ??= GetDefaultParseOptions(); return(CSharpSyntaxTree.Create((CSharpSyntaxNode)root, (CSharpParseOptions)options, filePath, encoding)); }
internal override SyntaxTree ParseGeneratedSourceText(GeneratedSourceText input, string fileName, CancellationToken cancellationToken) => CSharpSyntaxTree.ParseTextLazy(input.Text, (CSharpParseOptions)_state.ParseOptions, fileName);