public async Task UpdaterService()
        {
            var workspace = new AdhocWorkspace(TestHostServices.CreateHostServices());
            workspace.Options = workspace.Options.WithChangedOption(RemoteHostOptions.SolutionChecksumMonitorBackOffTimeSpanInMS, 1);

            var analyzerReference = new AnalyzerFileReference(typeof(object).Assembly.Location, new NullAssemblyAnalyzerLoader());
            var service = CreateRemoteHostClientService(workspace, SpecializedCollections.SingletonEnumerable<AnalyzerReference>(analyzerReference));

            service.Enable();

            // make sure client is ready
            var client = await service.GetRemoteHostClientAsync(CancellationToken.None);

            // add solution
            workspace.AddSolution(SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Default));

            // TODO: use waiter to make sure workspace events and updater is ready.
            //       this delay is temporary until I set all .Next unit test hardness to setup correctly
            await Task.Delay(TimeSpan.FromSeconds(1));

            // checksum should already exist
            SolutionStateChecksums checksums;
            Assert.True(workspace.CurrentSolution.State.TryGetStateChecksums(out checksums));

            service.Disable();
        }
 protected override string GetAnalyzerAssemblyPath(AnalyzerFileReference reference)
 {
     // TODO: find out a way to get analyzer assembly location
     //       without actually loading analyzer in memory
     var assembly = reference.GetAssembly();
     return assembly?.Location;
 }
        public async Task UpdaterService()
        {
            var workspace = new AdhocWorkspace(TestHostServices.CreateHostServices());
            workspace.Options = workspace.Options.WithChangedOption(RemoteHostOptions.SolutionChecksumMonitorBackOffTimeSpanInMS, 1);

            var analyzerReference = new AnalyzerFileReference(typeof(object).Assembly.Location, new NullAssemblyAnalyzerLoader());
            var service = CreateRemoteHostClientService(workspace, SpecializedCollections.SingletonEnumerable<AnalyzerReference>(analyzerReference));

            service.Enable();

            // make sure client is ready
            var client = await service.GetRemoteHostClientAsync(CancellationToken.None);

            // add solution
            workspace.AddSolution(SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Default));

            // TODO: use waiter to make sure workspace events and updater is ready.
            //       this delay is temporary until I set all .Next unit test hardness to setup correctly
            await Task.Delay(TimeSpan.FromSeconds(1));

            var checksumService = workspace.Services.GetService<ISolutionChecksumService>();

            Checksum checksum;
            using (var scope = await checksumService.CreateChecksumAsync(workspace.CurrentSolution, CancellationToken.None))
            {
                // create solution checksum and hold onto the checksum and let it go
                checksum = scope.SolutionChecksum.Checksum;
            }

            // there should be one held in memory by solution checksum updator
            var solutionObject = checksumService.GetChecksumObject(checksum, CancellationToken.None);
            Assert.Equal(solutionObject.Checksum, checksum);

            service.Disable();
        }
        public async Task UpdaterService()
        {
            var exportProvider = TestHostServices.CreateMinimalExportProvider();

            var workspace = new AdhocWorkspace(TestHostServices.CreateHostServices(exportProvider));
            workspace.Options = workspace.Options.WithChangedOption(RemoteHostOptions.SolutionChecksumMonitorBackOffTimeSpanInMS, 1);

            var listener = new Listener();
            var analyzerReference = new AnalyzerFileReference(typeof(object).Assembly.Location, new NullAssemblyAnalyzerLoader());

            var service = CreateRemoteHostClientService(workspace, SpecializedCollections.SingletonEnumerable<AnalyzerReference>(analyzerReference), listener);

            service.Enable();

            // make sure client is ready
            var client = await service.GetRemoteHostClientAsync(CancellationToken.None);

            // add solution
            workspace.AddSolution(SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Default));

            var listeners = exportProvider.GetExports<IAsynchronousOperationListener, FeatureMetadata>();
            var workspaceListener = listeners.First(l => l.Metadata.FeatureName == FeatureAttribute.Workspace).Value as IAsynchronousOperationWaiter;

            // wait for listener
            await workspaceListener.CreateWaitTask();
            await listener.CreateWaitTask();

            // checksum should already exist
            SolutionStateChecksums checksums;
            Assert.True(workspace.CurrentSolution.State.TryGetStateChecksums(out checksums));

            service.Disable();
        }
    public void BeforeCompile(BeforeCompileContext context)
    {
        string analyzerAssemblyPath = Path.Combine(context.ProjectContext.ProjectDirectory, @"../../lib/DotNetDoodle.Analyzers.dll");
        ImmutableArray<DiagnosticAnalyzer> diagnosticAnalyzers = new AnalyzerFileReference(analyzerAssemblyPath, FromFileLoader.Instance).GetAnalyzers(LanguageNames.CSharp);
        var compilation = context.Compilation.WithAnalyzers(diagnosticAnalyzers);
        ImmutableArray<Diagnostic> diagsnostics = compilation.GetAnalyzerDiagnosticsAsync().Result;

        foreach (var diagsnostic in diagsnostics)
        {
            context.Diagnostics.Add(diagsnostic);
        }
    }
        public void AssemblyLoading()
        {
            StringBuilder sb = new StringBuilder();
            var directory = Temp.CreateDirectory();

            EventHandler<AnalyzerAssemblyLoadEventArgs> handler = (e, args) =>
            {
                var relativePath = args.Path.Substring(directory.Path.Length);
                sb.AppendFormat("Assembly {0} loaded from {1}", args.LoadedAssembly.FullName, relativePath);
                sb.AppendLine();
            };

            AnalyzerFileReference.AssemblyLoad += handler;

            var alphaDll = directory.CreateFile("Alpha.dll").WriteAllBytes(TestResources.AssemblyLoadTests.AssemblyLoadTests.Alpha);
            var betaDll = directory.CreateFile("Beta.dll").WriteAllBytes(TestResources.AssemblyLoadTests.AssemblyLoadTests.Beta);
            var gammaDll = directory.CreateFile("Gamma.dll").WriteAllBytes(TestResources.AssemblyLoadTests.AssemblyLoadTests.Gamma);
            var deltaDll = directory.CreateFile("Delta.dll").WriteAllBytes(TestResources.AssemblyLoadTests.AssemblyLoadTests.Delta);

            AnalyzerFileReference alphaReference = new AnalyzerFileReference(alphaDll.Path);
            Assembly alpha = alphaReference.GetAssembly();
            File.Delete(alphaDll.Path);

            var a = alpha.CreateInstance("Alpha.A");
            a.GetType().GetMethod("Write").Invoke(a, new object[] { sb, "Test A" });

            File.Delete(gammaDll.Path);
            File.Delete(deltaDll.Path);

            AnalyzerFileReference betaReference = new AnalyzerFileReference(betaDll.Path);
            Assembly beta = betaReference.GetAssembly();
            var b = beta.CreateInstance("Beta.B");
            b.GetType().GetMethod("Write").Invoke(b, new object[] { sb, "Test B" });

            var expected = @"Assembly Alpha, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null loaded from \Alpha.dll
Assembly Gamma, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null loaded from \Gamma.dll
Assembly Delta, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null loaded from \Delta.dll
Delta: Gamma: Alpha: Test A
Assembly Beta, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null loaded from \Beta.dll
Delta: Gamma: Beta: Test B
";

            var actual = sb.ToString();

            Assert.Equal(expected, actual);

            AnalyzerFileReference.AssemblyLoad -= handler;
        }
        public async Task GlobalAssets()
        {
            var workspace = new AdhocWorkspace(TestHostServices.CreateHostServices());

            var analyzerReference = new AnalyzerFileReference(typeof(object).Assembly.Location, new NullAssemblyAnalyzerLoader());
            var service = CreateRemoteHostClientService(workspace, SpecializedCollections.SingletonEnumerable<AnalyzerReference>(analyzerReference));

            service.Enable();

            // make sure client is ready
            var client = await service.GetRemoteHostClientAsync(CancellationToken.None);

            var checksumService = workspace.Services.GetService<ISolutionSynchronizationService>();
            var asset = checksumService.GetGlobalAsset(analyzerReference, CancellationToken.None);
            Assert.NotNull(asset);

            service.Disable();

            var noAsset = checksumService.GetGlobalAsset(analyzerReference, CancellationToken.None);
            Assert.Null(noAsset);
        }
        private static ImmutableArray <DiagnosticAnalyzer> CreateLanguageSpecificAnalyzers(string language, AnalyzerFileReference reference)
        {
            // Get all analyzers in the assembly for the given language.
            var builder = ImmutableArray.CreateBuilder <DiagnosticAnalyzer>();

            reference.AddAnalyzers(builder, language);
            return(builder.ToImmutable());
        }
 private string TryGetAnalyzerAssemblyPath(AnalyzerFileReference file)
 {
     try
     {
         return GetAnalyzerAssemblyPath(file);
     }
     catch
     {
         // we can't load the assembly analyzer file reference is pointing to.
         // rather than crashing, handle it gracefully
         return null;
     }
 }
