private async Task <SolutionStateChecksums> ComputeChecksumsAsync(CancellationToken cancellationToken) { try { using (Logger.LogBlock(FunctionId.SolutionState_ComputeChecksumsAsync, FilePath, cancellationToken)) { // get states by id order to have deterministic checksum var orderedProjectIds = ChecksumCache.GetOrCreate(ProjectIds, _ => ProjectIds.OrderBy(id => id.Id).ToImmutableArray()); var projectChecksumTasks = orderedProjectIds.Select(id => ProjectStates[id]) .Where(s => RemoteSupportedLanguages.IsSupported(s.Language)) .Select(s => s.GetChecksumAsync(cancellationToken)); var serializer = _solutionServices.Workspace.Services.GetService <ISerializerService>(); var infoChecksum = serializer.CreateChecksum(SolutionAttributes, cancellationToken); var optionsChecksum = serializer.CreateChecksum(Options, cancellationToken); var analyzerReferenceChecksums = ChecksumCache.GetOrCreate <AnalyzerReferenceChecksumCollection>(AnalyzerReferences, _ => new AnalyzerReferenceChecksumCollection(AnalyzerReferences.Select(r => serializer.CreateChecksum(r, cancellationToken)).ToArray())); var projectChecksums = await Task.WhenAll(projectChecksumTasks).ConfigureAwait(false); return(new SolutionStateChecksums(infoChecksum, optionsChecksum, new ProjectChecksumCollection(projectChecksums), analyzerReferenceChecksums)); } } catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e, cancellationToken)) { throw ExceptionUtilities.Unreachable; } }
public static async Task <ImmutableArray <INamedTypeSymbol> > FindTypesAsync( INamedTypeSymbol type, Solution solution, IImmutableSet <Project>?projects, bool transitive, DependentTypesKind kind, CancellationToken cancellationToken) { if (SerializableSymbolAndProjectId.TryCreate(type, solution, cancellationToken, out var serializedType)) { var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false); if (client != null) { var projectIds = projects?.Where(p => RemoteSupportedLanguages.IsSupported(p.Language)).SelectAsArray(p => p.Id) ?? default; var result = await client.TryInvokeAsync <IRemoteDependentTypeFinderService, ImmutableArray <SerializableSymbolAndProjectId> >( solution, (service, solutionInfo, cancellationToken) => service.FindTypesAsync(solutionInfo, serializedType, projectIds, transitive, kind, cancellationToken), cancellationToken).ConfigureAwait(false); if (!result.HasValue) { return(ImmutableArray <INamedTypeSymbol> .Empty); } return(await RehydrateAsync(solution, result.Value, cancellationToken).ConfigureAwait(false)); } // TODO: Do not fall back to in-proc https://github.com/dotnet/roslyn/issues/47557 } return(await FindTypesInCurrentProcessAsync(type, solution, projects, transitive, kind, cancellationToken).ConfigureAwait(false)); }
public async Task <ImmutableArray <AddImportFixData> > GetFixesAsync( Document document, TextSpan span, string diagnosticId, int maxResults, bool placeSystemNamespaceFirst, ISymbolSearchService symbolSearchService, bool searchReferenceAssemblies, ImmutableArray <PackageSource> packageSources, CancellationToken cancellationToken) { if (RemoteSupportedLanguages.IsSupported(document.Project.Language)) { var callbackTarget = new RemoteSymbolSearchService(symbolSearchService, cancellationToken); var result = await document.Project.Solution.TryRunCodeAnalysisRemoteAsync <IList <AddImportFixData> >( callbackTarget, nameof(IRemoteAddImportFeatureService.GetFixesAsync), new object[] { document.Id, span, diagnosticId, maxResults, placeSystemNamespaceFirst, searchReferenceAssemblies, packageSources }, cancellationToken).ConfigureAwait(false); if (result != null) { return(result.ToImmutableArray()); } } return(await GetFixesInCurrentProcessAsync( document, span, diagnosticId, maxResults, placeSystemNamespaceFirst, symbolSearchService, searchReferenceAssemblies, packageSources, cancellationToken).ConfigureAwait(false)); }
public static async Task <ImmutableArray <SerializableImportCompletionItem> > GetUnimportedExtensionMethodsAsync( Document document, int position, ITypeSymbol receiverTypeSymbol, ISet <string> namespaceInScope, bool forceIndexCreation, CancellationToken cancellationToken) { var ticks = Environment.TickCount; var project = document.Project; // This service is only defined for C# and VB, but we'll be a bit paranoid. var client = RemoteSupportedLanguages.IsSupported(project.Language) ? await project.Solution.Workspace.TryGetRemoteHostClientAsync(cancellationToken).ConfigureAwait(false) : null; var(serializableItems, counter) = client == null ? await GetUnimportedExtensionMethodsInCurrentProcessAsync(document, position, receiverTypeSymbol, namespaceInScope, forceIndexCreation, cancellationToken).ConfigureAwait(false) : await GetUnimportedExtensionMethodsInRemoteProcessAsync(client, document, position, receiverTypeSymbol, namespaceInScope, forceIndexCreation, cancellationToken).ConfigureAwait(false); counter.TotalTicks = Environment.TickCount - ticks; counter.TotalExtensionMethodsProvided = serializableItems.Length; counter.Report(); return(serializableItems); }
public async Task FindAsync( SolutionState state, HashSet <Checksum> searchingChecksumsLeft, Dictionary <Checksum, object> result, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // verify input Contract.ThrowIfFalse(state.TryGetStateChecksums(out var stateChecksum)); Contract.ThrowIfFalse(this == stateChecksum); if (searchingChecksumsLeft.Remove(Checksum)) { result[Checksum] = this; } if (searchingChecksumsLeft.Remove(Attributes)) { result[Attributes] = state.SolutionAttributes; } if (searchingChecksumsLeft.Remove(Options)) { result[Options] = state.Options; } if (searchingChecksumsLeft.Remove(Projects.Checksum)) { result[Projects.Checksum] = Projects; } if (searchingChecksumsLeft.Remove(AnalyzerReferences.Checksum)) { result[AnalyzerReferences.Checksum] = AnalyzerReferences; } foreach (var(_, projectState) in state.ProjectStates) { // solution state checksum can't be created without project state checksums created first // check unsupported projects if (!projectState.TryGetStateChecksums(out var projectStateChecksums)) { Contract.ThrowIfTrue(RemoteSupportedLanguages.IsSupported(projectState.Language)); continue; } await projectStateChecksums.FindAsync(projectState, searchingChecksumsLeft, result, cancellationToken).ConfigureAwait(false); if (searchingChecksumsLeft.Count == 0) { break; } } ChecksumCollection.Find(state.AnalyzerReferences, AnalyzerReferences, searchingChecksumsLeft, result, cancellationToken); }
private static async Task <RemoteHostClient> TryGetRemoteHostClientAsync(Project project, CancellationToken cancellationToken) { // This service is only defined for C# and VB, but we'll be a bit paranoid. if (!RemoteSupportedLanguages.IsSupported(project.Language)) { return(null); } return(await project.Solution.Workspace.TryGetRemoteHostClientAsync(RemoteFeatureOptions.NavigateToEnabled, cancellationToken).ConfigureAwait(false)); }
public async Task <ProjectInfo> CreateProjectInfoAsync(Checksum projectChecksum, CancellationToken cancellationToken) { var projectChecksums = await GetAssetAsync <ProjectStateChecksums>(projectChecksum, cancellationToken).ConfigureAwait(false); var projectInfo = await GetAssetAsync <ProjectInfo.ProjectAttributes>(projectChecksums.Info, cancellationToken).ConfigureAwait(false); if (!RemoteSupportedLanguages.IsSupported(projectInfo.Language)) { // only add project our workspace supports. // workspace doesn't allow creating project with unknown languages return(null); } var compilationOptions = projectInfo.FixUpCompilationOptions( await GetAssetAsync <CompilationOptions>(projectChecksums.CompilationOptions, cancellationToken).ConfigureAwait(false)); var parseOptions = await GetAssetAsync <ParseOptions>(projectChecksums.ParseOptions, cancellationToken).ConfigureAwait(false); var projectReferences = await CreateCollectionAsync <ProjectReference>(projectChecksums.ProjectReferences, cancellationToken).ConfigureAwait(false); var metadataReferences = await CreateCollectionAsync <MetadataReference>(projectChecksums.MetadataReferences, cancellationToken).ConfigureAwait(false); var analyzerReferences = await CreateCollectionAsync <AnalyzerReference>(projectChecksums.AnalyzerReferences, cancellationToken).ConfigureAwait(false); var documentInfos = await CreateDocumentInfosAsync(projectChecksums.Documents, cancellationToken).ConfigureAwait(false); var additionalDocumentInfos = await CreateDocumentInfosAsync(projectChecksums.AdditionalDocuments, cancellationToken).ConfigureAwait(false); var analyzerConfigDocumentInfos = await CreateDocumentInfosAsync(projectChecksums.AnalyzerConfigDocuments, cancellationToken).ConfigureAwait(false); return(ProjectInfo.Create( projectInfo.Id, projectInfo.Version, projectInfo.Name, projectInfo.AssemblyName, projectInfo.Language, projectInfo.FilePath, projectInfo.OutputFilePath, compilationOptions, parseOptions, documentInfos, projectReferences, metadataReferences, analyzerReferences, additionalDocumentInfos, projectInfo.IsSubmission) .WithOutputRefFilePath(projectInfo.OutputRefFilePath) .WithCompilationOutputFilePaths(projectInfo.CompilationOutputFilePaths) .WithHasAllInformation(projectInfo.HasAllInformation) .WithRunAnalyzers(projectInfo.RunAnalyzers) .WithDefaultNamespace(projectInfo.DefaultNamespace) .WithAnalyzerConfigDocuments(analyzerConfigDocumentInfos) .WithTelemetryId(projectInfo.TelemetryId)); }
private static async Task AppendAssetMapAsync(this Project project, Dictionary <Checksum, object> map, CancellationToken cancellationToken) { if (!RemoteSupportedLanguages.IsSupported(project.Language)) { return; } var projectChecksums = await project.State.GetStateChecksumsAsync(cancellationToken).ConfigureAwait(false); projectChecksums.Find(project.State, Flatten(projectChecksums), map, cancellationToken); foreach (var document in project.Documents.Concat(project.AdditionalDocuments)) { await document.AppendAssetMapAsync(map, cancellationToken).ConfigureAwait(false); } }
private async Task <SolutionStateChecksums> ComputeChecksumsAsync(CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.SolutionState_ComputeChecksumsAsync, FilePath, cancellationToken)) { // get states by id order to have deterministic checksum var projectChecksumTasks = ProjectIds.Select(id => ProjectStates[id]) .Where(s => RemoteSupportedLanguages.IsSupported(s.Language)) .Select(s => s.GetChecksumAsync(cancellationToken)); var serializer = new Serializer(_solutionServices.Workspace); var infoChecksum = serializer.CreateChecksum(SolutionInfo.Attributes, cancellationToken); var projectChecksums = await Task.WhenAll(projectChecksumTasks).ConfigureAwait(false); return(new SolutionStateChecksums(infoChecksum, new ProjectChecksumCollection(projectChecksums))); } }
public void Find( SolutionState state, HashSet <Checksum> searchingChecksumsLeft, Dictionary <Checksum, object> result, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // verify input Contract.ThrowIfFalse(state.TryGetStateChecksums(out var stateChecksum)); Contract.ThrowIfFalse(this == stateChecksum); if (searchingChecksumsLeft.Remove(Checksum)) { result[Checksum] = this; } if (searchingChecksumsLeft.Remove(Info)) { result[Info] = state.SolutionAttributes; } if (searchingChecksumsLeft.Remove(Projects.Checksum)) { result[Projects.Checksum] = Projects; } foreach (var kv in state.ProjectStates) { var projectState = kv.Value; // solution state checksum can't be created without project state checksums created first // check unsupported projects if (!projectState.TryGetStateChecksums(out var projectStateChecksums)) { Contract.ThrowIfTrue(RemoteSupportedLanguages.IsSupported(projectState.Language)); continue; } projectStateChecksums.Find(projectState, searchingChecksumsLeft, result, cancellationToken); if (searchingChecksumsLeft.Count == 0) { return; } } }
/// <param name="projectsToInclude">Cone of projects to compute a checksum for. Pass in <see langword="null"/> /// to get a checksum for the entire solution</param> private async Task <SolutionStateChecksums> ComputeChecksumsAsync( HashSet <ProjectId>?projectsToInclude, SerializableOptionSet options, CancellationToken cancellationToken) { try { using (Logger.LogBlock(FunctionId.SolutionState_ComputeChecksumsAsync, FilePath, cancellationToken)) { // get states by id order to have deterministic checksum. Limit to the requested set of projects // if applicable. var orderedProjectIds = ChecksumCache.GetOrCreate(ProjectIds, _ => ProjectIds.OrderBy(id => id.Id).ToImmutableArray()); var projectChecksumTasks = orderedProjectIds.Where(id => projectsToInclude == null || projectsToInclude.Contains(id)) .Select(id => ProjectStates[id]) .Where(s => RemoteSupportedLanguages.IsSupported(s.Language)) .Select(s => s.GetChecksumAsync(cancellationToken)) .ToArray(); var serializer = _solutionServices.Workspace.Services.GetRequiredService <ISerializerService>(); var attributesChecksum = serializer.CreateChecksum(SolutionAttributes, cancellationToken); var optionsChecksum = serializer.CreateChecksum(options, cancellationToken); var frozenSourceGeneratedDocumentIdentityChecksum = Checksum.Null; var frozenSourceGeneratedDocumentTextChecksum = Checksum.Null; if (FrozenSourceGeneratedDocumentState != null) { frozenSourceGeneratedDocumentIdentityChecksum = serializer.CreateChecksum(FrozenSourceGeneratedDocumentState.Identity, cancellationToken); frozenSourceGeneratedDocumentTextChecksum = (await FrozenSourceGeneratedDocumentState.GetStateChecksumsAsync(cancellationToken).ConfigureAwait(false)).Text; } var analyzerReferenceChecksums = ChecksumCache.GetOrCreate <ChecksumCollection>(AnalyzerReferences, _ => new ChecksumCollection(AnalyzerReferences.Select(r => serializer.CreateChecksum(r, cancellationToken)).ToArray())); var projectChecksums = await Task.WhenAll(projectChecksumTasks).ConfigureAwait(false); return(new SolutionStateChecksums(attributesChecksum, optionsChecksum, new ChecksumCollection(projectChecksums), analyzerReferenceChecksums, frozenSourceGeneratedDocumentIdentityChecksum, frozenSourceGeneratedDocumentTextChecksum)); } } catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e, cancellationToken)) { throw ExceptionUtilities.Unreachable; } }
private (ImmutableHashSet <string> languages, SortedDictionary <OptionKey, (OptionValueKind, object?)> values) GetLanguagesAndValuesToSerialize(bool includeValues) { var valuesBuilder = new SortedDictionary <OptionKey, (OptionValueKind, object?)>(OptionKeyComparer.Instance); var languages = ImmutableHashSet <string> .Empty; foreach (var(optionKey, value) in _serializableOptionValues) { Debug.Assert(ShouldSerialize(optionKey)); Debug.Assert(!optionKey.Option.IsPerLanguage || RemoteSupportedLanguages.IsSupported(optionKey.Language)); if (optionKey.Language != null) { languages = languages.Add(optionKey.Language); } if (includeValues) { OptionValueKind kind; switch (value) { case ICodeStyleOption: if (optionKey.Option.Type.GenericTypeArguments.Length != 1) { continue; } kind = OptionValueKind.CodeStyleOption; break; case NamingStylePreferences: kind = OptionValueKind.NamingStylePreferences; break; default: kind = value != null && value.GetType().IsEnum ? OptionValueKind.Enum : OptionValueKind.Object; break; } valuesBuilder.Add(optionKey, (kind, value)); } } return(languages, valuesBuilder); }
private async Task <SolutionStateChecksums> ComputeChecksumsAsync(CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.SolutionState_ComputeChecksumsAsync, FilePath, cancellationToken)) { // get states by id order to have deterministic checksum var orderedProjectIds = ChecksumCache.GetOrCreate(ProjectIds, _ => ProjectIds.OrderBy(id => id.Id).ToImmutableArray()); var projectChecksumTasks = orderedProjectIds.Select(id => ProjectStates[id]) .Where(s => RemoteSupportedLanguages.IsSupported(s.Language)) .Select(s => s.GetChecksumAsync(cancellationToken)); var serializer = _solutionServices.Workspace.Services.GetService <ISerializerService>(); var infoChecksum = serializer.CreateChecksum(SolutionAttributes, cancellationToken); var optionsChecksum = serializer.CreateChecksum(Options, cancellationToken); var projectChecksums = await Task.WhenAll(projectChecksumTasks).ConfigureAwait(false); return(new SolutionStateChecksums(infoChecksum, optionsChecksum, new ProjectChecksumCollection(projectChecksums))); } }
private static void AppendAssetMap(Project project, Dictionary <Checksum, object> map) { if (!project.State.TryGetStateChecksums(out var projectChecksums)) { Debug.Assert(!RemoteSupportedLanguages.IsSupported(project.Language)); return; } projectChecksums.Find(project.State, Flatten(projectChecksums), map, CancellationToken.None); foreach (var document in project.Documents) { AppendAssetMap(document, map); } foreach (var document in project.AdditionalDocuments) { AppendAssetMap(document, map); } }
private static async Task <(bool, ImmutableArray <SymbolAndProjectId>)> TryFindAllDeclarationsWithNormalQueryInRemoteProcessAsync( Project project, SearchQuery query, SymbolFilter criteria, CancellationToken cancellationToken) { if (!RemoteSupportedLanguages.IsSupported(project.Language)) { return(false, ImmutableArray <SymbolAndProjectId> .Empty); } var result = await project.Solution.TryRunCodeAnalysisRemoteAsync <IList <SerializableSymbolAndProjectId> >( nameof(IRemoteSymbolFinder.FindAllDeclarationsWithNormalQueryAsync), new object[] { project.Id, query.Name, query.Kind, criteria }, cancellationToken).ConfigureAwait(false); if (result == null) { return(false, ImmutableArray <SymbolAndProjectId> .Empty); } var rehydrated = await RehydrateAsync( project.Solution, result, cancellationToken).ConfigureAwait(false); return(true, rehydrated); }
private static async Task <(bool succeeded, ImmutableArray <SymbolAndProjectId> results)> TryFindSourceDeclarationsWithPatternInRemoteProcessAsync( Project project, string pattern, SymbolFilter criteria, CancellationToken cancellationToken) { if (!RemoteSupportedLanguages.IsSupported(project.Language)) { return(false, ImmutableArray <SymbolAndProjectId> .Empty); } var result = await project.Solution.TryRunCodeAnalysisRemoteAsync <IList <SerializableSymbolAndProjectId> >( nameof(IRemoteSymbolFinder.FindProjectSourceDeclarationsWithPatternAsync), new object[] { project.Id, pattern, criteria }, cancellationToken).ConfigureAwait(false); if (result == null) { return(false, ImmutableArray <SymbolAndProjectId> .Empty); } var rehydrated = await RehydrateAsync( project.Solution, result, cancellationToken).ConfigureAwait(false); return(true, rehydrated); }
private static async Task <(bool, ImmutableArray <SymbolAndProjectId>)> TryFindSourceDeclarationsWithNormalQueryInRemoteProcessAsync( Project project, string name, bool ignoreCase, SymbolFilter criteria, CancellationToken cancellationToken) { if (!RemoteSupportedLanguages.IsSupported(project.Language)) { return(false, ImmutableArray <SymbolAndProjectId> .Empty); } var result = await project.Solution.TryRunCodeAnalysisRemoteAsync <ImmutableArray <SerializableSymbolAndProjectId> >( RemoteFeatureOptions.SymbolFinderEnabled, nameof(IRemoteSymbolFinder.FindProjectSourceDeclarationsWithNormalQueryAsync), new object[] { project.Id, name, ignoreCase, criteria }, cancellationToken).ConfigureAwait(false); if (result.IsDefault) { return(false, ImmutableArray <SymbolAndProjectId> .Empty); } var rehydrated = await RehydrateAsync( project.Solution, result, cancellationToken).ConfigureAwait(false); return(true, rehydrated); }
public void Serialize(ObjectWriter writer, CancellationToken cancellationToken) { // We serialize the following contents from this option set: // 1. Languages // 2. Prefetched serializable option key-value pairs // 3. Changed option keys. // NOTE: keep the serialization in sync with Deserialize method below. // NOTE: keep this in sync with GetDebugString above. cancellationToken.ThrowIfCancellationRequested(); var(languages, values) = this.GetLanguagesAndValuesToSerialize(includeValues: true); writer.WriteInt32(languages.Count); foreach (var language in languages.Order()) { Debug.Assert(RemoteSupportedLanguages.IsSupported(language)); writer.WriteString(language); } writer.WriteInt32(values.Count); foreach (var(optionKey, (kind, value)) in values) { SerializeOptionKey(optionKey); writer.WriteInt32((int)kind); if (kind == OptionValueKind.Enum) { RoslynDebug.Assert(value != null); writer.WriteInt32((int)value); } else if (kind is OptionValueKind.CodeStyleOption or OptionValueKind.NamingStylePreferences) { RoslynDebug.Assert(value != null); ((IObjectWritable)value).WriteTo(writer); }
private bool ShouldSerialize(OptionKey optionKey) => _serializableOptionValues.ContainsKey(optionKey) && (!optionKey.Option.IsPerLanguage || RemoteSupportedLanguages.IsSupported(optionKey.Language));
/// <param name="projectsToInclude">Cone of projects to compute a checksum for. Pass in <see langword="null"/> /// to get a checksum for the entire solution</param> private async Task <SolutionStateChecksums> ComputeChecksumsAsync( HashSet <ProjectId>?projectsToInclude, SerializableOptionSet options, CancellationToken cancellationToken) { try { using (Logger.LogBlock(FunctionId.SolutionState_ComputeChecksumsAsync, FilePath, cancellationToken)) { // get states by id order to have deterministic checksum. Limit expensive computation to the // requested set of projects if applicable. var orderedProjectIds = ChecksumCache.GetOrCreate(ProjectIds, _ => ProjectIds.OrderBy(id => id.Id).ToImmutableArray()); var projectChecksumTasks = orderedProjectIds .Select(id => (state: ProjectStates[id], mustCompute: projectsToInclude == null || projectsToInclude.Contains(id))) .Where(t => RemoteSupportedLanguages.IsSupported(t.state.Language)) .Select(async t => { // if it's a project that's specifically in the sync'ed cone, include this checksum so that // this project definitely syncs over. if (t.mustCompute) { return(await t.state.GetChecksumAsync(cancellationToken).ConfigureAwait(false)); } // If it's a project that is not in the cone, still try to get the latest checksum for it if // we have it. That way we don't send over a checksum *without* that project, causing the // OOP side to throw that project away (along with all the compilation info stored with it). if (t.state.TryGetStateChecksums(out var stateChecksums)) { return(stateChecksums.Checksum); } // We have never computed the checksum for this project. Don't send anything for it. return(null); }) .ToArray(); var serializer = _solutionServices.Workspace.Services.GetRequiredService <ISerializerService>(); var attributesChecksum = serializer.CreateChecksum(SolutionAttributes, cancellationToken); var optionsChecksum = serializer.CreateChecksum(options, cancellationToken); var frozenSourceGeneratedDocumentIdentityChecksum = Checksum.Null; var frozenSourceGeneratedDocumentTextChecksum = Checksum.Null; if (FrozenSourceGeneratedDocumentState != null) { frozenSourceGeneratedDocumentIdentityChecksum = serializer.CreateChecksum(FrozenSourceGeneratedDocumentState.Identity, cancellationToken); frozenSourceGeneratedDocumentTextChecksum = (await FrozenSourceGeneratedDocumentState.GetStateChecksumsAsync(cancellationToken).ConfigureAwait(false)).Text; } var analyzerReferenceChecksums = ChecksumCache.GetOrCreate <ChecksumCollection>(AnalyzerReferences, _ => new ChecksumCollection(AnalyzerReferences.Select(r => serializer.CreateChecksum(r, cancellationToken)).ToArray())); var projectChecksums = await Task.WhenAll(projectChecksumTasks).ConfigureAwait(false); return(new SolutionStateChecksums( attributesChecksum, optionsChecksum, new ChecksumCollection(projectChecksums.WhereNotNull().ToArray()), analyzerReferenceChecksums, frozenSourceGeneratedDocumentIdentityChecksum, frozenSourceGeneratedDocumentTextChecksum)); } } catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e, cancellationToken)) { throw ExceptionUtilities.Unreachable; } }
public async Task FindAsync( SolutionState state, HashSet <Checksum> searchingChecksumsLeft, Dictionary <Checksum, object> result, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // verify input Contract.ThrowIfFalse(state.TryGetStateChecksums(out var stateChecksum)); Contract.ThrowIfFalse(this == stateChecksum); if (searchingChecksumsLeft.Remove(Checksum)) { result[Checksum] = this; } if (searchingChecksumsLeft.Remove(Attributes)) { result[Attributes] = state.SolutionAttributes; } if (searchingChecksumsLeft.Remove(Options)) { result[Options] = state.Options; } if (searchingChecksumsLeft.Remove(FrozenSourceGeneratedDocumentIdentity)) { Contract.ThrowIfNull(state.FrozenSourceGeneratedDocumentState, "We should not have had a FrozenSourceGeneratedDocumentIdentity checksum if we didn't have a text in the first place."); result[FrozenSourceGeneratedDocumentIdentity] = state.FrozenSourceGeneratedDocumentState.Identity; } if (searchingChecksumsLeft.Remove(FrozenSourceGeneratedDocumentText)) { Contract.ThrowIfNull(state.FrozenSourceGeneratedDocumentState, "We should not have had a FrozenSourceGeneratedDocumentState checksum if we didn't have a text in the first place."); result[FrozenSourceGeneratedDocumentText] = await SerializableSourceText.FromTextDocumentStateAsync(state.FrozenSourceGeneratedDocumentState, cancellationToken).ConfigureAwait(false); } if (searchingChecksumsLeft.Remove(Projects.Checksum)) { result[Projects.Checksum] = Projects; } if (searchingChecksumsLeft.Remove(AnalyzerReferences.Checksum)) { result[AnalyzerReferences.Checksum] = AnalyzerReferences; } foreach (var(_, projectState) in state.ProjectStates) { // solution state checksum can't be created without project state checksums created first // check unsupported projects if (!projectState.TryGetStateChecksums(out var projectStateChecksums)) { Contract.ThrowIfTrue(RemoteSupportedLanguages.IsSupported(projectState.Language)); continue; } await projectStateChecksums.FindAsync(projectState, searchingChecksumsLeft, result, cancellationToken).ConfigureAwait(false); if (searchingChecksumsLeft.Count == 0) { break; } } ChecksumCollection.Find(state.AnalyzerReferences, AnalyzerReferences, searchingChecksumsLeft, result, cancellationToken); }
public string GetDebugString() { // NOTE: keep this in sync with Serialize below. using var _ = PooledStringBuilder.GetInstance(out var sb); var(languages, values) = this.GetLanguagesAndValuesToSerialize(includeValues: true); sb.AppendLine($"languages count: {languages.Count}"); foreach (var language in languages.Order()) { Debug.Assert(RemoteSupportedLanguages.IsSupported(language)); sb.AppendLine(language); } sb.AppendLine(); sb.AppendLine($"values count: {values.Count}"); foreach (var(optionKey, (kind, value)) in values) { SerializeOptionKey(optionKey); sb.Append($"{kind}: "); if (kind == OptionValueKind.Enum) { RoslynDebug.Assert(value != null); sb.AppendLine(value.ToString()); } else if (kind is OptionValueKind.CodeStyleOption) { RoslynDebug.Assert(value != null); var codeStyleOption = (ICodeStyleOption)value; sb.AppendLine(codeStyleOption.ToXElement().ToString()); } else if (kind is OptionValueKind.NamingStylePreferences) { RoslynDebug.Assert(value != null); var namingStylePreferences = (NamingStylePreferences)value; sb.AppendLine(namingStylePreferences.CreateXElement().ToString()); } else { sb.AppendLine($"{value}"); } sb.AppendLine(); } sb.AppendLine(); sb.AppendLine($"changed options count: {_changedOptionKeysSerializable.Count}"); foreach (var changedKey in _changedOptionKeysSerializable.OrderBy(OptionKeyComparer.Instance)) { SerializeOptionKey(changedKey); } return(sb.ToString()); void SerializeOptionKey(OptionKey optionKey) { Debug.Assert(ShouldSerialize(optionKey)); sb.AppendLine($"{optionKey.Option.Name} {optionKey.Option.Feature} {optionKey.Option.IsPerLanguage} {optionKey.Language}"); } }