Example #1
0
        /// <summary>
        /// Create a new solution instance with the project specified updated to include the
        /// specified analyzer reference.
        /// </summary>
        public Solution AddAnalyzerReference(ProjectId projectId, AnalyzerReference analyzerReference)
        {
            var newState = _state.AddAnalyzerReference(projectId, analyzerReference);

            if (newState == _state)
            {
                return(this);
            }

            return(new Solution(newState));
        }
Example #2
0
        public void WriteTo(AnalyzerReference reference, ObjectWriter writer, bool usePathFromAssembly, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            switch (reference)
            {
            case AnalyzerFileReference file:
            {
                // fail to load analyzer assembly
                var assemblyPath = usePathFromAssembly ? TryGetAnalyzerAssemblyPath(file) : file.FullPath;
                if (assemblyPath == null)
                {
                    WriteUnresolvedAnalyzerReferenceTo(reference, writer);
                    return;
                }

                writer.WriteString(nameof(AnalyzerFileReference));
                writer.WriteInt32((int)SerializationKinds.FilePath);

                // TODO: remove this kind of host specific knowledge from common layer.
                //       but think moving it to host layer where this implementation detail actually exist.
                //
                // analyzer assembly path to load analyzer acts like
                // snapshot version for analyzer (since it is based on shadow copy)
                // we can't send over bits and load analyer from memory (image) due to CLR not being able
                // to find satellite dlls for analyzers.
                writer.WriteString(file.FullPath);
                writer.WriteString(assemblyPath);
                return;
            }

            case UnresolvedAnalyzerReference unresolved:
            {
                WriteUnresolvedAnalyzerReferenceTo(unresolved, writer);
                return;
            }

            case AnalyzerReference analyzerReference when analyzerReference.GetType().FullName == VisualStudioUnresolvedAnalyzerReference:
            {
                WriteUnresolvedAnalyzerReferenceTo(analyzerReference, writer);
                return;
            }

            case AnalyzerImageReference _:
            {
                // TODO: think a way to support this or a way to deal with this kind of situation.
                // https://github.com/dotnet/roslyn/issues/15783
                throw new NotSupportedException(nameof(AnalyzerImageReference));
            }

            default:
                throw ExceptionUtilities.UnexpectedValue(reference);
            }
        }
Example #3
0
        public Checksum CreateChecksum(AnalyzerReference reference, CancellationToken cancellationToken)
        {
            using (var stream = SerializableBytes.CreateWritableStream())
                using (var writer = new StreamObjectWriter(stream, cancellationToken: cancellationToken))
                {
                    WriteTo(reference, writer, cancellationToken);

                    stream.Position = 0;
                    return(Checksum.Create(stream));
                }
        }
Example #4
0
        private static Checksum CreateChecksum(AnalyzerReference reference)
        {
            using (var stream = SerializableBytes.CreateWritableStream())
                using (var objectWriter = new ObjectWriter(stream))
                {
                    objectWriter.WriteString(WellKnownSynchronizationKinds.AnalyzerReference);
                    objectWriter.WriteString(reference.FullPath);

                    return(Checksum.Create(stream));
                }
        }
Example #5
0
        public static WorkspaceAnalyzerReferenceAsset Create(
            AnalyzerReference reference,
            ISerializerService serializer,
            IReferenceSerializationService hostSerializationService,
            CancellationToken cancellationToken)
        {
            var checksum = Checksum.Create(
                WellKnownSynchronizationKind.AnalyzerReference,
                hostSerializationService.CreateChecksum(reference, usePathFromAssembly, cancellationToken));

            return(new WorkspaceAnalyzerReferenceAsset(reference, serializer, checksum));
        }
Example #6
0
            protected override bool TryGetExtensionsFromReference(AnalyzerReference reference, out ImmutableArray <CodeRefactoringProvider> extensions)
            {
                // check whether the analyzer reference knows how to return fixers directly.
                if (reference is ICodeRefactoringProviderFactory codeRefactoringProviderFactory)
                {
                    extensions = codeRefactoringProviderFactory.GetRefactorings();
                    return(true);
                }

                extensions = default;
                return(false);
            }