示例#10
0
        internal static ImmutableArray<IDiagnosticAnalyzer> GetOrCreateAnalyzersFromFile(AnalyzerFileReference analyzerReference)
        {
            string fullPath = analyzerReference.FullPath;
            Debug.Assert(PathUtilities.IsAbsolute(fullPath));

            lock (Guard)
            {
                // may throw:
                FileKey key = FileKey.Create(fullPath);

                CachedAnalyzers cachedAnalyzers;
                if (analyzersFromFiles.TryGetValue(key, out cachedAnalyzers) && cachedAnalyzers.Analyzers.IsAlive)
                {
                    return (ImmutableArray<IDiagnosticAnalyzer>)cachedAnalyzers.Analyzers.Target;
                }

                // get all analyzers in the assembly:
                var builder = ImmutableArray.CreateBuilder<IDiagnosticAnalyzer>();
                analyzerReference.AddAnalyzers(builder, null, null);
                var analyzers = builder.ToImmutable();

                // refresh the timestamp (the file may have changed just before we memory-mapped it):
                key = FileKey.Create(fullPath);

                analyzersFromFiles[key] = new CachedAnalyzers(analyzers);
                analyzerAssemblyKeys.Add(key);
                EnableCompactTimer();

                return analyzers;
            }
        }
示例#11
0
        private static ImmutableArray<AnalyzerReference> CreateAnalyzerReferencesFromPackages(
            IEnumerable<HostDiagnosticAnalyzerPackage> analyzerPackages,
            HostAnalyzerReferenceDiagnosticReporter reporter)
        {
            if (analyzerPackages == null || analyzerPackages.IsEmpty())
            {
                return ImmutableArray<AnalyzerReference>.Empty;
            }

            var analyzerAssemblies = analyzerPackages.SelectMany(p => p.Assemblies);

            var builder = ImmutableArray.CreateBuilder<AnalyzerReference>();
            foreach (var analyzerAssembly in analyzerAssemblies.Distinct(StringComparer.OrdinalIgnoreCase))
            {
                var reference = new AnalyzerFileReference(analyzerAssembly, s_assemblyLoader);
                reference.AnalyzerLoadFailed += reporter.OnAnalyzerLoadFailed;

                builder.Add(reference);
            }

            return builder.ToImmutable();
        }
 protected abstract string GetAnalyzerAssemblyPath(AnalyzerFileReference reference);
