private static async Task <Tuple <Compilation, SemanticModel, TypeDeclarationSyntaxInfo> > VerifyCompilation(Compilation compilation, TypeDeclarationSyntaxInfo typeNode) { var tree = typeNode.Syntax.SyntaxTree; if (tree == null) { var cu = CSharpSyntaxTree.Create( SyntaxFactory .CompilationUnit() .WithMembers(SyntaxFactory.List(new[] { (MemberDeclarationSyntax)typeNode.Syntax }))); var root = await cu.GetRootAsync().ConfigureAwait(false); typeNode.Syntax = (TypeDeclarationSyntax)root.ChildNodes().First(); var newCompilation = compilation.AddSyntaxTrees(cu); var semanticModel = newCompilation.GetSemanticModel(cu); return(new Tuple <Compilation, SemanticModel, TypeDeclarationSyntaxInfo>(newCompilation, semanticModel, typeNode)); } var result = AddToCompilation(compilation, tree); var childNodes = result.Item2.GetRoot().DescendantNodesAndSelf(); typeNode.Syntax = childNodes.OfType <TypeDeclarationSyntax>().First(); return(new Tuple <Compilation, SemanticModel, TypeDeclarationSyntaxInfo>( result.Item1, result.Item1.GetSemanticModel(result.Item2), typeNode)); }
private static Compilation GetCompilation(Type type) { lock (decompiledTypes) { if (!decompiledTypes.TryGetValue(type, out Compilation compilation)) { EntityHandle handle = MetadataTokenHelpers.TryAsEntityHandle(type.MetadataToken) ?? throw new InvalidOperationException(); string assemblyPath = type.Assembly.Location; if (!decompilers.TryGetValue(assemblyPath, out CSharpDecompiler decompiler)) { decompiler = CreateDecompiler(assemblyPath); decompilers.Add(assemblyPath, decompiler); } string sourceCode = decompiler.DecompileAsString(handle); sourceCode = ClosureTypeDeclarationRegex.Replace(sourceCode, ShaderGenerator.DelegateTypeName); sourceCode = LambdaMethodDeclarationRegex.Replace(sourceCode, $"internal void {ShaderGenerator.DelegateEntryPointName}"); SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sourceCode, CSharpParseOptions.Default.WithLanguageVersion(Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8)); compilation = globalCompilation.AddSyntaxTrees(syntaxTree); decompiledTypes.Add(type, compilation); } return(compilation); } }
public async Task AddingFileWithNewLibraryImport_DoesNotRegenerateOriginalMethod() { string source = CodeSnippets.BasicParametersAndModifiers <int>(); Compilation comp1 = await TestUtils.CreateCompilation(source); Microsoft.Interop.LibraryImportGenerator generator = new(); GeneratorDriver driver = TestUtils.CreateDriver(comp1, null, new[] { generator }, EnableIncrementalTrackingDriverOptions); driver = driver.RunGenerators(comp1); Compilation comp2 = comp1.AddSyntaxTrees(CSharpSyntaxTree.ParseText(CodeSnippets.BasicParametersAndModifiers <bool>(), new CSharpParseOptions(LanguageVersion.Preview))); GeneratorDriver driver2 = driver.RunGenerators(comp2); GeneratorRunResult runResult = driver2.GetRunResult().Results[0]; Assert.Collection(runResult.TrackedSteps[StepNames.CalculateStubInformation], step => { Assert.Collection(step.Outputs, output => Assert.Equal(IncrementalStepRunReason.Unchanged, output.Reason)); }, step => { Assert.Collection(step.Outputs, output => Assert.Equal(IncrementalStepRunReason.New, output.Reason)); }); }
public Assembly CraeteAssembly(Compilation compilation, params MemberDeclarationSyntax[] assemblyMembers) { assemblyMembers = assemblyMembers ?? Array.Empty <MemberDeclarationSyntax>(); var @namespace = NamespaceDeclaration(IdentifierName(AssemblyNamespace)).AddMembers(assemblyMembers); var @compilationUnit = CompilationUnit().AddMembers(@namespace); var inner_compilation = compilation.AddSyntaxTrees(@compilationUnit.SyntaxTree); var stream = new MemoryStream(); var emitResult = inner_compilation.Emit(stream); if (_diagnostics != null) { var errors = string.Join("\n", emitResult.Diagnostics.Select(x => x.ToString()).ToArray()); _diagnostics?.CompilationResult(@compilationUnit.NormalizeWhitespace(elasticTrivia: true).ToFullString()); _diagnostics?.CompilationResult(errors); } if (emitResult.Success) { stream.Seek(0, SeekOrigin.Begin); var assembly = Assembly.Load(stream.ToArray()); return(assembly); } return(default);
public async Task LoadAsync(CancellationToken cancellationToken) { _cancellationToken = cancellationToken; // add all compiler extensions to the project var trees = new ConcurrentBag <SyntaxTree>(); Parallel.ForEach(Compilation.References.OfType <PortableExecutableReference>(), r => { foreach (var source in LoadCompilerExtensionsFromAssembly(r.FilePath)) { try { trees.Add(CSharpSyntaxTree.ParseText(source.source)); } catch (Exception e) { Log.Error(e, "Failed to parse C# source from resource {0} in assembly {1}", source.name, r.FilePath); } } }); Compilation = Compilation.AddSyntaxTrees(trees); _semanticModel = new ConcurrentDictionary <SyntaxTree, SemanticModel>(SyntaxTreeComparer.Instance); Attributes = new AttributeRegistry(); LoadAttributes(Compilation, cancellationToken); foreach (var reference in Compilation.References.OfType <CompilationReference>()) { LoadAttributes(reference.Compilation, cancellationToken); } Attributes = Attributes; }
Compilation GenerateFromResource(string name, GeneratorExecutionContext context, Compilation compilation, string GenerationFolder) { var assembly = typeof(JsonGenerator).Assembly; using (Stream resource = assembly.GetManifestResourceStream($"JsonSrcGen.{name}")) using (StreamReader reader = new StreamReader(resource)) { string content = reader.ReadToEnd(); context.AddSource(name, SourceText.From(content, Encoding.UTF8)); CSharpParseOptions options = (context.Compilation as CSharpCompilation).SyntaxTrees[0].Options as CSharpParseOptions; compilation = compilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(SourceText.From(content, Encoding.UTF8), options)); if (GenerationFolder != null) { try { File.WriteAllText(Path.Combine(GenerationFolder, name), content); } catch (DirectoryNotFoundException) { //Don't fail the generation as this makes the CI Unit Tests fail } } return(compilation); } }
public Type Compile() { if (expressions.Count != 1) { throw new Exception("HAML node stack misaligned. Expected only 1 root node."); } FlushStringRun(); _renderMethod = _renderMethod.AddBodyStatements(SyntaxFactory.Block(expressions.Peek())); _compilationTargetClass = _compilationTargetClass.AddMembers(_renderMethod); _compilationUnit = _compilationUnit .AddMembers(_compilationTargetClass); _compilationUnit = _compilationUnit.NormalizeWhitespace(" ", true); _compilation = _compilation.AddSyntaxTrees(CSharpSyntaxTree.Create(_compilationUnit)); MemoryStream stream = new MemoryStream(); EmitResult result = _compilation.Emit(stream); _compilation.Emit("Output.dll"); if (!result.Success) { throw new HamlCompilationFailedException(result.Diagnostics); } stream.Flush(); stream.Seek(0, SeekOrigin.Begin); Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(stream); return(assembly.GetType(_compilationTargetClass.Identifier.Text)); }
private static Tuple <Compilation, SyntaxTree> AddToCompilation(Compilation compilation, SyntaxTree tree) { if (!compilation.ContainsSyntaxTree(tree)) { var newTree = tree; if (!tree.HasCompilationUnitRoot) { var childNodes = tree.GetRoot() .ChildNodes() .AsArray(); newTree = CSharpSyntaxTree.Create(SyntaxFactory.CompilationUnit() .WithMembers( SyntaxFactory.List(childNodes.OfType <MemberDeclarationSyntax>())) .WithUsings( SyntaxFactory.List(childNodes.OfType <UsingDirectiveSyntax>())) .WithExterns( SyntaxFactory.List(childNodes.OfType <ExternAliasDirectiveSyntax>()))); } var comp = compilation.AddSyntaxTrees(newTree); return(new Tuple <Compilation, SyntaxTree>(comp, newTree)); } return(new Tuple <Compilation, SyntaxTree>(compilation, tree)); }
/// <summary> /// Decompiles a target method and returns its <see cref="SyntaxTree"/> and <see cref="SemanticModel"/> info /// </summary> /// <param name="methodInfo">The input <see cref="MethodInfo"/> to inspect</param> /// <param name="methodType">The type of method to decompile</param> /// <param name="rootNode">The root node for the syntax tree of the input method</param> /// <param name="semanticModel">The semantic model for the input method</param> public void GetSyntaxTree(MethodInfo methodInfo, MethodType methodType, out MethodDeclarationSyntax rootNode, out SemanticModel semanticModel) { string sourceCode = methodType switch { MethodType.Execute => GetSyntaxTreeForExecuteMethod(methodInfo), MethodType.Static => GetSyntaxTreeForStaticMethod(methodInfo), _ => throw new ArgumentOutOfRangeException(nameof(methodType), $"Invalid method type: {methodType}") }; // Load the type syntax tree SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sourceCode); // Get the root node to return rootNode = syntaxTree .GetRoot() .DescendantNodes() .OfType <MethodDeclarationSyntax>() .First(node => node.Identifier.ToString().Equals(methodInfo.Name) || node.GetLeadingTrivia().ToFullString().Contains(methodInfo.Name)); // Update the incremental compilation and retrieve the syntax tree for the method Compilation compilation = _Compilation.AddSyntaxTrees(syntaxTree); semanticModel = compilation.GetSemanticModel(syntaxTree); }
private static async Task <Tuple <Compilation, SemanticModel, SyntaxTree, NamespaceDeclarationSyntaxInfo> > VerifyCompilation(Compilation compilation, NamespaceDeclarationSyntaxInfo namespaceNode) { SemanticModel semanticModel; var tree = namespaceNode.Syntax.SyntaxTree; if (tree == null) { var compilationUnit = SyntaxFactory.CompilationUnit() .WithMembers(SyntaxFactory.List(new[] { (MemberDeclarationSyntax)namespaceNode.Syntax })); var cu = CSharpSyntaxTree.Create(compilationUnit); var root = await cu.GetRootAsync().ConfigureAwait(false); namespaceNode.Syntax = root.ChildNodes().First(); var newCompilation = compilation.AddSyntaxTrees(cu); semanticModel = newCompilation.GetSemanticModel(cu); return(new Tuple <Compilation, SemanticModel, SyntaxTree, NamespaceDeclarationSyntaxInfo>(newCompilation, semanticModel, cu, namespaceNode)); } var result = AddToCompilation(compilation, tree); compilation = result.Item1; tree = result.Item2; semanticModel = compilation.GetSemanticModel(tree); return(new Tuple <Compilation, SemanticModel, SyntaxTree, NamespaceDeclarationSyntaxInfo>(compilation, semanticModel, tree, namespaceNode)); }
public static Compilation AddSource(this Compilation compilation, string source) { var options = (compilation as CSharpCompilation)?.SyntaxTrees[0].Options as CSharpParseOptions; SyntaxTree attributeSyntaxTree = CSharpSyntaxTree.ParseText(SourceText.From(source, Encoding.UTF8), options); return(compilation.AddSyntaxTrees(attributeSyntaxTree)); }
private static Compilation GetStubCompilation(GeneratorExecutionContext context, Class stubClass) { Compilation compilation = context.Compilation; var options = (compilation as CSharpCompilation)?.SyntaxTrees[0].Options as CSharpParseOptions; return(compilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(SourceText.From(ClassWriter.Write(stubClass), Encoding.UTF8), options))); }
static ImplementationFactoryTestsBase() { var thisAssembly = typeof(ImplementationFactoryTestsBase).Assembly; string dotNetDir = Path.GetDirectoryName(typeof(object).GetTypeInfo().Assembly.Location); // For actually executing code, we need to reference the compiled test assembly, so that the types we're seeing at the same // types as the ones the unit tests are seeing. // However, this doesn't give us source locations, which we need in order to test diagnostics. So for testing these, we include // the test project's files as source, rather than referencing the test project. var executionProject = new AdhocWorkspace() .AddProject("Execution", LanguageNames.CSharp) .WithCompilationOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) .WithSpecificDiagnosticOptions(new KeyValuePair <string, ReportDiagnostic>[] { KeyValuePair.Create("CS1701", ReportDiagnostic.Suppress), KeyValuePair.Create("CS1702", ReportDiagnostic.Suppress), }) .WithNullableContextOptions(NullableContextOptions.Enable)) .AddMetadataReference(MetadataReference.CreateFromFile(typeof(object).Assembly.Location)) .AddMetadataReference(MetadataReference.CreateFromFile(Path.Join(dotNetDir, "netstandard.dll"))) .AddMetadataReference(MetadataReference.CreateFromFile(Path.Join(dotNetDir, "System.Runtime.dll"))) .AddMetadataReference(MetadataReference.CreateFromFile(Path.Join(dotNetDir, "System.Net.Http.dll"))) .AddMetadataReference(MetadataReference.CreateFromFile(Path.Join(dotNetDir, "System.Collections.dll"))) .AddMetadataReference(MetadataReference.CreateFromFile(Path.Join(dotNetDir, "System.Linq.Expressions.dll"))) .AddMetadataReference(MetadataReference.CreateFromFile(typeof(RestClient).Assembly.Location)) .AddMetadataReference(MetadataReference.CreateFromFile(thisAssembly.Location)); executionCompilation = executionProject.GetCompilationAsync().Result; var diagnosticsProject = new AdhocWorkspace() .AddProject("Diagnostics", LanguageNames.CSharp) .WithCompilationOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) .WithNullableContextOptions(NullableContextOptions.Enable)) .AddMetadataReference(MetadataReference.CreateFromFile(typeof(object).Assembly.Location)) .AddMetadataReference(MetadataReference.CreateFromFile(Path.Join(dotNetDir, "netstandard.dll"))) .AddMetadataReference(MetadataReference.CreateFromFile(Path.Join(dotNetDir, "System.Runtime.dll"))) .AddMetadataReference(MetadataReference.CreateFromFile(Path.Join(dotNetDir, "System.Net.Http.dll"))) .AddMetadataReference(MetadataReference.CreateFromFile(Path.Join(dotNetDir, "System.Linq.Expressions.dll"))) .AddMetadataReference(MetadataReference.CreateFromFile(typeof(RestClient).Assembly.Location)); diagnosticsCompilation = diagnosticsProject.GetCompilationAsync().Result; var syntaxTrees = new List <SyntaxTree>(); foreach (string resourceName in thisAssembly.GetManifestResourceNames()) { if (resourceName.EndsWith(".cs")) { using (var reader = new StreamReader(thisAssembly.GetManifestResourceStream(resourceName))) { syntaxTrees.Add(SyntaxFactory.ParseSyntaxTree(reader.ReadToEnd())); } } } diagnosticsCompilation = diagnosticsCompilation.AddSyntaxTrees(syntaxTrees); }
/// <inheritdoc/> public void UpdateCompilation(IEnumerable <CSharpSyntaxTree>?trees) { if (trees is not null) { CSharpCompilation compilation = Compilation; Compilation = Compilation.AddSyntaxTrees(trees); OnUpdate(compilation); } }
/// <inheritdoc/> public void UpdateCompilation(CSharpSyntaxTree?tree) { if (tree is not null) { CSharpCompilation compilation = Compilation; Compilation = Compilation.AddSyntaxTrees(tree); OnUpdate(compilation); } }
public static Compilation AddSyntaxTreeToCompilation(Compilation sourceCompilation, string sourceText) { var options = (sourceCompilation as CSharpCompilation).SyntaxTrees[0].Options as CSharpParseOptions; var compilation = sourceCompilation.AddSyntaxTrees( CSharpSyntaxTree.ParseText(SourceText.From(sourceText, Encoding.UTF8), options)); return(compilation); }
private static IReadOnlyList <TagHelperDescriptor> GetTagHelpersFromCompilation(Compilation compilation, StaticCompilationTagHelperFeature tagHelperFeature, SyntaxTree syntaxTrees) { var compilationWithDeclarations = compilation.AddSyntaxTrees(syntaxTrees); tagHelperFeature.Compilation = compilationWithDeclarations; tagHelperFeature.TargetAssembly = compilationWithDeclarations.Assembly; return(tagHelperFeature.GetDescriptors()); }
private void SingleFirstPassSurroundedByClassAndMethod(SyntaxTree tree) { var newTree = _languageConversion.CreateTree(_languageConversion.WithSurroundingClassAndMethod(tree.GetText().ToString())); _methodBodyOnly = true; _sourceCompilation = _sourceCompilation.AddSyntaxTrees(newTree); _syntaxTreesToConvert = new[] { newTree }; Convert(); }
/// <summary> /// Decompiles a target method and returns its <see cref="SyntaxTree"/> and <see cref="SemanticModel"/> info /// </summary> /// <param name="methodInfo">The input <see cref="MethodInfo"/> to inspect</param> /// <param name="rootNode">The root node for the syntax tree of the input method</param> /// <param name="semanticModel">The semantic model for the input method</param> public void GetSyntaxTree(MethodInfo methodInfo, out MethodDeclarationSyntax rootNode, out SemanticModel semanticModel) { lock (Lock) { // Get the handle of the containing type method string assemblyPath = methodInfo.DeclaringType?.Assembly.Location ?? throw new InvalidOperationException(); EntityHandle typeHandle = MetadataTokenHelpers.TryAsEntityHandle(methodInfo.DeclaringType.MetadataToken) ?? throw new InvalidOperationException(); // Get or create a decompiler for the target assembly, and decompile the type if (!Decompilers.TryGetValue(assemblyPath, out CSharpDecompiler decompiler)) { decompiler = CreateDecompiler(assemblyPath); Decompilers.Add(assemblyPath, decompiler); } // Decompile the method source and fix the method declaration for local methods converted to lambdas string sourceCode = decompiler.DecompileAsString(typeHandle), typeFixedCode = ClosureTypeDeclarationRegex.Replace(sourceCode, "Shader"), methodFixedCode = LambdaMethodDeclarationRegex.Replace(typeFixedCode, m => $"// {m.Value}{Environment.NewLine} internal void Main"); // Workaround for some local methods not being decompiled correctly if (!methodFixedCode.Contains("internal void Main")) { EntityHandle methodHandle = MetadataTokenHelpers.TryAsEntityHandle(methodInfo.MetadataToken) ?? throw new InvalidOperationException(); string methodOnlySourceCode = decompiler.DecompileAsString(methodHandle), methodOnlyFixedSourceCode = LambdaMethodDeclarationRegex.Replace(methodOnlySourceCode, m => $"// {m.Value}{Environment.NewLine} internal void Main"), methodOnlyIndentedSourceCode = $" {methodOnlyFixedSourceCode.Replace(Environment.NewLine, $"{Environment.NewLine} ")}"; int lastClosedBracketsIndex = methodFixedCode.LastIndexOf('}'); methodFixedCode = methodFixedCode.Insert(lastClosedBracketsIndex, methodOnlyIndentedSourceCode); } // Unwrap the nested fields string unwrappedSourceCode = UnwrapSyntaxTree(methodFixedCode); // Remove the in keyword from the source string inFixedSourceCode = Regex.Replace(unwrappedSourceCode, @"(?<!\w)in ", string.Empty); // Tweak the out declarations string outFixedSourceCode = RefactorInlineOutDeclarations(inFixedSourceCode, methodInfo.Name); // Load the type syntax tree SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(outFixedSourceCode); // Get the root node to return rootNode = syntaxTree.GetRoot().DescendantNodes().OfType <MethodDeclarationSyntax>().First(node => node.GetLeadingTrivia().ToFullString().Contains(methodInfo.Name)); // Update the incremental compilation and retrieve the syntax tree for the method _Compilation = _Compilation.AddSyntaxTrees(syntaxTree); semanticModel = _Compilation.GetSemanticModel(syntaxTree); } }
public static (Assembly Assembly, List <Diagnostic> Diagnostics) Compile(string code) { // Parse the C# code... CSharpParseOptions parseOptions = new CSharpParseOptions() .WithKind(SourceCodeKind.Regular) // ...as representing a complete .cs file .WithLanguageVersion(LanguageVersion.Latest); // ...enabling the latest language features // Compile the C# code... CSharpCompilationOptions compileOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) // ...to a dll .WithWarningLevel(2) .WithOptimizationLevel(OptimizationLevel.Release) // ...in Release configuration .WithAllowUnsafe(enabled: true); // ...enabling unsafe code // Invoke the compiler... Compilation compilation = CSharpCompilation.Create("TestInMemoryAssembly") // ..with some fake dll name .WithOptions(compileOptions) .AddReferences( MetadataReference.CreateFromFile(typeof(object).Assembly.Location), MetadataReference.CreateFromFile(typeof(INotifyPropertyChanged).Assembly.Location), MetadataReference.CreateFromFile(typeof(ISet <>).Assembly.Location), MetadataReference.CreateFromFile(typeof(RAssert).Assembly.Location), #if DEBUG MetadataReference.CreateFromFile(@"..\..\..\Conan.Plugin.PropertyChanged\bin\Debug\Conan.Plugin.PropertyChanged.dll") #else MetadataReference.CreateFromFile(@"..\..\..\Conan.Plugin.PropertyChanged\bin\Release\Conan.Plugin.PropertyChanged.dll") #endif ); // Parse and compile the C# code into a *.dll and *.xml file in-memory var tree = CSharpSyntaxTree.ParseText(code, parseOptions); compilation = compilation.AddSyntaxTrees(tree); var diagnostics = new List <Diagnostic>(); var rewriter = new PropertyChangedRewriter(); compilation = rewriter.Rewrite(compilation, diagnostics.Add); var peStream = new MemoryStream(); var emitResult = compilation.Emit(peStream); if (!emitResult.Success) { throw new InvalidOperationException("Compilation failed: " + string.Join("\n", emitResult.Diagnostics)); } // Parse the *.dll (with Cecil) and the *.xml (with XDocument) peStream.Seek(0, SeekOrigin.Begin); return(Assembly.Load(peStream.ToArray()), diagnostics); }
internal static Compilation AddSource(this Compilation compilation, ref GeneratorExecutionContext context, SourceCode sourceCode) { var sourceText = SourceText.From(sourceCode.Text, Encoding.UTF8); context.AddSource(sourceCode.HintName, sourceText); // NB: https://github.com/dotnet/roslyn/issues/49753 // To be replaced after above issue is resolved. var options = (CSharpParseOptions)((CSharpCompilation)compilation).SyntaxTrees[0].Options; return(compilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(sourceText, options))); }
public EmitResult Generate(IDictionary <string, MetadataReference> existingReferences) { Compilation = CSharpCompilation.Create( assemblyName: AssemblyName, options: Worker.OriginalCompilation.Options, references: Worker.OriginalCompilation.References); foreach (var other in Requires.Keys) { if (other.EmitResult != null && !other.EmitResult.Success) { // Skip this reference if it hasn't beed emitted continue; } // If we're already referencing this assembly then skip it if (existingReferences.ContainsKey(other.AssemblyName)) { continue; } Compilation = Compilation.AddReferences(other.RealOrShallowReference()); } foreach (var syntaxReference in TypeSymbol.DeclaringSyntaxReferences) { var node = syntaxReference.GetSyntax(); var tree = syntaxReference.SyntaxTree; var root = tree.GetRoot(); var nodesToRemove = GetNodesToRemove(root, node).ToArray(); // what it looks like when removed var newRoot = root.RemoveNodes(nodesToRemove, SyntaxRemoveOptions.KeepDirectives); var newTree = SyntaxFactory.SyntaxTree(newRoot, options: tree.Options, path: tree.FilePath, encoding: Encoding.UTF8); // update compilation with code removed Compilation = Compilation.AddSyntaxTrees(newTree); } OutputStream = new MemoryStream(); EmitResult = Compilation.Emit(OutputStream); if (!EmitResult.Success) { return(EmitResult); } OutputStream.Position = 0; Reference = new MetadataImageReference(OutputStream); OutputStream.Position = 0; return(EmitResult); }
protected void UpdateCompilationWith(SourceText[] sourceTexts) { if (sourceTexts is null) { throw new ArgumentNullException(nameof(sourceTexts)); } var options = ((CSharpCompilation)_compilation).SyntaxTrees[0].Options; var sourceTrees = sourceTexts.ConvertAll(sourceText => CSharpSyntaxTree.ParseText(sourceText, (CSharpParseOptions)options)); _compilation = _compilation.AddSyntaxTrees(sourceTrees); }
private static void RebuildSemanticModel(ref SyntaxTree oldTree, ref SyntaxTree tree, ref SyntaxNode root, ref Compilation compilation, out SemanticModel semanticModel) { if (oldTree != null) { compilation = compilation.RemoveSyntaxTrees(oldTree); } oldTree = root.SyntaxTree; compilation = compilation.AddSyntaxTrees(root.SyntaxTree); tree = compilation.SyntaxTrees.Last(); root = tree.GetRoot(); semanticModel = compilation.GetSemanticModel(tree); }
public static List <StaticMethodSource> GetStaticMethods(Compilation libraryCompilation, string sourceCode, Dictionary <CodeLocation, StaticMethodSource> methodsMap) { var tree = SyntaxTree.ParseText(sourceCode); var compilation = libraryCompilation.AddSyntaxTrees(tree); var queue = new Queue <StaticMethodSource>(); var visitedMethods = new HashSet <CodeLocation>(); Traverse(tree.GetRoot(), node => { if (node is MemberAccessExpressionSyntax) { var model = compilation.GetSemanticModel(node.SyntaxTree); var info = model.GetSymbolInfo((ExpressionSyntax)node); if (info.Symbol != null && info.Symbol.Kind == SymbolKind.Method && info.Symbol.DeclaringSyntaxNodes.Count == 1) { var methodLocation = new CodeLocation(info.Symbol.DeclaringSyntaxNodes[0]); if (methodsMap.ContainsKey(methodLocation)) { if (!visitedMethods.Contains(methodLocation)) { visitedMethods.Add(methodLocation); queue.Enqueue(methodsMap[methodLocation]); } } } } return(false); }); var result = new List <StaticMethodSource>(); while (queue.Any()) { var method = queue.Dequeue(); result.Add(method); if (method.MethodReferences != null) { foreach (var methodReference in method.MethodReferences) { if (!visitedMethods.Contains(methodReference)) { visitedMethods.Add(methodReference); queue.Enqueue(methodsMap[methodReference]); } } } } return(result); }
/// <summary> /// Adds custom Types (Services.cs, Attributes) to the compilation /// </summary> /// <param name="compilation">compilation, where the types should be added</param> /// <returns>new Compilation with types added</returns> private static Compilation AddOwnTypesToCompilation(Compilation compilation) { var options = (compilation as CSharpCompilation)?.SyntaxTrees[0].Options as CSharpParseOptions; var tempCompilation = compilation .AddSyntaxTrees(CSharpSyntaxTree.ParseText(SourceText.From(Types.ServicesStub, Encoding.UTF8), options)) .AddSyntaxTrees(CSharpSyntaxTree.ParseText(SourceText.From(Types.TransientAttribute, Encoding.UTF8), options)) .AddSyntaxTrees(CSharpSyntaxTree.ParseText(SourceText.From(Types.PrimaryConstructorAttribute, Encoding.UTF8), options)); return(tempCompilation); }
protected static Compilation GenerateSourceCodeFromResource( string resourceName, GeneratorExecutionContext context, Compilation compilation) { string sourceCode = EmbbededResourceReader.GetResource(resourceName); context.AddSource("Generated__" + resourceName, SourceText.From(sourceCode, Encoding.UTF8)); var options = (context.Compilation as CSharpCompilation).SyntaxTrees[0].Options as CSharpParseOptions; var generatedCodeSyntax = CSharpSyntaxTree.ParseText(SourceText.From(sourceCode, Encoding.UTF8), options); compilation = compilation.AddSyntaxTrees(generatedCodeSyntax); return(compilation); }
/// <summary> /// Adds the <paramref name="compilationUnit" /> to the normalized compilation. /// </summary> /// <param name="compilationUnit">The compilation unit that should be added.</param> /// <param name="fileName">The name of the generated file.</param> protected void AddCompilationUnit([NotNull] CompilationUnitSyntax compilationUnit, string fileName = null) { Requires.NotNull(compilationUnit, nameof(compilationUnit)); var path = $"{fileName ?? String.Empty}.g.cs{Guid.NewGuid()}"; // Ideally, we'd construct the syntax tree from the compilation unit directly instead of printing out the // compilation unit and then parsing it again. However, if we do that, we can no longer use any C# 6 features // in the generated code - probably some Roslyn bug. const string header = "#line hidden\n#pragma warning disable 0414, 0649, 0108, 0169\n"; var file = header + compilationUnit.NormalizeWhitespace().ToFullString(); var syntaxTree = SyntaxFactory.ParseSyntaxTree(file, new CSharpParseOptions(), path, Encoding.UTF8); Compilation = Compilation.AddSyntaxTrees(syntaxTree); }
public async Task ChangingMarshallingStrategy_RegeneratesStub() { string stubSource = CodeSnippets.BasicParametersAndModifiers("CustomType"); string customTypeImpl1 = "struct CustomType { System.IntPtr handle; }"; string customTypeImpl2 = "class CustomType : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid { public CustomType():base(true){} protected override bool ReleaseHandle(){return true;} }"; Compilation comp1 = await TestUtils.CreateCompilation(stubSource); SyntaxTree customTypeImpl1Tree = CSharpSyntaxTree.ParseText(customTypeImpl1, new CSharpParseOptions(LanguageVersion.Preview)); comp1 = comp1.AddSyntaxTrees(customTypeImpl1Tree); Microsoft.Interop.DllImportGenerator generator = new(); GeneratorDriver driver = TestUtils.CreateDriver(comp1, null, new[] { generator }); driver = driver.RunGenerators(comp1); generator.IncrementalTracker = new IncrementalityTracker(); Compilation comp2 = comp1.ReplaceSyntaxTree(customTypeImpl1Tree, CSharpSyntaxTree.ParseText(customTypeImpl2, new CSharpParseOptions(LanguageVersion.Preview))); driver.RunGenerators(comp2); Assert.Collection(generator.IncrementalTracker.ExecutedSteps, step => { Assert.Equal(IncrementalityTracker.StepName.CalculateStubInformation, step.Step); }, step => { Assert.Equal(IncrementalityTracker.StepName.GenerateSingleStub, step.Step); }, step => { Assert.Equal(IncrementalityTracker.StepName.NormalizeWhitespace, step.Step); }, step => { Assert.Equal(IncrementalityTracker.StepName.ConcatenateStubs, step.Step); }, step => { Assert.Equal(IncrementalityTracker.StepName.OutputSourceFile, step.Step); }); }
public EventPropertyGetter Compile( ICodegenClass clazz, ClassLoaderProvider classLoaderProvider, Type interfaceClass, string classLevelComment) { // build members and namespaces var memberSet = new LinkedHashSet <ICodegenMember>(clazz.Members); var classes = clazz.GetReferencedClasses(); var imports = CompileImports(classes); // generate code var code = GenerateCode(imports, clazz, memberSet, classLevelComment); var version = LanguageVersion.Latest; var options = new CSharpParseOptions( languageVersion: version, documentationMode: DocumentationMode.None, kind: SourceCodeKind.Regular, preprocessorSymbols: null); var syntaxTree = CSharpSyntaxTree.ParseText(code, options); _compilation = _compilation.AddSyntaxTrees(syntaxTree); using (var stream = new MemoryStream()) { var emitResult = _compilation.Emit(stream); if (emitResult.Success) { stream.Seek(0, SeekOrigin.Begin); var assembly = Assembly.Load(stream.ToArray()); } else { var failures = emitResult.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error); } } throw new NotImplementedException(); }
private static Tuple<Compilation, SyntaxTree> AddToCompilation(Compilation compilation, SyntaxTree tree) { if (!compilation.ContainsSyntaxTree(tree)) { var newTree = tree; if (!tree.HasCompilationUnitRoot) { var childNodes = tree.GetRoot() .ChildNodes() .AsArray(); newTree = CSharpSyntaxTree.Create(SyntaxFactory.CompilationUnit() .WithMembers( SyntaxFactory.List(childNodes.OfType<MemberDeclarationSyntax>())) .WithUsings( SyntaxFactory.List(childNodes.OfType<UsingDirectiveSyntax>())) .WithExterns( SyntaxFactory.List(childNodes.OfType<ExternAliasDirectiveSyntax>()))); } var comp = compilation.AddSyntaxTrees(newTree); return new Tuple<Compilation, SyntaxTree>(comp, newTree); } return new Tuple<Compilation, SyntaxTree>(compilation, tree); }
public override ITypeSymbol GetTypeSymbolFromFullName(string fullName, Compilation compilation) { ITypeSymbol typeSymbol = compilation.GetTypeByMetadataName(fullName); if (typeSymbol == null) { var parsedTypeName = SyntaxFactory.ParseTypeName(fullName); // Check to see if the name we parsed has any skipped text. If it does, don't bother trying to // speculatively bind it because we'll likely just get the wrong thing since we found a bunch // of non-sensical tokens. if (parsedTypeName.ContainsSkippedText) { return null; } // If we couldn't get the name, we just grab the first tree in the compilation to // speculatively bind at position zero. However, if there *aren't* any trees, we fork the // compilation with an empty tree for the purposes of speculative binding. // // I'm a bad person. var tree = compilation.SyntaxTrees.FirstOrDefault(); if (tree == null) { tree = SyntaxFactory.ParseSyntaxTree(""); compilation = compilation.AddSyntaxTrees(tree); } var semanticModel = compilation.GetSemanticModel(tree); typeSymbol = semanticModel.GetSpeculativeTypeInfo(0, parsedTypeName, SpeculativeBindingOption.BindAsTypeOrNamespace).Type; } if (typeSymbol == null) { Debug.Fail("Could not find type: " + fullName); throw new ArgumentException(); } return typeSymbol; }
private static async Task<Tuple<Compilation, SemanticModel, TypeDeclarationSyntaxInfo>> VerifyCompilation(Compilation compilation, TypeDeclarationSyntaxInfo typeNode) { var tree = typeNode.Syntax.SyntaxTree; if (tree == null) { var cu = CSharpSyntaxTree.Create( SyntaxFactory .CompilationUnit() .WithMembers(SyntaxFactory.List(new[] { (MemberDeclarationSyntax)typeNode.Syntax }))); var root = await cu.GetRootAsync().ConfigureAwait(false); typeNode.Syntax = (TypeDeclarationSyntax)root.ChildNodes().First(); var newCompilation = compilation.AddSyntaxTrees(cu); var semanticModel = newCompilation.GetSemanticModel(cu); return new Tuple<Compilation, SemanticModel, TypeDeclarationSyntaxInfo>(newCompilation, semanticModel, typeNode); } var result = AddToCompilation(compilation, tree); var childNodes = result.Item2.GetRoot().DescendantNodesAndSelf(); typeNode.Syntax = childNodes.OfType<TypeDeclarationSyntax>().First(); return new Tuple<Compilation, SemanticModel, TypeDeclarationSyntaxInfo>( result.Item1, result.Item1.GetSemanticModel(result.Item2), typeNode); }
public override ITypeSymbol GetTypeSymbolFromFullName(string fullName, Compilation compilation) { ITypeSymbol typeSymbol = compilation.GetTypeByMetadataName(fullName); if (typeSymbol == null) { var parsedTypeName = SyntaxFactory.ParseTypeName(fullName); // If we couldn't get the name, we just grab the first tree in the compilation to // speculatively bind at position zero. However, if there *aren't* any trees, we fork the // compilation with an empty tree for the purposes of speculative binding. // // I'm a bad person. var tree = compilation.SyntaxTrees.FirstOrDefault(); if (tree == null) { tree = SyntaxFactory.ParseSyntaxTree(""); compilation = compilation.AddSyntaxTrees(tree); } var semanticModel = compilation.GetSemanticModel(tree); typeSymbol = semanticModel.GetSpeculativeTypeInfo(0, parsedTypeName, SpeculativeBindingOption.BindAsTypeOrNamespace).Type; } if (typeSymbol == null) { Debug.Fail("Could not find type: " + fullName); throw new ArgumentException(); } return typeSymbol; }
private static async Task<Tuple<Compilation, SemanticModel, SyntaxTree, NamespaceDeclarationSyntaxInfo>> VerifyCompilation(Compilation compilation, NamespaceDeclarationSyntaxInfo namespaceNode) { SemanticModel semanticModel; var tree = namespaceNode.Syntax.SyntaxTree; if (tree == null) { var compilationUnit = SyntaxFactory.CompilationUnit() .WithMembers(SyntaxFactory.List(new[] { (MemberDeclarationSyntax)namespaceNode.Syntax })); var cu = CSharpSyntaxTree.Create(compilationUnit); var root = await cu.GetRootAsync().ConfigureAwait(false); namespaceNode.Syntax = root.ChildNodes().First(); var newCompilation = compilation.AddSyntaxTrees(cu); semanticModel = newCompilation.GetSemanticModel(cu); return new Tuple<Compilation, SemanticModel, SyntaxTree, NamespaceDeclarationSyntaxInfo>(newCompilation, semanticModel, cu, namespaceNode); } var result = AddToCompilation(compilation, tree); compilation = result.Item1; tree = result.Item2; semanticModel = compilation.GetSemanticModel(tree); return new Tuple<Compilation, SemanticModel, SyntaxTree, NamespaceDeclarationSyntaxInfo>(compilation, semanticModel, tree, namespaceNode); }