Example #7
0
        /// <summary>
        /// Call this method when an analyzer reference is removed from a project in the host environment.
        /// </summary>
        protected internal void OnAnalyzerReferenceRemoved(ProjectId projectId, AnalyzerReference analyzerReference)
        {
            using (this.serializationLock.DisposableWait())
            {
                CheckProjectIsInCurrentSolution(projectId);
                CheckProjectHasAnalyzerReference(projectId, analyzerReference);

                var oldSolution = this.CurrentSolution;
                var newSolution = this.SetCurrentSolution(oldSolution.RemoveAnalyzerReference(projectId, analyzerReference));

                this.RaiseWorkspaceChangedEventAsync(WorkspaceChangeKind.ProjectChanged, oldSolution, newSolution, projectId);
            }
        }
        public CpsDiagnosticItemSource(Workspace workspace, ProjectId projectId, IVsHierarchyItem item, IAnalyzersCommandHandler commandHandler, IDiagnosticAnalyzerService analyzerService)
            : base(workspace, projectId, commandHandler, analyzerService)
        {
            _item = item;

            _analyzerReference = TryGetAnalyzerReference(_workspace.CurrentSolution);
            if (_analyzerReference == null)
            {
                // The workspace doesn't know about the project and/or the analyzer yet.
                // Hook up an event handler so we can update when it does.
                _workspace.WorkspaceChanged += OnWorkspaceChangedLookForAnalyzer;
            }
        }
        public void SonarAnalyzerManager_HasNoCollidingAnalyzerReference_NoAssemblyIdentity()
        {
            IEnumerable <AnalyzerReference> references = new AnalyzerReference[]
            {
                new ConfigurableAnalyzerReference(
                    new object(),
                    SonarAnalyzerManager.AnalyzerName)
            };

            SonarAnalyzerManager.HasConflictingAnalyzerReference(
                SonarAnalyzerManager.GetProjectAnalyzerConflictStatus(references))
            .Should().BeTrue("If no AssemblyIdentity is present, but the name matches, we should report a conflict");
        }
        public void SonarAnalyzerManager_HasNoCollidingAnalyzerReference_SameNameVersion()
        {
            IEnumerable <AnalyzerReference> references = new AnalyzerReference[]
            {
                new ConfigurableAnalyzerReference(
                    new AssemblyIdentity(SonarAnalyzerManager.AnalyzerName, SonarAnalyzerManager.AnalyzerVersion),
                    SonarAnalyzerManager.AnalyzerName)
            };

            SonarAnalyzerManager.HasConflictingAnalyzerReference(
                SonarAnalyzerManager.GetProjectAnalyzerConflictStatus(references))
            .Should().BeFalse("Same named and versioned analyzers should not be reported as conflicting ones");
        }
 public override void WriteAnalyzerReferenceTo(AnalyzerReference reference, ObjectWriter writer, CancellationToken cancellationToken)
 {
     if (reference is TestGeneratorReference generatorReference)
     {
         // It's a test reference, we'll just store it in a map and then just write out our GUID
         _sharedTestGeneratorReferences.TryAdd(generatorReference.Guid, generatorReference);
         writer.WriteGuid(generatorReference.Guid);
     }
     else
     {
         writer.WriteGuid(Guid.Empty);
         base.WriteAnalyzerReferenceTo(reference, writer, cancellationToken);
     }
 }
        public void WriteTo(AnalyzerReference reference, ObjectWriter writer, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var file = reference as AnalyzerFileReference;

            if (file != null)
            {
                // fail to load analyzer assembly
                var assemblyPath = TryGetAnalyzerAssemblyPath(file);
                if (assemblyPath == null)
                {
                    WriteUnresolvedAnalyzerReferenceTo(reference, writer);
                    return;
                }

                writer.WriteString(nameof(AnalyzerFileReference));
                writer.WriteInt32((int)SerializationKinds.FilePath);

                writer.WriteString(file.FullPath);

                // TODO: remove this kind of host specific knowledge from common layer.
                //       but think moving it to host layer where this implementation detail actually exist.
                //
                // analyzer assembly path to load analyzer acts like
                // snapshot version for analyzer (since it is based on shadow copy)
                // we can't send over bits and load analyer from memory (image) due to CLR not being able
                // to find satellite dlls for analyzers.
                writer.WriteString(assemblyPath);
                return;
            }

            var unresolved = reference as UnresolvedAnalyzerReference;

            if (unresolved != null)
            {
                WriteUnresolvedAnalyzerReferenceTo(reference, writer);
                return;
            }

            var image = reference as AnalyzerImageReference;

            if (image != null)
            {
                // TODO: think a way to support this or a way to deal with this kind of situation.
                throw new NotSupportedException(nameof(AnalyzerImageReference));
            }

            throw ExceptionUtilities.UnexpectedValue(reference.GetType());
        }
                    public bool HasAnalyzerReference(AnalyzerReference analyzerReference)
                    {
                        Contract.ThrowIfNull(analyzerReference);

                        if (analyzerReference is AnalyzerFileReference)
                        {
                            // Filter out duplicate analyzer references with same assembly name/full path.
                            return analyzerReference.Display != null && _diagnosticAnalyzerIdMap.ContainsKey(analyzerReference.Display);
                        }
                        else
                        {
                            // For non-file references, we will check individual DiagnosticAnalyzer instances for duplicates.
                            return false;
                        }
                    }
                    public bool HasAnalyzerReference(AnalyzerReference analyzerReference)
                    {
                        Contract.ThrowIfNull(analyzerReference);

                        if (analyzerReference is AnalyzerFileReference)
                        {
                            // Filter out duplicate analyzer references with same assembly name/full path.
                            return(analyzerReference.Display != null && _diagnosticAnalyzerIdMap.ContainsKey(analyzerReference.Display));
                        }
                        else
                        {
                            // For non-file references, we will check individual DiagnosticAnalyzer instances for duplicates.
                            return(false);
                        }
                    }