示例#13
0
        public async Task SnapshotWithMissingReferencesTest()
        {
            var hostServices = MefHostServices.Create(
                MefHostServices.DefaultAssemblies.Add(typeof(Host.TemporaryStorageServiceFactory.TemporaryStorageService).Assembly));

            var project = new AdhocWorkspace(hostServices).CurrentSolution.AddProject("Project", "Project.dll", LanguageNames.CSharp);

            var metadata = new MissingMetadataReference();
            var analyzer = new AnalyzerFileReference("missing_reference", new MissingAnalyzerLoader());

            project = project.AddMetadataReference(metadata);
            project = project.AddAnalyzerReference(analyzer);

            var snapshotService = (new SolutionSynchronizationServiceFactory()).CreateService(project.Solution.Workspace.Services) as ISolutionSynchronizationService;
            using (var snapshot = await snapshotService.CreatePinnedRemotableDataScopeAsync(project.Solution, CancellationToken.None).ConfigureAwait(false))
            {
                // this shouldn't throw
                var recovered = await GetSolutionAsync(snapshotService, snapshot).ConfigureAwait(false);
            }
        }
示例#14
0
        public async Task Missing_Analyzer_Serailization_Test()
        {
            var workspace = new AdhocWorkspace();
            var serializer = new Serializer(workspace.Services);

            var reference = new AnalyzerFileReference("missing_reference", new MissingAnalyzerLoader());

            // make sure this doesn't throw
            var assetFromFile = SolutionAsset.Create(serializer.CreateChecksum(reference, CancellationToken.None), reference, serializer);
            var assetFromStorage = await CloneAssetAsync(serializer, assetFromFile).ConfigureAwait(false);
            var assetFromStorage2 = await CloneAssetAsync(serializer, assetFromStorage).ConfigureAwait(false);
        }
