Esempio n. 1
0
        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));
            });
        }
Esempio n. 4
0
        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);
Esempio n. 5
0
        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;
        }
Esempio n. 6
0
        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);
                }
        }
Esempio n. 7
0
        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));
        }
Esempio n. 8
0
        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));
        }
Esempio n. 9
0
        /// <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);
        }
Esempio n. 10
0
        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));
        }
Esempio n. 11
0
        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));
        }
Esempio n. 12
0
        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)));
        }
Esempio n. 13
0
        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);
        }
Esempio n. 14
0
 /// <inheritdoc/>
 public void UpdateCompilation(IEnumerable <CSharpSyntaxTree>?trees)
 {
     if (trees is not null)
     {
         CSharpCompilation compilation = Compilation;
         Compilation = Compilation.AddSyntaxTrees(trees);
         OnUpdate(compilation);
     }
 }
Esempio n. 15
0
 /// <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);
        }
Esempio n. 17
0
        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());
        }
Esempio n. 18
0
        private void SingleFirstPassSurroundedByClassAndMethod(SyntaxTree tree)
        {
            var newTree = _languageConversion.CreateTree(_languageConversion.WithSurroundingClassAndMethod(tree.GetText().ToString()));

            _methodBodyOnly       = true;
            _sourceCompilation    = _sourceCompilation.AddSyntaxTrees(newTree);
            _syntaxTreesToConvert = new[] { newTree };
            Convert();
        }
Esempio n. 19
0
        /// <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);
            }
        }
Esempio n. 20
0
        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)));
        }
Esempio n. 22
0
        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);
        }
Esempio n. 23
0
        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);
        }
Esempio n. 24
0
 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);
 }
Esempio n. 25
0
        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);
        }
Esempio n. 26
0
        /// <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);
        }
Esempio n. 27
0
        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);
        }
Esempio n. 28
0
        /// <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);
        }
Esempio n. 29
0
        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);
            });
        }
Esempio n. 30
0
        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);
		}
Esempio n. 34
0
        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);
		}