public ExecutionResult Execute(Compilation compilation) { var outputPath = Path.Combine(_hostPath, $"script{_id}.dll"); var emitResult = compilation.Emit( $"{_moduleName}{_id}", outputPath, _previousGlobals, _previousMethods ); if (emitResult.Diagnostics.Any()) { return(new ExecutionResult(emitResult.Diagnostics, null)); } // successful emit so save it _previousGlobals = emitResult.Globals; _previousMethods = emitResult.Methods; _previous = compilation; if (emitResult.Assembly != null) { _references = _references.Add(emitResult.Assembly); } _id++; var asm = _loadContext.LoadFromAssemblyPath(outputPath); var method = asm.EntryPoint; var result = method?.Invoke(null, Array.Empty <object>()); return(new ExecutionResult(ImmutableArray <Diagnostic> .Empty, result)); }
private static void GenerateClasses(string rootDirectory, Project project) { Compilation?compilation = project.GetCompilationAsync().Result; if (compilation == null) { return; } Utils.Init(compilation); var gatherInterfacesToGenerateFrom = new GatherInterfacesToGenerateFrom(); gatherInterfacesToGenerateFrom.Visit(compilation.GlobalNamespace); Context context = new Context(compilation, rootDirectory); var wpfUIFramework = new WpfUIFramework(context); var winUIUIFramework = new WinUIUIFramework(context); var winFormsUIFramework = new WinFormsUIFramework(context); var macUIUIFramework = new MacUIFramework(context); foreach (INamedTypeSymbol interfaceType in gatherInterfacesToGenerateFrom.Interfaces) { Console.WriteLine($"Processing {interfaceType.Name}"); var intface = new Interface(context, interfaceType); intface.Generate(wpfUIFramework); //intface.Generate(winUIUIFramework); //intface.Generate(winFormsUIFramework); intface.Generate(macUIUIFramework); intface.GenerateExtensionsClass(); } }
public ScriptHost( ImmutableArray <AssemblyDefinition> references, Compilation?previous, string moduleName ) { _references = references; _previous = previous; _moduleName = moduleName; _previousGlobals = new Dictionary <Symbol, FieldReference>(); _previousMethods = new Dictionary <Symbol, MethodReference>(); var uuid = Guid.NewGuid().ToString(); _loadContext = new AssemblyLoadContext(uuid, true); _hostPath = Path.Combine( Path.GetTempPath(), "Panther", "Execution", $"{moduleName}-{uuid}" ); if (!Directory.Exists(_hostPath)) { Directory.CreateDirectory(_hostPath); } }
public void Execute(GeneratorExecutionContext context) { Compilation?compilation = context.Compilation; compilation = GenerateHelperClasses(context); INamedTypeSymbol?serviceLocatorClass = compilation.GetTypeByMetadataName("DI.ServiceLocator") !; INamedTypeSymbol?transientAttribute = compilation.GetTypeByMetadataName("DI.TransientAttribute") !; INamedTypeSymbol?iEnumerableOfT = compilation.GetTypeByMetadataName("System.Collections.Generic.IEnumerable`1") !.ConstructUnboundGenericType(); INamedTypeSymbol?listOfT = compilation.GetTypeByMetadataName("System.Collections.Generic.List`1") !; var knownTypes = new KnownTypes(iEnumerableOfT, listOfT, transientAttribute); var services = new List <Service>(); foreach (SyntaxTree?tree in compilation.SyntaxTrees) { SemanticModel?semanticModel = compilation.GetSemanticModel(tree); IEnumerable <INamedTypeSymbol>?typesToCreate = from i in tree.GetRoot().DescendantNodesAndSelf().OfType <InvocationExpressionSyntax>() let symbol = semanticModel.GetSymbolInfo(i).Symbol as IMethodSymbol where symbol != null where SymbolEqualityComparer.Default.Equals(symbol.ContainingType, serviceLocatorClass) select symbol.ReturnType as INamedTypeSymbol; foreach (INamedTypeSymbol?typeToCreate in typesToCreate) { CollectServices(context, typeToCreate, compilation, services, knownTypes); } } GenerateServiceLocator(context, services); }
public async Task <ICollection <IEnumValue> > GetListedValuesAsync() { Project project = _workspace.CurrentSolution.Projects.First(p => PathHelper.IsSamePath(p.FilePath !, _unconfiguredProject.FullPath)); Compilation?compilation = await project.GetCompilationAsync(); List <IEnumValue> enumValues = new(); if (_includeEmptyValue) { enumValues.Add(new PageEnumValue(new EnumValue { Name = "", DisplayName = VSResources.StartupObjectNotSet })); } IEntryPointFinderService? entryPointFinderService = project.LanguageServices.GetService <IEntryPointFinderService>(); IEnumerable <INamedTypeSymbol>?entryPoints = entryPointFinderService?.FindEntryPoints(compilation?.GlobalNamespace, SearchForEntryPointsInFormsOnly); if (entryPoints is not null) { enumValues.AddRange(entryPoints.Select(ep => { string name = ep.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat.WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted)); return(new PageEnumValue(new EnumValue { Name = name, DisplayName = name })); })); } return(enumValues); }
public async Task SourceGeneratorBasedOnAdditionalFileGeneratesSyntaxTreesOnce( bool fetchCompilationBeforeAddingGenerator, bool generatorSupportsIncrementalUpdates) { var analyzerReference = new TestGeneratorReference(new AdditionalFileAddedGenerator() { CanApplyChanges = generatorSupportsIncrementalUpdates }); var project = CreateEmptyProject() .AddAnalyzerReference(analyzerReference); // Optionally fetch the compilation first, which validates that we handle both running the generator // when the file already exists, and when it is added incrementally. Compilation?originalCompilation = null; if (fetchCompilationBeforeAddingGenerator) { originalCompilation = await project.GetRequiredCompilationAsync(CancellationToken.None); } project = project.AddAdditionalDocument("Test.txt", "Hello, world!").Project; var newCompilation = await project.GetRequiredCompilationAsync(CancellationToken.None); Assert.NotSame(originalCompilation, newCompilation); var generatedTree = Assert.Single(newCompilation.SyntaxTrees); Assert.Equal("Test.generated", Path.GetFileName(generatedTree.FilePath)); }
private void Purge() { if (this.compilation is null) { if (RefCount == 0) { Inner.Clear(); } return; } lock (this.gate) { if (this.compilation is null) { return; } if (Interlocked.Decrement(ref RefCount) > 0) { foreach (var tree in this.compilation.SyntaxTrees) { Inner.TryRemove(tree, out _); } } else { Inner.Clear(); } this.compilation = null; } }
public async Task SourceGeneratorBasedOnAdditionalFileGeneratesSyntaxTreesOnce( bool fetchCompilationBeforeAddingGenerator, bool useRecoverableTrees) { using var workspace = useRecoverableTrees ? CreateWorkspaceWithRecoverableSyntaxTreesAndWeakCompilations() : CreateWorkspace(); var analyzerReference = new TestGeneratorReference(new GenerateFileForEachAdditionalFileWithContentsCommented() { }); var project = AddEmptyProject(workspace.CurrentSolution) .AddAnalyzerReference(analyzerReference); // Optionally fetch the compilation first, which validates that we handle both running the generator // when the file already exists, and when it is added incrementally. Compilation?originalCompilation = null; if (fetchCompilationBeforeAddingGenerator) { originalCompilation = await project.GetRequiredCompilationAsync(CancellationToken.None); } project = project.AddAdditionalDocument("Test.txt", "Hello, world!").Project; var newCompilation = await project.GetRequiredCompilationAsync(CancellationToken.None); Assert.NotSame(originalCompilation, newCompilation); var generatedTree = Assert.Single(newCompilation.SyntaxTrees); var generatorType = typeof(GenerateFileForEachAdditionalFileWithContentsCommented); Assert.Equal($"{generatorType.Assembly.GetName().Name}\\{generatorType.FullName}\\Test.generated.cs", generatedTree.FilePath); var generatedDocument = Assert.Single(await project.GetSourceGeneratedDocumentsAsync()); Assert.Same(generatedTree, await generatedDocument.GetSyntaxTreeAsync()); }
private static bool VerifyForwardedTypes( Dictionary <INamedTypeSymbol, INamedTypeSymbol> equivalentTypesWithDifferingAssemblies, ISymbol searchSymbol, ISymbol symbolToMatch, Solution solution, Compilation?searchSymbolCompilation, Compilation?symbolToMatchCompilation) { using var _ = PooledHashSet <INamedTypeSymbol> .GetInstance(out var verifiedKeys); var count = equivalentTypesWithDifferingAssemblies.Count; var verifiedCount = 0; // First check forwarded types in searchSymbolCompilation. if (searchSymbolCompilation != null || TryGetCompilation(searchSymbol, solution, out searchSymbolCompilation)) { verifiedCount = VerifyForwardedTypes(equivalentTypesWithDifferingAssemblies, searchSymbolCompilation, verifiedKeys, isSearchSymbolCompilation: true); if (verifiedCount == count) { // All equivalent types verified. return(true); } } if (symbolToMatchCompilation != null || TryGetCompilation(symbolToMatch, solution, out symbolToMatchCompilation)) { // Now check forwarded types in symbolToMatchCompilation. verifiedCount += VerifyForwardedTypes(equivalentTypesWithDifferingAssemblies, symbolToMatchCompilation, verifiedKeys, isSearchSymbolCompilation: false); } return(verifiedCount == count); }
/// <summary> /// Gets the version of the target .NET framework of the compilation. /// </summary> /// <returns> /// Null if the target framenwork is not .NET Framework. /// </returns> /// <remarks> /// This method returns the assembly version of mscorlib for .NET Framework prior version 4.0. /// It is using API diff tool to compare new classes in different versions and decide which version it is referencing /// i.e. for .NET framework 3.5, the returned version would be 2.0.0.0. /// For .NET Framework 4.X, this method returns the actual framework version instead of assembly verison of mscorlib, /// i.e. for .NET framework 4.5.2, this method return 4.5.2 instead of 4.0.0.0. /// </remarks> public static Version?GetDotNetFrameworkVersion([NotNullWhen(returnValue: true)] Compilation?compilation) { if (compilation == null || !IsTypeDeclaredInExpectedAssembly(compilation, "System.String", "mscorlib").GetValueOrDefault()) { return(null); } IAssemblySymbol mscorlibAssembly = compilation.GetSpecialType(SpecialType.System_String).ContainingAssembly; if (mscorlibAssembly.Identity.Version.Major < 4) { return(mscorlibAssembly.Identity.Version); } if (mscorlibAssembly.GetTypeByMetadataName(WellKnownTypeNames.SystemAppContext) != null) { return(new Version(4, 6)); } INamedTypeSymbol typeSymbol = mscorlibAssembly.GetTypeByMetadataName(WellKnownTypeNames.SystemIOUnmanagedMemoryStream); if (!typeSymbol.GetMembers("FlushAsync").IsEmpty) { return(new Version(4, 5, 2)); } typeSymbol = mscorlibAssembly.GetTypeByMetadataName(WellKnownTypeNames.SystemDiagnosticsTracingEventSource); if (typeSymbol != null) { return(typeSymbol.GetMembers("CurrentThreadActivityId").IsEmpty ? new Version(4, 5) : new Version(4, 5, 1)); } return(new Version(4, 0)); }
protected override void EvaluateSubmission(string text) { var syntaxTree = SyntaxTree.Parse(text); var compilation = Compilation.CreateScript(this.Previous, syntaxTree); if (this.ShowTree) { syntaxTree.Root.WriteTo(Console.Out); } if (this.ShowProgram) { compilation.EmitTree(Console.Out); } var result = compilation.Evaluate(this.Variables); if (!result.Diagnostics.Any()) { if (result.Value != null) { Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(result.Value); Console.ResetColor(); } this.Previous = compilation; this.SaveSubmission(text); } else { Console.Error.WriteDiagnostics(result.Diagnostics); } }
internal bool RegisterAttributes( GeneratorExecutionContext context, out CandidateReceiver?typescriptCandidateReceiver, out Compilation?compilation) { // retrieve the populated receiver if (!(context.SyntaxReceiver is CandidateReceiver receiver)) { typescriptCandidateReceiver = null; compilation = null; return(false); } typescriptCandidateReceiver = receiver; // TODO: we should allow source generators to provide source during initialize, so that this step isn't required. if (!(context.Compilation is CSharpCompilation)) { compilation = null; return(false); } compilation = context.Compilation; return(true); }
internal static void VerifyArguments(Diagnostic diagnostic, Compilation?compilation, Func <Diagnostic, bool> isSupportedDiagnostic) { if (diagnostic is DiagnosticWithInfo) { // Compiler diagnostic, skip validations. return; } if (diagnostic == null) { throw new ArgumentNullException(nameof(diagnostic)); } if (compilation != null) { VerifyDiagnosticLocationsInCompilation(diagnostic, compilation); } if (!isSupportedDiagnostic(diagnostic)) { throw new ArgumentException(string.Format(CodeAnalysisResources.UnsupportedDiagnosticReported, diagnostic.Id), nameof(diagnostic)); } if (!UnicodeCharacterUtilities.IsValidIdentifier(diagnostic.Id)) { // Disallow invalid diagnostic IDs. // Note that the parsing logic in Csc/Vbc MSBuild tasks to decode command line compiler output relies on diagnostics having a valid ID. // See https://github.com/dotnet/roslyn/issues/4376 for details. throw new ArgumentException(string.Format(CodeAnalysisResources.InvalidDiagnosticIdReported, diagnostic.Id), nameof(diagnostic)); } }
static bool isEnabledWithAnalyzerConfigOptions( DiagnosticDescriptor descriptor, SeverityFilter severityFilter, Compilation? compilation, AnalyzerOptions? analyzerOptions, CancellationToken cancellationToken) { if (compilation != null && compilation.Options.SyntaxTreeOptionsProvider is { } treeOptions) { foreach (var tree in compilation.SyntaxTrees) { // Check if diagnostic is enabled by SyntaxTree.DiagnosticOptions or Bulk configuration from AnalyzerConfigOptions. if (treeOptions.TryGetDiagnosticValue(tree, descriptor.Id, cancellationToken, out var configuredValue) || analyzerOptions.TryGetSeverityFromBulkConfiguration(tree, compilation, descriptor, cancellationToken, out configuredValue)) { if (configuredValue != ReportDiagnostic.Suppress && !severityFilter.Contains(configuredValue)) { return true; } } } } return false; }
public async Task SourceGeneratorBasedOnAdditionalFileGeneratesSyntaxTreesOnce( bool fetchCompilationBeforeAddingGenerator) { using var workspace = new AdhocWorkspace(); var analyzerReference = new TestGeneratorReference(new GenerateFileForEachAdditionalFileWithContentsCommented() { }); var project = AddEmptyProject(workspace.CurrentSolution) .AddAnalyzerReference(analyzerReference); // Optionally fetch the compilation first, which validates that we handle both running the generator // when the file already exists, and when it is added incrementally. Compilation?originalCompilation = null; if (fetchCompilationBeforeAddingGenerator) { originalCompilation = await project.GetRequiredCompilationAsync(CancellationToken.None); } project = project.AddAdditionalDocument("Test.txt", "Hello, world!").Project; var newCompilation = await project.GetRequiredCompilationAsync(CancellationToken.None); Assert.NotSame(originalCompilation, newCompilation); var generatedTree = Assert.Single(newCompilation.SyntaxTrees); Assert.Equal("Microsoft.CodeAnalysis.Workspaces.UnitTests\\Microsoft.CodeAnalysis.UnitTests.SolutionWithSourceGeneratorTests+GenerateFileForEachAdditionalFileWithContentsCommented\\Test.generated.cs", generatedTree.FilePath); }
/// <inheritdoc cref="CreateExecutionContext(Compilation, GeneratorInitialize)"/> public static GeneratorExecutionContext CreateExecutionContext(Compilation?compilation) { SourceGeneratorProxy proxy = new(); CSharpGeneratorDriver driver = CSharpGeneratorDriver.Create(proxy); _ = driver.RunGenerators(compilation ?? CreateBaseCompilation()); return(proxy.ExecutionContext); }
private Task <IEnumerable <Diagnostic> > ComputeProjectDiagnosticAnalyzerDiagnosticsAsync( Project project, ProjectDiagnosticAnalyzer analyzer, Compilation?compilation, CancellationToken cancellationToken) { return(AnalyzerService.ComputeProjectDiagnosticAnalyzerDiagnosticsAsync(project, analyzer, compilation, DiagnosticLogAggregator, cancellationToken)); }
protected State(ValueSource <Optional <Compilation> >?compilation, Compilation?declarationOnlyCompilation) { // Declaration-only compilations should never have any references Contract.ThrowIfTrue(declarationOnlyCompilation != null && declarationOnlyCompilation.ExternalReferences.Any()); Compilation = compilation; DeclarationOnlyCompilation = declarationOnlyCompilation; }
public void Execute(SourceGeneratorContext context) { Compilation?compilation = context.Compilation; string sourceBuilder = Generate(compilation); context.AddSource("ServiceLocator.cs", SourceText.From(sourceBuilder, Encoding.UTF8)); }
private Compilation(bool isScript, Compilation?previous, params SyntaxTree[]?syntaxTrees) { this.IsScript = isScript; this.Previous = previous; this.SyntaxTrees = syntaxTrees == null ? ImmutableArray <SyntaxTree> .Empty : syntaxTrees.ToImmutableArray(); }
private Task <IEnumerable <Diagnostic> > ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync( Document document, DocumentDiagnosticAnalyzer analyzer, AnalysisKind kind, Compilation?compilation, CancellationToken cancellationToken) { return(AnalyzerService.ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, analyzer, kind, compilation, DiagnosticLogAggregator, cancellationToken)); }
/// <inheritdooc /> public override bool CanGenerateBody(INamedTypeSymbol typeSymbol, Compilation?compilation) { // TODO: Use more efficient version! var nonStaticFieldsAndProperties = GetNonStaticNonPrivateFieldsAndProperties(typeSymbol); // Intentionally passing 'null' as compilation argument, because we want to skip the analysis whether the StructGenerator attribute is defined or not. // The generator can do stuff if there are some non-private fields or props, or the other generators can produce something. return(nonStaticFieldsAndProperties.Any() || _typeEqualityGenerator.CanGenerateBody(typeSymbol, compilation: null) || _toStringGenerator.CanGenerateBody(typeSymbol, compilation: null)); }
private static bool OriginalSymbolsMatchCore( ISymbol searchSymbol, ISymbol symbolToMatch, Solution solution, Compilation?searchSymbolCompilation, Compilation?symbolToMatchCompilation) { if (searchSymbol == null || symbolToMatch == null) { return(false); } searchSymbol = searchSymbol.GetOriginalUnreducedDefinition(); symbolToMatch = symbolToMatch.GetOriginalUnreducedDefinition(); // We compare the given searchSymbol and symbolToMatch for equivalence using SymbolEquivalenceComparer // as follows: // 1) We compare the given symbols using the SymbolEquivalenceComparer.IgnoreAssembliesInstance, // which ignores the containing assemblies for named types equivalence checks. This is required // to handle equivalent named types which are forwarded to completely different assemblies. // 2) If the symbols are NOT equivalent ignoring assemblies, then they cannot be equivalent. // 3) Otherwise, if the symbols ARE equivalent ignoring assemblies, they may or may not be equivalent // if containing assemblies are NOT ignored. We need to perform additional checks to ensure they // are indeed equivalent: // // (a) If IgnoreAssembliesInstance.Equals equivalence visitor encountered any pair of non-nested // named types which were equivalent in all aspects, except that they resided in different // assemblies, we need to ensure that all such pairs are indeed equivalent types. Such a pair // of named types is equivalent if and only if one of them is a type defined in either // searchSymbolCompilation(C1) or symbolToMatchCompilation(C2), say defined in reference assembly // A (version v1) in compilation C1, and the other type is a forwarded type, such that it is // forwarded from reference assembly A (version v2) to assembly B in compilation C2. // (b) Otherwise, if no such named type pairs were encountered, symbols ARE equivalent. using var _ = PooledDictionary <INamedTypeSymbol, INamedTypeSymbol> .GetInstance(out var equivalentTypesWithDifferingAssemblies); // 1) Compare searchSymbol and symbolToMatch using SymbolEquivalenceComparer.IgnoreAssembliesInstance if (!SymbolEquivalenceComparer.IgnoreAssembliesInstance.Equals(searchSymbol, symbolToMatch, equivalentTypesWithDifferingAssemblies)) { // 2) If the symbols are NOT equivalent ignoring assemblies, then they cannot be equivalent. return(false); } // 3) If the symbols ARE equivalent ignoring assemblies, they may or may not be equivalent if containing assemblies are NOT ignored. if (equivalentTypesWithDifferingAssemblies.Count > 0) { // Step 3a) Ensure that all pairs of named types in equivalentTypesWithDifferingAssemblies are indeed equivalent types. return(VerifyForwardedTypes( equivalentTypesWithDifferingAssemblies, searchSymbol, symbolToMatch, solution, searchSymbolCompilation, symbolToMatchCompilation)); } // 3b) If no such named type pairs were encountered, symbols ARE equivalent. return(true); }
/// <summary> /// Determine whether a type (given by name) is actually declared in the expected assembly (also given by name) /// </summary> /// <remarks> /// This can be used to decide whether we are referencing the expected framework for a given type. /// For example, System.String exists in mscorlib for .NET Framework and System.Runtime for other framework (e.g. .NET Core). /// </remarks> public static bool?IsTypeDeclaredInExpectedAssembly([NotNullWhen(returnValue: true)] Compilation?compilation, string typeName, string assemblyName) { if (compilation == null) { return(null); } INamedTypeSymbol?typeSymbol = compilation.GetOrCreateTypeByMetadataName(typeName); return(typeSymbol?.ContainingAssembly.Identity.Name.Equals(assemblyName, StringComparison.Ordinal)); }
private static async Task <(bool success, bool isCaseSensitive)> TryDetermineIfCompilationIsCaseSensitiveAsync(CodeAnalysis.Project?project) { if (project is null) { return(false, false); } Compilation?compilation = await project.GetCompilationAsync(); return(compilation is null ? (false, false) : (true, compilation.IsCaseSensitive)); }
/// <inheritdoc /> public override bool CanGenerateBody(INamedTypeSymbol typeSymbol, Compilation?compilation) { if (compilation != null && StructRecordGenerator.HasStructRecordAttribute(typeSymbol, compilation)) { // StructRecord attribute is applied, don't need to generate anything. return(false); } // 5 is the number of equality members. return(GetExistingMembersToGenerate(typeSymbol).Length < 5); }
public async Task <Compilation?> GetCompilationAsync() { if (compilation == null) { string code = await File.ReadAllTextAsync(kryptonFileLocation); compilation = await Task.Run(() => Analyser.Analyse(code)); } return(compilation); }
private Compilation( ImmutableArray <AssemblyDefinition> references, bool isScript, Compilation?previous, params SyntaxTree[] syntaxTrees ) { References = references; IsScript = isScript; Previous = previous; SyntaxTrees = syntaxTrees.ToImmutableArray(); }
private async Task <ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> > MergeProjectDiagnosticAnalyzerDiagnosticsAsync( Project project, ImmutableArray <DiagnosticAnalyzer> ideAnalyzers, Compilation?compilation, ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> result, CancellationToken cancellationToken) { try { // create result map var version = await GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false); foreach (var analyzer in ideAnalyzers) { var builder = new DiagnosticAnalysisResultBuilder(project, version); if (analyzer is DocumentDiagnosticAnalyzer documentAnalyzer) { foreach (var document in project.Documents) { var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (tree != null) { builder.AddSyntaxDiagnostics(tree, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Syntax, compilation, cancellationToken).ConfigureAwait(false)); builder.AddSemanticDiagnostics(tree, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Semantic, compilation, cancellationToken).ConfigureAwait(false)); } else { builder.AddExternalSyntaxDiagnostics(document.Id, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Syntax, compilation, cancellationToken).ConfigureAwait(false)); builder.AddExternalSemanticDiagnostics(document.Id, await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(document, documentAnalyzer, AnalysisKind.Semantic, compilation, cancellationToken).ConfigureAwait(false)); } } } if (analyzer is ProjectDiagnosticAnalyzer projectAnalyzer) { builder.AddCompilationDiagnostics(await ComputeProjectDiagnosticAnalyzerDiagnosticsAsync(project, projectAnalyzer, compilation, cancellationToken).ConfigureAwait(false)); } // merge the result to existing one. // there can be existing one from compiler driver with empty set. overwrite it with // ide one. result = result.SetItem(analyzer, DiagnosticAnalysisResult.CreateFromBuilder(builder)); } return(result); } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }
public bool TryGetCompilation([NotNullWhen(true)] out Compilation?compilation) { var state = ReadState(); if (state.FinalCompilation != null && state.FinalCompilation.TryGetValue(out var compilationOpt) && compilationOpt.HasValue) { compilation = compilationOpt.Value; return(true); } compilation = null; return(false); }