示例#15
0
        private void UpdateProject(ProjectFileInfo projectFileInfo)
        {
            var project = _workspace.CurrentSolution.GetProject(projectFileInfo.WorkspaceId);

            var unusedDocuments = project.Documents.ToDictionary(d => d.FilePath, d => d.Id);

            foreach (var file in projectFileInfo.SourceFiles)
            {
                if (unusedDocuments.Remove(file))
                {
                    continue;
                }

                using (var stream = File.OpenRead(file))
                {
                    var sourceText = SourceText.From(stream, encoding: Encoding.UTF8);
                    var id = DocumentId.CreateNewId(projectFileInfo.WorkspaceId);
                    var version = VersionStamp.Create();

                    var loader = TextLoader.From(TextAndVersion.Create(sourceText, version));

                    _workspace.AddDocument(DocumentInfo.Create(id, file, filePath: file, loader: loader));
                }
            }

            foreach (var unused in unusedDocuments)
            {
                _workspace.RemoveDocument(unused.Value);
            }

            var unusedProjectReferences = new HashSet<ProjectReference>(project.ProjectReferences);

            foreach (var projectReferencePath in projectFileInfo.ProjectReferences)
            {
                ProjectFileInfo projectReferenceInfo;
                if (_context.Projects.TryGetValue(projectReferencePath, out projectReferenceInfo))
                {
                    var reference = new ProjectReference(projectReferenceInfo.WorkspaceId);

                    if (unusedProjectReferences.Remove(reference))
                    {
                        // This reference already exists
                        continue;
                    }

                    _workspace.AddProjectReference(project.Id, reference);
                }
                else
                {
                    _logger.WriteWarning(string.Format("Unable to resolve project reference '{0}' for '{1}'.", projectReferencePath, projectFileInfo.ProjectFilePath));
                }
            }

            foreach (var unused in unusedProjectReferences)
            {
                _workspace.RemoveProjectReference(project.Id, unused);
            }

            var unusedAnalyzers = new Dictionary<string, AnalyzerReference>(project.AnalyzerReferences.ToDictionary(a => a.FullPath));

            foreach (var analyzerPath in projectFileInfo.Analyzers)
            {
                if (!File.Exists(analyzerPath))
                {
                    _logger.WriteWarning(string.Format("Unable to resolve assembly '{0}'", analyzerPath));
                }
                else
                {
                    if (unusedAnalyzers.Remove(analyzerPath))
                    {
                        continue;
                    }
#if ASPNET50
                    var analyzerReference = new AnalyzerFileReference(analyzerPath);
                    project.AddAnalyzerReference(analyzerReference);
#endif
                }
            }

            foreach (var analyzerReference in unusedAnalyzers.Values)
            {
                project.RemoveAnalyzerReference(analyzerReference);
            }

            var unusedReferences = new HashSet<MetadataReference>(project.MetadataReferences);

            foreach (var referencePath in projectFileInfo.References)
            {
                if (!File.Exists(referencePath))
                {
                    _logger.WriteWarning(string.Format("Unable to resolve assembly '{0}'", referencePath));
                }
                else
                {
                    var metadataReference = _metadataReferenceCache.GetMetadataReference(referencePath);

                    if (unusedReferences.Remove(metadataReference))
                    {
                        continue;
                    }

                    _logger.WriteVerbose(string.Format("Adding reference '{0}' to '{1}'.", referencePath, projectFileInfo.ProjectFilePath));
                    _workspace.AddMetadataReference(project.Id, metadataReference);
                }
            }

            foreach (var reference in unusedReferences)
            {
                _workspace.RemoveMetadataReference(project.Id, reference);
            }
        }
 public void ClearAnalyzerReferenceDiagnostics(AnalyzerFileReference analyzerReference, string language, ProjectId projectId)
 {
     var analyzers = analyzerReference.GetAnalyzers(language);
     ClearAnalyzerDiagnostics(analyzers, projectId);
     AnalyzerManager.Instance.ClearAnalyzerState(analyzers);
 }