Example #15
0
        public void SonarAnalyzerManager_GetIsBoundWithoutAnalyzer_Unbound_NonConflicting()
        {
            this.activeSolutionBoundTracker.IsActiveSolutionBound = false;

            IEnumerable <AnalyzerReference> references = new AnalyzerReference[]
            {
                new ConfigurableAnalyzerReference(
                    new AssemblyIdentity(SonarAnalyzerManager.AnalyzerName, SonarAnalyzerManager.AnalyzerVersion),
                    SonarAnalyzerManager.AnalyzerName)
            };

            this.testSubject.GetIsBoundWithoutAnalyzer(
                SonarAnalyzerManager.GetProjectAnalyzerConflictStatus(references))
            .Should().BeFalse("Unbound solution should never return true");
        }
Example #16
0
        public void RemoveAnalyzerReference(AnalyzerReference reference)
        {
            if (reference is AnalyzerFileReference fileRef)
            {
                var relativePath = PathUtilities.GetRelativePath(_loadedProject.DirectoryPath, fileRef.FullPath);

                var analyzers = _loadedProject.GetItems(ItemNames.Analyzer);
                var item      = analyzers.FirstOrDefault(it => PathUtilities.PathsEqual(it.EvaluatedInclude, relativePath) ||
                                                         PathUtilities.PathsEqual(it.EvaluatedInclude, fileRef.FullPath));
                if (item != null)
                {
                    _loadedProject.RemoveItem(item);
                }
            }
        }
Example #17
0
 public DiagnosticItem(
     ProjectId projectId,
     AnalyzerReference analyzerReference,
     DiagnosticDescriptor descriptor,
     ReportDiagnostic effectiveSeverity,
     string language,
     IAnalyzersCommandHandler commandHandler
     ) : base(descriptor.Id + ": " + descriptor.Title)
 {
     ProjectId          = projectId;
     _analyzerReference = analyzerReference;
     Descriptor         = descriptor;
     EffectiveSeverity  = effectiveSeverity;
     _language          = language;
     _commandHandler    = commandHandler;
 }
Example #18
0
        public static void WriteTo(AnalyzerReference reference, ObjectWriter writer, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            switch (reference)
            {
            case AnalyzerFileReference file:
                writer.WriteString(nameof(AnalyzerFileReference));
                writer.WriteString(file.FullPath);
                writer.WriteBoolean(IsAnalyzerReferenceWithShadowCopyLoader(file));
                break;

            default:
                throw ExceptionUtilities.UnexpectedValue(reference);
            }
        }
Example #19
0
        public AnalyzerReference GetReference()
        {
            if (_analyzerReference == null)
            {
                if (File.Exists(_fullPath))
                {
                    _analyzerReference = new AnalyzerFileReference(_fullPath, InMemoryAssemblyProvider.GetAssembly);
                    ((AnalyzerFileReference)_analyzerReference).AnalyzerLoadFailed += OnAnalyzerLoadError;
                }
                else
                {
                    _analyzerReference = new UnresolvedAnalyzerReference(_fullPath);
                }
            }

            return(_analyzerReference);
        }
        public void SonarAnalyzerManager_HasNoCollidingAnalyzerReference_SameVersionDifferentName()
        {
            var name = "Some test name";

            name.Should().NotBe(SonarAnalyzerManager.AnalyzerName,
                                "Test input should be different from the expected analyzer name");

            IEnumerable <AnalyzerReference> references = new AnalyzerReference[]
            {
                new ConfigurableAnalyzerReference(
                    new AssemblyIdentity(name, SonarAnalyzerManager.AnalyzerVersion), name)
            };

            SonarAnalyzerManager.HasConflictingAnalyzerReference(
                SonarAnalyzerManager.GetProjectAnalyzerConflictStatus(references))
            .Should().BeFalse("Name is not considered in the conflict checking");
        }
