Example #1
0
        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);
        }
Example #2
0
        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());
                    }
                }
        }
Example #3
0
        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);
            }
        }
Example #6
0
        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());
            }
Example #10
0
            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);
            }