示例#17
0
        private static ImmutableArray<DiagnosticAnalyzer> CreateAnalyzersFromFile(AnalyzerFileReference reference, string langauge)
        {
            Debug.Assert(PathUtilities.IsAbsolute(reference.FullPath));

            // get all analyzers in the assembly for the given language;
            var builder = ImmutableArray.CreateBuilder<DiagnosticAnalyzer>();
            reference.AddAnalyzers(builder, langauge);
            var analyzers = builder.ToImmutable();

            CacheAnalyzers(langauge, reference.FullPath, analyzers);
            EnableCompactTimer();

            return analyzers;
        }
示例#18
0
        private static ImmutableArray<DiagnosticAnalyzer> CreateAnalyzersFromFile(AnalyzerFileReference reference)
        {
            Debug.Assert(PathUtilities.IsAbsolute(reference.FullPath));

            // get all analyzers in the assembly;
            var map = ImmutableDictionary.CreateBuilder<string, ImmutableArray<DiagnosticAnalyzer>>();
            reference.AddAnalyzers(map);

            // TODO: fix the cache mechanism. I don't understand how the cache is supposed to work
            // so I am leaving it as it is for now. (does weak reference things currently actually work?)
            // also, current one looks like assume a file can have analzyers for only one language.
            // is this assumption right?
            //
            // foreach (var kv in mapBuilder)
            // {
            //     CacheAnalyzers(kv.Key, fullPath, kv.Value);
            // }
            //
            // EnableCompactTimer();

            var array = ImmutableArray.CreateBuilder<DiagnosticAnalyzer>();
            foreach (var analyzers in map.Values)
            {
                array.AddRange(analyzers);
            }

            return array.ToImmutable();
        }
示例#19
0
        internal static ImmutableArray<DiagnosticAnalyzer> GetOrCreateAnalyzersFromFile(AnalyzerFileReference analyzerReference, string langauge = null)
        {
            string fullPath = analyzerReference.FullPath;
            Debug.Assert(PathUtilities.IsAbsolute(fullPath));

            lock (Guard)
            {
                // may throw:
                FileKey key = FileKey.Create(fullPath);

                CachedAnalyzers cachedAnalyzers;
                if (s_analyzersFromFiles.TryGetValue(key, out cachedAnalyzers))
                {
                    if (cachedAnalyzers.Analyzers.IsAlive && cachedAnalyzers.Language == langauge)
                    {
                        return (ImmutableArray<DiagnosticAnalyzer>)cachedAnalyzers.Analyzers.Target;
                    }
                    else
                    {
                        s_analyzersFromFiles.Remove(key);
                        var removed = s_analyzerAssemblyKeys.Remove(key);
                        Debug.Assert(removed);
                        Debug.Assert(!s_analyzerAssemblyKeys.Contains(key));
                    }
                }

                if (langauge == null)
                {
                    return CreateAnalyzersFromFile(analyzerReference);
                }

                return CreateAnalyzersFromFile(analyzerReference, langauge);
            }
        }
 protected override string GetAnalyzerAssemblyPath(AnalyzerFileReference reference)
 {
     // default implementation doesn't do shadow copying and doesn't guarantee snapshot
     return reference.FullPath;
 }
        public async Task Missing_Analyzer_Serailization_Test()
        {
            var workspace = new AdhocWorkspace();
            var reference = new AnalyzerFileReference("missing_reference", new MissingAnalyzerLoader());

            var serializer = new Serializer(workspace.Services);
            var trees = new ChecksumTreeCollection();
            var assetBuilder = new AssetBuilder(trees.CreateRootTreeNode(workspace.CurrentSolution.State));

            // make sure this doesn't throw
            var assetFromFile = assetBuilder.Build(reference, CancellationToken.None);
            var assetFromStorage = await CloneAssetAsync(serializer, assetBuilder, assetFromFile).ConfigureAwait(false);
            var assetFromStorage2 = await CloneAssetAsync(serializer, assetBuilder, assetFromStorage).ConfigureAwait(false);
        }
        public void ClearAnalyzerReferenceDiagnostics(AnalyzerFileReference analyzerReference, string language, ProjectId projectId)
        {
            var analyzers = analyzerReference.GetAnalyzers(language);

            ClearAnalyzerDiagnostics(analyzers, projectId);
        }