Example #21
0
        public void Reset()
        {
            if (_analyzerReference is AnalyzerFileReference analyzerFileReference)
            {
                analyzerFileReference.AnalyzerLoadFailed -= OnAnalyzerLoadError;

                if (_analyzerLoadErrors != null && _analyzerLoadErrors.Count > 0)
                {
                    _hostDiagnosticUpdateSource.ClearDiagnosticsForProject(_projectId, this);
                }

                _hostDiagnosticUpdateSource.ClearAnalyzerReferenceDiagnostics(analyzerFileReference, _language, _projectId);
            }

            _analyzerLoadErrors = null;
            _analyzerReference  = null;
        }
        public AnalyzerReference GetReference()
        {
            if (_analyzerReference == null)
            {
                if (File.Exists(_fullPath))
                {
                    _analyzerReference = new AnalyzerFileReference(_fullPath, _loader);
                    ((AnalyzerFileReference)_analyzerReference).AnalyzerLoadFailed += OnAnalyzerLoadError;
                }
                else
                {
                    _analyzerReference = new UnresolvedAnalyzerReference(_fullPath);
                }
            }

            return(_analyzerReference);
        }
Example #23
0
        public void RemoveAnalyzerReference(AnalyzerReference reference)
        {
            var fileRef = reference as AnalyzerFileReference;

            if (fileRef != null)
            {
                string relativePath = FilePathUtilities.GetRelativePath(_loadedProject.DirectoryPath, fileRef.FullPath);

                var analyzers = _loadedProject.GetItems("Analyzer");
                var item      = analyzers.FirstOrDefault(it => FilePathUtilities.PathsEqual(it.EvaluatedInclude, relativePath) ||
                                                         FilePathUtilities.PathsEqual(it.EvaluatedInclude, fileRef.FullPath));
                if (item != null)
                {
                    _loadedProject.RemoveItem(item);
                }
            }
        }
        public void SonarAnalyzerManager_HasNoCollidingAnalyzerReference_NoDisplayName()
        {
            var version = new Version("0.1.2.3");

            version.Should().NotBe(SonarAnalyzerManager.AnalyzerVersion,
                                   "Test input should be different from the expected analyzer version");

            IEnumerable <AnalyzerReference> references = new AnalyzerReference[]
            {
                new ConfigurableAnalyzerReference(
                    new AssemblyIdentity(SonarAnalyzerManager.AnalyzerName, version),
                    null)
            };

            SonarAnalyzerManager.HasConflictingAnalyzerReference(
                SonarAnalyzerManager.GetProjectAnalyzerConflictStatus(references))
            .Should().BeFalse("Null analyzer name should not report conflict");
        }
        public void SonarAnalyzerManager_HasCollidingAnalyzerReference()
        {
            var version = new Version("0.1.2.3");

            version.Should().NotBe(SonarAnalyzerManager.AnalyzerVersion,
                                   "Test input should be different from the expected analyzer version");

            IEnumerable <AnalyzerReference> references = new AnalyzerReference[]
            {
                new ConfigurableAnalyzerReference(
                    new AssemblyIdentity(SonarAnalyzerManager.AnalyzerName, version),
                    SonarAnalyzerManager.AnalyzerName)
            };

            SonarAnalyzerManager.HasConflictingAnalyzerReference(
                SonarAnalyzerManager.GetProjectAnalyzerConflictStatus(references))
            .Should().BeTrue("Conflicting analyzer package not found");
        }
Example #26
0
        public AnalyzerReference GetReference()
        {
            if (_analyzerReference == null)
            {
                if (File.Exists(_fullPath))
                {
                    // Pass down a custom loader that will ensure we are watching for file changes once we actually load the assembly.
                    var assemblyLoaderForFileTracker = new AnalyzerAssemblyLoaderThatEnsuresFileBeingWatched(this);
                    _analyzerReference = new AnalyzerFileReference(_fullPath, assemblyLoaderForFileTracker);
                    ((AnalyzerFileReference)_analyzerReference).AnalyzerLoadFailed += OnAnalyzerLoadError;
                }
                else
                {
                    _analyzerReference = new VisualStudioUnresolvedAnalyzerReference(_fullPath, this);
                }
            }

            return(_analyzerReference);
        }
