public void WorkspaceAnalyzer_Serailization_Desktop_Test() { var hostServices = MefHostServices.Create( MefHostServices.DefaultAssemblies.Add(typeof(Host.TemporaryStorageServiceFactory.TemporaryStorageService).Assembly)); using var tempRoot = new TempRoot(); using var workspace = new AdhocWorkspace(hostServices); var reference = CreateShadowCopiedAnalyzerReference(tempRoot); var assetBuilder = new CustomAssetBuilder(workspace); var asset = assetBuilder.Build(reference, CancellationToken.None); // verify checksum from custom asset builder uses different checksum than regular one var service = workspace.Services.GetService <IReferenceSerializationService>(); var expectedChecksum = Checksum.Create( WellKnownSynchronizationKind.AnalyzerReference, service.CreateChecksum(reference, usePathFromAssembly: false, CancellationToken.None)); Assert.Equal(expectedChecksum, asset.Checksum); // verify usePathFromAssembly return different checksum for same reference var fromFilePath = service.CreateChecksum(reference, usePathFromAssembly: false, CancellationToken.None); var fromAssembly = service.CreateChecksum(reference, usePathFromAssembly: true, CancellationToken.None); Assert.NotEqual(fromFilePath, fromAssembly); }
private static async Task VerifyOptionSetsAsync(Workspace workspace, string language) { var assetBuilder = new CustomAssetBuilder(workspace); var serializer = new Serializer(workspace); var asset = assetBuilder.Build(workspace.Options, language, CancellationToken.None); using (var stream = SerializableBytes.CreateWritableStream()) using (var writer = new ObjectWriter(stream)) { await asset.WriteObjectToAsync(writer, CancellationToken.None).ConfigureAwait(false); stream.Position = 0; using (var reader = ObjectReader.TryGetReader(stream)) { var recovered = serializer.Deserialize <OptionSet>(asset.Kind, reader, CancellationToken.None); var assetFromStorage = assetBuilder.Build(recovered, language, CancellationToken.None); Assert.Equal(asset.Checksum, assetFromStorage.Checksum); // option should be exactly same Assert.Equal(0, recovered.GetChangedOptions(workspace.Options).Count()); } } }
public async Task TestHostAnalyzers() { var code = @"class Test { void Method() { var t = new Test(); } }"; using (var workspace = CreateWorkspace(LanguageNames.CSharp, code)) { var analyzerType = typeof(CSharpUseExplicitTypeDiagnosticAnalyzer); var analyzerReference = new AnalyzerFileReference(analyzerType.Assembly.Location, new TestAnalyzerAssemblyLoader()); // add host analyzer as global assets var snapshotService = workspace.Services.GetService <IRemotableDataService>(); var assetBuilder = new CustomAssetBuilder(workspace); var asset = assetBuilder.Build(analyzerReference, CancellationToken.None); snapshotService.AddGlobalAsset(analyzerReference, asset, CancellationToken.None); var client = await RemoteHostClient.TryGetClientAsync(workspace, CancellationToken.None).ConfigureAwait(false); Assert.True(await client.TryRunRemoteAsync( WellKnownRemoteHostServices.RemoteHostService, nameof(IRemoteHostService.SynchronizeGlobalAssetsAsync), new[] { new Checksum[] { asset.Checksum } }, workspace.CurrentSolution, callbackTarget: null, CancellationToken.None)); // set option workspace.TryApplyChanges(workspace.CurrentSolution.WithOptions(workspace.Options .WithChangedOption(CSharpCodeStyleOptions.VarWhenTypeIsApparent, new CodeStyleOption <bool>(false, NotificationOption.Suggestion)))); // run analysis var project = workspace.CurrentSolution.Projects.First(); var runner = CreateAnalyzerRunner(workspace); var compilationWithAnalyzers = (await project.GetCompilationAsync()).WithAnalyzers( analyzerReference.GetAnalyzers(project.Language).Where(a => a.GetType() == analyzerType).ToImmutableArray(), new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution)); // no result for open file only analyzer unless forced var result = await runner.AnalyzeAsync(compilationWithAnalyzers, project, forcedAnalysis : false, cancellationToken : CancellationToken.None); Assert.Empty(result.AnalysisResult); result = await runner.AnalyzeAsync(compilationWithAnalyzers, project, forcedAnalysis : true, cancellationToken : CancellationToken.None); var analyzerResult = result.AnalysisResult[compilationWithAnalyzers.Analyzers[0]]; // check result var diagnostics = analyzerResult.GetDocumentDiagnostics(analyzerResult.DocumentIds.First(), AnalysisKind.Semantic); Assert.Equal(IDEDiagnosticIds.UseExplicitTypeDiagnosticId, diagnostics[0].Id); } }
private void AddGlobalAssets(CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.RemoteHostClientService_AddGlobalAssetsAsync, cancellationToken)) { var snapshotService = _workspace.Services.GetService <ISolutionSynchronizationService>(); var assetBuilder = new CustomAssetBuilder(_workspace); foreach (var reference in _analyzerService.GetHostAnalyzerReferences()) { var asset = assetBuilder.Build(reference, cancellationToken); snapshotService.AddGlobalAsset(reference, asset, cancellationToken); } } }
public async Task TestDuplicatedAnalyzers() { var code = @"class Test { void Method() { var t = new Test(); } }"; using (var workspace = CreateWorkspace(LanguageNames.CSharp, code)) { var analyzerType = typeof(DuplicateAnalyzer); var analyzerReference = new AnalyzerFileReference(analyzerType.Assembly.Location, new TestAnalyzerAssemblyLoader()); // add host analyzer as global assets var snapshotService = workspace.Services.GetService <IRemotableDataService>(); var assetBuilder = new CustomAssetBuilder(workspace); var asset = assetBuilder.Build(analyzerReference, CancellationToken.None); snapshotService.AddGlobalAsset(analyzerReference, asset, CancellationToken.None); var client = await RemoteHostClient.TryGetClientAsync(workspace, CancellationToken.None).ConfigureAwait(false); Assert.True(await client.TryRunRemoteAsync( WellKnownRemoteHostServices.RemoteHostService, nameof(IRemoteHostService.SynchronizeGlobalAssetsAsync), new[] { new Checksum[] { asset.Checksum } }, workspace.CurrentSolution, callbackTarget: null, cancellationToken: CancellationToken.None)); // run analysis var project = workspace.CurrentSolution.Projects.First().AddAnalyzerReference(analyzerReference); var executor = new DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner(owner: null, hostDiagnosticUpdateSource: new MyUpdateSource(workspace)); var analyzerDriver = (await project.GetCompilationAsync()).WithAnalyzers( analyzerReference.GetAnalyzers(project.Language).Where(a => a.GetType() == analyzerType).ToImmutableArray(), new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution)); var result = await executor.AnalyzeAsync(analyzerDriver, project, forcedAnalysis : false, cancellationToken : CancellationToken.None); var analyzerResult = result.AnalysisResult[analyzerDriver.Analyzers[0]]; // check result var diagnostics = analyzerResult.GetDocumentDiagnostics(analyzerResult.DocumentIds.First(), AnalysisKind.Syntax); Assert.Equal("test", diagnostics[0].Id); } }
public async Task TestUnresolvedAnalyzerReference() { var workspace = new AdhocWorkspace(); var project = workspace.CurrentSolution.AddProject("empty", "empty", LanguageNames.CSharp); var mockFileChangeService = new Mock <IVsFileChangeEx>(); using (var analyzer = new VisualStudioAnalyzer( @"PathToAnalyzer", fileChangeService: mockFileChangeService.Object, hostDiagnosticUpdateSource: null, projectId: project.Id, workspace: workspace, loader: null, language: project.Language)) { var analyzerReference = analyzer.GetReference(); project = project.WithAnalyzerReferences(new AnalyzerReference[] { analyzerReference, }); var checksum = await project.State.GetChecksumAsync(CancellationToken.None).ConfigureAwait(false); Assert.NotNull(checksum); var assetBuilder = new CustomAssetBuilder(workspace); var serializer = new Serializer(workspace); var asset = assetBuilder.Build(analyzerReference, CancellationToken.None); using (var stream = SerializableBytes.CreateWritableStream()) using (var writer = new ObjectWriter(stream)) { await asset.WriteObjectToAsync(writer, CancellationToken.None).ConfigureAwait(false); stream.Position = 0; using (var reader = ObjectReader.TryGetReader(stream)) { var recovered = serializer.Deserialize <AnalyzerReference>(asset.Kind, reader, CancellationToken.None); var assetFromStorage = assetBuilder.Build(recovered, CancellationToken.None); Assert.Equal(asset.Checksum, assetFromStorage.Checksum); // This won't round trip, but we should get an UnresolvedAnalyzerReference, with the same path Assert.Equal(analyzerReference.FullPath, recovered.FullPath); } } } }
public async Task TestHostAnalyzers() { var code = @"class Test { void Method() { var t = new Test(); } }"; using (var workspace = CreateWorkspace(LanguageNames.CSharp, code)) { var analyzerType = typeof(CSharpUseExplicitTypeDiagnosticAnalyzer); var analyzerReference = new AnalyzerFileReference(analyzerType.Assembly.Location, new TestAnalyzerAssemblyLoader()); // add host analyzer as global assets var snapshotService = workspace.Services.GetService <IRemotableDataService>(); var assetBuilder = new CustomAssetBuilder(workspace); var asset = assetBuilder.Build(analyzerReference, CancellationToken.None); snapshotService.AddGlobalAsset(analyzerReference, asset, CancellationToken.None); var client = await workspace.Services.GetService <IRemoteHostClientService>().TryGetRemoteHostClientAsync(CancellationToken.None); await client.TryRunRemoteAsync( WellKnownRemoteHostServices.RemoteHostService, workspace.CurrentSolution, nameof(IRemoteHostService.SynchronizeGlobalAssetsAsync), (object)(new Checksum[] { asset.Checksum }), CancellationToken.None); // set option workspace.Options = workspace.Options.WithChangedOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, new CodeStyleOption <bool>(false, NotificationOption.Suggestion)); // run analysis var project = workspace.CurrentSolution.Projects.First(); var executor = new DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner(owner: null, hostDiagnosticUpdateSource: new MyUpdateSource(workspace)); var analyzerDriver = (await project.GetCompilationAsync()).WithAnalyzers( analyzerReference.GetAnalyzers(project.Language).Where(a => a.GetType() == analyzerType).ToImmutableArray(), new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution.Options, project.Solution)); var result = await executor.AnalyzeAsync(analyzerDriver, project, forcedAnalysis : false, cancellationToken : CancellationToken.None); var analyzerResult = result.AnalysisResult[analyzerDriver.Analyzers[0]]; // check result var diagnostics = analyzerResult.SemanticLocals[analyzerResult.DocumentIds.First()]; Assert.Equal(IDEDiagnosticIds.UseExplicitTypeDiagnosticId, diagnostics[0].Id); } }
public async Task TestHostAnalyzers() { var code = @"class Test { void Method() { var t = new Test(); } }"; using (var workspace = CreateWorkspace(LanguageNames.CSharp, code)) { var analyzerType = typeof(CSharpUseExplicitTypeDiagnosticAnalyzer); var analyzerReference = new AnalyzerFileReference(analyzerType.Assembly.Location, new TestAnalyzerAssemblyLoader()); var mockAnalyzerService = CreateMockDiagnosticAnalyzerService(new[] { analyzerReference }); // add host analyzer as global assets var snapshotService = workspace.Services.GetService <ISolutionSynchronizationService>(); var assetBuilder = new CustomAssetBuilder(workspace); foreach (var reference in mockAnalyzerService.GetHostAnalyzerReferences()) { var asset = assetBuilder.Build(reference, CancellationToken.None); snapshotService.AddGlobalAsset(reference, asset, CancellationToken.None); } // set option workspace.Options = workspace.Options.WithChangedOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, new CodeStyleOption <bool>(false, NotificationOption.Suggestion)); // run analysis var project = workspace.CurrentSolution.Projects.First(); var executor = (ICodeAnalysisDiagnosticAnalyzerExecutor) new DiagnosticAnalyzerExecutor(mockAnalyzerService, new MyUpdateSource(workspace)).CreateService(workspace.Services); var analyzerDriver = (await project.GetCompilationAsync()).WithAnalyzers(analyzerReference.GetAnalyzers(project.Language).Where(a => a.GetType() == analyzerType).ToImmutableArray()); var result = await executor.AnalyzeAsync(analyzerDriver, project, CancellationToken.None); var analyzerResult = result.AnalysisResult[analyzerDriver.Analyzers[0]]; // check result var diagnostics = analyzerResult.SemanticLocals[analyzerResult.DocumentIds.First()]; Assert.Equal(IDEDiagnosticIds.UseExplicitTypeDiagnosticId, diagnostics[0].Id); } }
private Checksum[] AddGlobalAssets(CancellationToken cancellationToken) { var builder = ArrayBuilder <Checksum> .GetInstance(); using (Logger.LogBlock(FunctionId.RemoteHostClientService_AddGlobalAssetsAsync, cancellationToken)) { var snapshotService = _workspace.Services.GetService <ISolutionSynchronizationService>(); var assetBuilder = new CustomAssetBuilder(_workspace); foreach (var reference in _analyzerService.GetHostAnalyzerReferences()) { var asset = assetBuilder.Build(reference, cancellationToken); builder.Add(asset.Checksum); snapshotService.AddGlobalAsset(reference, asset, cancellationToken); } } return(builder.ToArrayAndFree()); }
private CustomAsset GetOptionsAsset(Solution solution, string language, CancellationToken cancellationToken) { // TODO: we need better way to deal with options. optionSet itself is green node but // it is not part of snapshot and can't save option to solution since we can't use language // specific option without loading related language specific dlls var options = solution.Options; // we have cached options if (_lastOptionSetPerLanguage.TryGetValue(language, out var value) && value.Item1 == options) { return(value.Item2); } // otherwise, we need to build one. var assetBuilder = new CustomAssetBuilder(solution); var asset = assetBuilder.Build(options, language, cancellationToken); _lastOptionSetPerLanguage[language] = ValueTuple.Create(options, asset); return(asset); }