示例#23
0
        public async Task Missing_Analyzer_Serailization_Desktop_Test()
        {
            var hostServices = MefHostServices.Create(
                MefHostServices.DefaultAssemblies.Add(typeof(Host.TemporaryStorageServiceFactory.TemporaryStorageService).Assembly));

            var workspace = new AdhocWorkspace(hostServices);
            var serializer = new Serializer(workspace.Services);

            var reference = new AnalyzerFileReference("missing_reference", new MissingAnalyzerLoader());

            // make sure this doesn't throw
            var assetFromFile = SolutionAsset.Create(serializer.CreateChecksum(reference, CancellationToken.None), reference, serializer);
            var assetFromStorage = await CloneAssetAsync(serializer, assetFromFile).ConfigureAwait(false);
            var assetFromStorage2 = await CloneAssetAsync(serializer, assetFromStorage).ConfigureAwait(false);
        }
        public async Task RoundTrip_Analyzer_Serailization_Test()
        {
            var workspace = new AdhocWorkspace();
            var serializer = new Serializer(workspace);

            var reference = new AnalyzerFileReference(typeof(object).Assembly.Location, new MockShadowCopyAnalyzerAssemblyLoader());

            // make sure this doesn't throw
            var assetFromFile = SolutionAsset.Create(serializer.CreateChecksum(reference, CancellationToken.None), reference, serializer);
            var assetFromStorage = await CloneAssetAsync(serializer, assetFromFile).ConfigureAwait(false);
            var assetFromStorage2 = await CloneAssetAsync(serializer, assetFromStorage).ConfigureAwait(false);
        }
        private void UpdateProject(ProjectFileInfo projectFileInfo)
        {
            var project = _workspace.CurrentSolution.GetProject(projectFileInfo.WorkspaceId);

            var unusedDocuments = project.Documents.ToDictionary(d => d.FilePath, d => d.Id);

            foreach (var file in projectFileInfo.SourceFiles)
            {
                if (unusedDocuments.Remove(file))
                {
                    continue;
                }

                using (var stream = File.OpenRead(file))
                {
                    var sourceText = SourceText.From(stream, encoding: Encoding.UTF8);
                    var id = DocumentId.CreateNewId(projectFileInfo.WorkspaceId);
                    var version = VersionStamp.Create();

                    var loader = TextLoader.From(TextAndVersion.Create(sourceText, version));

                    _workspace.AddDocument(DocumentInfo.Create(id, file, filePath: file, loader: loader));
                }
            }

            if (projectFileInfo.SpecifiedLanguageVersion.HasValue || projectFileInfo.DefineConstants != null)
            {
                var parseOptions = projectFileInfo.SpecifiedLanguageVersion.HasValue
                    ? new CSharpParseOptions(projectFileInfo.SpecifiedLanguageVersion.Value)
                    : new CSharpParseOptions();
                if (projectFileInfo.DefineConstants != null && projectFileInfo.DefineConstants.Any())
                {
                    parseOptions = parseOptions.WithPreprocessorSymbols(projectFileInfo.DefineConstants);
                }
                _workspace.SetParseOptions(project.Id, parseOptions);
            }

            foreach (var unused in unusedDocuments)
            {
                _workspace.RemoveDocument(unused.Value);
            }

            var unusedProjectReferences = new HashSet<ProjectReference>(project.ProjectReferences);

            foreach (var projectReferencePath in projectFileInfo.ProjectReferences)
            {
                ProjectFileInfo projectReferenceInfo;
                if (_context.Projects.TryGetValue(projectReferencePath, out projectReferenceInfo))
                {
                    var reference = new ProjectReference(projectReferenceInfo.WorkspaceId);

                    if (unusedProjectReferences.Remove(reference))
                    {
                        // This reference already exists
                        continue;
                    }

                    _workspace.AddProjectReference(project.Id, reference);
                }
                else
                {
                    _logger.LogWarning($"Unable to resolve project reference '{projectReferencePath}' for '{projectFileInfo}'.");
                }
            }

            foreach (var unused in unusedProjectReferences)
            {
                _workspace.RemoveProjectReference(project.Id, unused);
            }

            var unusedAnalyzers = new Dictionary<string, AnalyzerReference>(project.AnalyzerReferences.ToDictionary(a => a.FullPath));

            foreach (var analyzerPath in projectFileInfo.Analyzers)
            {
                if (!File.Exists(analyzerPath))
                {
                    _logger.LogWarning($"Unable to resolve assembly '{analyzerPath}'");
                }
                else
                {
                    if (unusedAnalyzers.Remove(analyzerPath))
                    {
                        continue;
                    }
#if DNX451
                    var analyzerReference = new AnalyzerFileReference(analyzerPath);
                    project.AddAnalyzerReference(analyzerReference);
#endif
                }
            }

            foreach (var analyzerReference in unusedAnalyzers.Values)
            {
                project.RemoveAnalyzerReference(analyzerReference);
            }

            var unusedReferences = new HashSet<MetadataReference>(project.MetadataReferences);

            foreach (var referencePath in projectFileInfo.References)
            {
                if (!File.Exists(referencePath))
                {
                    _logger.LogWarning($"Unable to resolve assembly '{referencePath}'");
                }
                else
                {
                    var metadataReference = _metadataReferenceCache.GetMetadataReference(referencePath);

                    if (unusedReferences.Remove(metadataReference))
                    {
                        continue;
                    }

                    _logger.LogVerbose($"Adding reference '{referencePath}' to '{projectFileInfo.ProjectFilePath}'.");
                    _workspace.AddMetadataReference(project.Id, metadataReference);
                }
            }

            foreach (var reference in unusedReferences)
            {
                _workspace.RemoveMetadataReference(project.Id, reference);
            }
        }