Example #27
0
        public void SonarAnalyzerManager_GetIsBoundWithoutAnalyzer_Unbound_Conflicting()
        {
            this.activeSolutionBoundTracker.IsActiveSolutionBound = false;

            var version = new Version("0.1.2.3");

            version.Should().NotBe(SonarAnalyzerManager.AnalyzerVersion,
                                   "Test input should be different from the expected analyzer version");

            IEnumerable <AnalyzerReference> references = new AnalyzerReference[]
            {
                new ConfigurableAnalyzerReference(
                    new AssemblyIdentity(SonarAnalyzerManager.AnalyzerName, version),
                    SonarAnalyzerManager.AnalyzerName)
            };

            this.testSubject.GetIsBoundWithoutAnalyzer(
                SonarAnalyzerManager.GetProjectAnalyzerConflictStatus(references))
            .Should().BeFalse("Unbound solution should never return true");
        }
Example #28
0
        public void SonarAnalyzerManager_GetIsBoundWithoutAnalyzer_Bound_Conflicting()
        {
            this.activeSolutionBoundTracker.IsActiveSolutionBound = true;

            var version = new Version("0.1.2.3");

            Assert.AreNotEqual(SonarAnalyzerManager.AnalyzerVersion, version,
                               "Test input should be different from the expected analyzer version");

            IEnumerable <AnalyzerReference> references = new AnalyzerReference[]
            {
                new ConfigurableAnalyzerReference(
                    new AssemblyIdentity(SonarAnalyzerManager.AnalyzerName, version),
                    SonarAnalyzerManager.AnalyzerName)
            };

            Assert.IsFalse(
                this.testSubject.GetIsBoundWithoutAnalyzer(
                    SonarAnalyzerManager.GetProjectAnalyzerConflictStatus(references)),
                "Bound solution with conflicting analyzer name should never return true");
        }
        public void SonarAnalyzerManager_MultipleReferencesWithSameName_CollidingVersion()
        {
            var version = new Version("0.1.2.3");

            version.Should().NotBe(SonarAnalyzerManager.AnalyzerVersion,
                                   "Test input should be different from the expected analyzer version");

            IEnumerable <AnalyzerReference> references = new AnalyzerReference[]
            {
                new ConfigurableAnalyzerReference(
                    new AssemblyIdentity(SonarAnalyzerManager.AnalyzerName, version),
                    SonarAnalyzerManager.AnalyzerName),
                new ConfigurableAnalyzerReference(
                    new AssemblyIdentity(SonarAnalyzerManager.AnalyzerName, SonarAnalyzerManager.AnalyzerVersion),
                    SonarAnalyzerManager.AnalyzerName),
            };

            SonarAnalyzerManager.HasConflictingAnalyzerReference(
                SonarAnalyzerManager.GetProjectAnalyzerConflictStatus(references))
            .Should().BeFalse("Having already colliding references should not disable the embedded analyzer if one is of the same version");
        }
Example #30
0
        protected override void ApplyAnalyzerReferenceRemoved(ProjectId projectId, AnalyzerReference analyzerReference)
        {
            if (projectId == null)
            {
                throw new ArgumentNullException(nameof(projectId));
            }

            if (analyzerReference == null)
            {
                throw new ArgumentNullException(nameof(analyzerReference));
            }

            GetProjectData(projectId, out var hostProject, out var hierarchy, out var project);

            string filePath = GetAnalyzerPath(analyzerReference);

            if (filePath != null)
            {
                VSProject3 vsProject = (VSProject3)project.Object;
                vsProject.AnalyzerReferences.Remove(filePath);
            }
        }
        private IEnumerable <BaseDiagnosticItem> GetDiagnosticItems(string language, CompilationOptions options, ImmutableDictionary <string, ReportDiagnostic> analyzerConfigSpecificDiagnosticOptions)
        {
            // Within an analyzer assembly, an individual analyzer may report multiple different diagnostics
            // with the same ID. Or, multiple analyzers may report diagnostics with the same ID. Or a
            // combination of the two may occur.
            // We only want to show one node in Solution Explorer for a given ID. So we pick one, but we need
            // to be consistent in which one we pick. Diagnostics with the same ID may have different
            // descriptions or messages, and it would be strange if the node's name changed from one run of
            // VS to another. So we group the diagnostics by ID, sort them within a group, and take the first
            // one.

            return(AnalyzerReference.GetAnalyzers(language)
                   .SelectMany(a => _diagnosticAnalyzerService.GetDiagnosticDescriptors(a))
                   .GroupBy(d => d.Id)
                   .OrderBy(g => g.Key, StringComparer.CurrentCulture)
                   .Select(g =>
            {
                var selectedDiagnostic = g.OrderBy(d => d, s_comparer).First();
                var effectiveSeverity = selectedDiagnostic.GetEffectiveSeverity(options, analyzerConfigSpecificDiagnosticOptions);
                return CreateItem(selectedDiagnostic, effectiveSeverity);
            }));
        }