示例#26
0
        static void Main(string[] args)
        {
            SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(@"
                using System;

                namespace RoslynCompileSample
                {
                    public class Writer
                    {
                        public void Write(string message)
                        {
                            var prefix = GetMessagePrefix();
                            Console.WriteLine(prefix + ""-"" + message);
                        }

                        public string GetMessagePrefix()
                        {
                            return ""pre"";
                        }
                    }
                }");

            string assemblyName = Path.GetRandomFileName();
            MetadataReference[] references = new MetadataReference[]
            {
                MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location)
            };

            string analyzerAssemblyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\lib\DotNetDoodle.Analyzers.dll");
            ImmutableArray<DiagnosticAnalyzer> diagnosticAnalyzers = new AnalyzerFileReference(analyzerAssemblyPath).GetAnalyzers(LanguageNames.CSharp);

            CompilationWithAnalyzers compilationWithAnalyzers = CSharpCompilation.Create(
                assemblyName,
                syntaxTrees: new[] { syntaxTree },
                references: references,
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)).WithAnalyzers(diagnosticAnalyzers);

            ImmutableArray<Diagnostic> diagsnostics = compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().Result;

            using (var ms = new MemoryStream())
            {
                EmitResult result = compilationWithAnalyzers.Compilation.Emit(ms);
                ImmutableArray<Diagnostic> allDiagsnostics = result.Diagnostics.Concat(diagsnostics).ToImmutableArray();

                if (!result.Success)
                {
                    IEnumerable<Diagnostic> failures = allDiagsnostics.Where(diagnostic =>
                        diagnostic.IsWarningAsError ||
                        diagnostic.Severity == DiagnosticSeverity.Error);

                    foreach (Diagnostic diagnostic in failures)
                    {
                        Console.Error.WriteLine("ERROR: {0}: {1}", diagnostic.Id, diagnostic.GetMessage());
                    }

                    WriteWarnings(allDiagsnostics);
                }
                else
                {
                    WriteWarnings(allDiagsnostics);

                    ms.Seek(0, SeekOrigin.Begin);
                    Assembly assembly = Assembly.Load(ms.ToArray());

                    Type type = assembly.GetType("RoslynCompileSample.Writer");
                    object obj = Activator.CreateInstance(type);
                    type.InvokeMember("Write",
                        BindingFlags.Default | BindingFlags.InvokeMethod,
                        null,
                        obj,
                        new object[] { "Hello World" });
                }
            }

            Console.ReadLine();
        }
 public void ClearAnalyzerReferenceDiagnostics(AnalyzerFileReference analyzerReference, string language, ProjectId projectId)
 {
     var analyzers = analyzerReference.GetAnalyzers(language);
     ClearAnalyzerDiagnostics(analyzers, projectId);
     CompilationWithAnalyzers.ClearAnalyzerState(analyzers);
 }
示例#28
0
        private static async Task<DiagnosticAnalysisResult> AnalyzeAsync(TestWorkspace workspace, ProjectId projectId, Type analyzerType, CancellationToken cancellationToken = default(CancellationToken))
        {
            var diagnosticService = workspace.ExportProvider.GetExportedValue<IDiagnosticAnalyzerService>();
            var executor = new VisualStudioDiagnosticAnalyzerExecutor(diagnosticService, new MyUpdateSource(workspace));

            var analyzerReference = new AnalyzerFileReference(analyzerType.Assembly.Location, new TestAnalyzerAssemblyLoader());
            var project = workspace.CurrentSolution.GetProject(projectId).AddAnalyzerReference(analyzerReference);

            var analyzerDriver = (await project.GetCompilationAsync()).WithAnalyzers(analyzerReference.GetAnalyzers(project.Language).Where(a => a.GetType() == analyzerType).ToImmutableArray());
            var result = await executor.AnalyzeAsync(analyzerDriver, project, cancellationToken);

            return result.AnalysisResult[analyzerDriver.Analyzers[0]];
        }
示例#29
0
        private static ImmutableArray <DiagnosticAnalyzer> CreateAnalyzersForAllLanguages(AnalyzerFileReference reference)
        {
            // Get all analyzers in the assembly.
            var map = ImmutableDictionary.CreateBuilder <string, ImmutableArray <DiagnosticAnalyzer> >();

            reference.AddAnalyzers(map);

            var builder = ImmutableArray.CreateBuilder <DiagnosticAnalyzer>();

            foreach (var analyzers in map.Values)
            {
                builder.AddRange(analyzers);
            }

            return(builder.ToImmutable());
        }
        public async Task TestHostAnalyzers()
        {
            var code = @"class Test
{
    void Method()
    {
        var t = new Test();
    }
}";

            using (var workspace = await CreateWorkspaceAsync(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 = new VisualStudioDiagnosticAnalyzerExecutor(mockAnalyzerService, new MyUpdateSource(workspace));
                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);
            }
        }
示例#31
0
        public void TestAddRemoveAnalyzerReference()
        {
            CreateFiles(GetSimpleCSharpSolutionFiles()
                .WithFile(@"Analyzers\MyAnalyzer.dll", GetResourceBytes("EmptyLibrary.dll")));

            var projFile = GetSolutionFileName(@"CSharpProject\CSharpProject.csproj");
            var projFileText = File.ReadAllText(projFile);
            Assert.Equal(false, projFileText.Contains(@"<Analyzer Include=""..\Analyzers\MyAnalyzer.dll"));

            using (var ws = MSBuildWorkspace.Create())
            {
                var solution = ws.OpenSolutionAsync(GetSolutionFileName("TestSolution.sln")).Result;
                var project = solution.Projects.First();

                var myAnalyzerPath = GetSolutionFileName(@"Analyzers\MyAnalyzer.dll");
                var aref = new AnalyzerFileReference(myAnalyzerPath, new InMemoryAssemblyLoader());

                // add reference to MyAnalyzer.dll
                ws.TryApplyChanges(project.AddAnalyzerReference(aref).Solution);
                projFileText = File.ReadAllText(projFile);
                Assert.Equal(true, projFileText.Contains(@"<Analyzer Include=""..\Analyzers\MyAnalyzer.dll"));

                // remove reference MyAnalyzer.dll
                ws.TryApplyChanges(ws.CurrentSolution.GetProject(project.Id).RemoveAnalyzerReference(aref).Solution);
                projFileText = File.ReadAllText(projFile);
                Assert.Equal(false, projFileText.Contains(@"<Analyzer Include=""..\Analyzers\MyAnalyzer.dll"));
            }
        }
示例#32
0
 private static ImmutableArray <DiagnosticAnalyzer> CreateLanguageSpecificAnalyzers(string language, AnalyzerFileReference @this)
 {
     return(MetadataCache.GetOrCreateAnalyzersFromFile(@this, language));
 }