diff --git a/src/VisualStudio/CSharp/Impl/CSharpVisualStudio.csproj b/src/VisualStudio/CSharp/Impl/CSharpVisualStudio.csproj index b3836aed2948b074e513eeff7b5d1a030f555f11..b3dd3a71dcaee49a3abb4158c011434851edabcb 100644 --- a/src/VisualStudio/CSharp/Impl/CSharpVisualStudio.csproj +++ b/src/VisualStudio/CSharp/Impl/CSharpVisualStudio.csproj @@ -133,9 +133,6 @@ - - - diff --git a/src/VisualStudio/CSharp/Impl/Telemetry/CSharpCompilationErrorTelemetryIncrementalAnalyzer.cs b/src/VisualStudio/CSharp/Impl/Telemetry/CSharpCompilationErrorTelemetryIncrementalAnalyzer.cs deleted file mode 100644 index 45ebe681c9badcab72047840c23ed76f69b8b414..0000000000000000000000000000000000000000 --- a/src/VisualStudio/CSharp/Impl/Telemetry/CSharpCompilationErrorTelemetryIncrementalAnalyzer.cs +++ /dev/null @@ -1,338 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Composition; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using System.Xml.Linq; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Options; -using Microsoft.CodeAnalysis.Shared.Extensions; -using Microsoft.CodeAnalysis.SolutionCrawler; -using Microsoft.Internal.VisualStudio.Shell; -using Microsoft.VisualStudio.LanguageServices.Implementation.CompilationErrorTelemetry; -using Roslyn.Utilities; -using System.Security.Cryptography; - -namespace Microsoft.VisualStudio.LanguageServices.Telemetry -{ - [ExportPerLanguageIncrementalAnalyzerProvider(CompilationErrorTelemetryIncrementalAnalyzer.Name, LanguageNames.CSharp), Shared] - internal class CSharpCompilationErrorTelemetryIncrementalAnalyzer : IPerLanguageIncrementalAnalyzerProvider - { - public IIncrementalAnalyzer CreatePerLanguageIncrementalAnalyzer(Workspace workspace, IIncrementalAnalyzerProvider provider) - { - return new Analyzer(); - } - - private class Analyzer : IIncrementalAnalyzer - { - private const string EventPrefix = "VS/Compilers/Compilation/"; - private const string PropertyPrefix = "VS.Compilers.Compilation.Error."; - - private const string TelemetryEventPath = EventPrefix + "Error"; - private const string TelemetryExceptionEventPath = EventPrefix + "TelemetryUnhandledException"; - private const string TelemetryErrorId = PropertyPrefix + "ErrorId"; - private const string TelemetryMethodName = PropertyPrefix + "MethodName"; - private const string TelemetryUnresolvedMemberName = PropertyPrefix + "UnresolvedMemberName"; - private const string TelemetryLeftExpressionDocId = PropertyPrefix + "LeftExpressionDocId"; - private const string TelemetryBaseTypes = PropertyPrefix + "LeftExpressionBaseTypeDocIds"; - private const string TelemetryGenericArguments = PropertyPrefix + "GenericArgumentDocIds"; - private const string TelemetryProjectGuid = PropertyPrefix + "ProjectGuid"; - private const string TelemetryMismatchedArgumentTypeDocIds = PropertyPrefix + "MismatchedArgumentDocIds"; - private const string UnspecifiedProjectGuid = "unspecified"; - - private SolutionId _currentSolutionId; - - private readonly CompilationErrorDetailDiscoverer _errorDetailDiscoverer = new CompilationErrorDetailDiscoverer(); - private readonly ProjectGuidCache _projectGuidCache = new ProjectGuidCache(); - private readonly CompilationErrorDetailCache _errorDetailCache = new CompilationErrorDetailCache(); - - public async Task AnalyzeDocumentAsync(Document document, SyntaxNode bodyOpt, InvocationReasons reasons, CancellationToken cancellationToken) - { - try - { - // do nothing if this document is not currently open. - // to prevent perf from getting too poor for large projects, only examine open documents. - if (!document.IsOpen()) - { - return; - } - - // Only analyzing C# for now - if (document.Project.Language != LanguageNames.CSharp) - { - return; - } - - List errorDetails = await _errorDetailDiscoverer.GetCompilationErrorDetails(document, bodyOpt, cancellationToken).ConfigureAwait(false); - - var errorsToReport = _errorDetailCache.GetErrorsToReportAndRecordErrors(document.Id, errorDetails); - if (errorsToReport != null) - { - using (var hashProvider = new SHA256CryptoServiceProvider()) - { - foreach (CompilationErrorDetails errorDetail in errorsToReport) - { - var telemetryEvent = TelemetryHelper.TelemetryService.CreateEvent(TelemetryEventPath); - telemetryEvent.SetStringProperty(TelemetryErrorId, errorDetail.ErrorId); - - string projectGuid = _projectGuidCache.GetProjectGuidFromProjectPath(document.Project.FilePath); - telemetryEvent.SetStringProperty(TelemetryProjectGuid, string.IsNullOrEmpty(projectGuid) ? UnspecifiedProjectGuid : projectGuid.ToString()); - - if (!string.IsNullOrEmpty(errorDetail.UnresolvedMemberName)) - { - telemetryEvent.SetStringProperty(TelemetryUnresolvedMemberName, GetHashedString(errorDetail.UnresolvedMemberName, hashProvider)); - } - - if (!string.IsNullOrEmpty(errorDetail.LeftExpressionDocId)) - { - telemetryEvent.SetStringProperty(TelemetryLeftExpressionDocId, GetHashedString(errorDetail.LeftExpressionDocId, hashProvider)); - } - - if (!IsArrayNullOrEmpty(errorDetail.LeftExpressionBaseTypeDocIds)) - { - string telemetryBaseTypes = string.Join(";", errorDetail.LeftExpressionBaseTypeDocIds.Select(docId => GetHashedString(docId, hashProvider))); - telemetryEvent.SetStringProperty(TelemetryBaseTypes, telemetryBaseTypes); - } - - if (!IsArrayNullOrEmpty(errorDetail.GenericArguments)) - { - string telemetryGenericArguments = string.Join(";", errorDetail.GenericArguments.Select(docId => GetHashedString(docId, hashProvider))); - telemetryEvent.SetStringProperty(TelemetryGenericArguments, telemetryGenericArguments); - } - - if (!string.IsNullOrEmpty(errorDetail.MethodName)) - { - telemetryEvent.SetStringProperty(TelemetryMethodName, GetHashedString(errorDetail.MethodName, hashProvider)); - } - - if (!IsArrayNullOrEmpty(errorDetail.ArgumentTypes)) - { - string telemetryMisMatchedArgumentTypeDocIds = string.Join(";", errorDetail.ArgumentTypes.Select(docId => GetHashedString(docId, hashProvider))); - telemetryEvent.SetStringProperty(TelemetryMismatchedArgumentTypeDocIds, telemetryMisMatchedArgumentTypeDocIds); - } - - TelemetryHelper.DefaultTelemetrySession.PostEvent(telemetryEvent); - } - } - } - } - catch (Exception e) - { - // The telemetry service itself can throw. - // So, to be very careful, put this in a try/catch too. - try - { - var exceptionEvent = TelemetryHelper.TelemetryService.CreateEvent(TelemetryExceptionEventPath); - exceptionEvent.SetStringProperty("Type", e.GetTypeDisplayName()); - exceptionEvent.SetStringProperty("Message", e.Message); - exceptionEvent.SetStringProperty("StackTrace", e.StackTrace); - TelemetryHelper.DefaultTelemetrySession.PostEvent(exceptionEvent); - } - catch - { - } - } - } - - public Task AnalyzeProjectAsync(Project project, bool semanticsChanged, InvocationReasons reasons, CancellationToken cancellationToken) - { - return SpecializedTasks.EmptyTask; - } - - public Task AnalyzeSyntaxAsync(Document document, InvocationReasons reasons, CancellationToken cancellationToken) - { - return SpecializedTasks.EmptyTask; - } - - public Task DocumentOpenAsync(Document document, CancellationToken cancellationToken) - { - return SpecializedTasks.EmptyTask; - } - - public Task DocumentCloseAsync(Document document, CancellationToken cancellationToken) - { - return SpecializedTasks.EmptyTask; - } - - public Task DocumentResetAsync(Document document, CancellationToken cancellationToken) - { - _errorDetailCache.ClearCacheForDocument(document.Id); - return SpecializedTasks.EmptyTask; - } - - public bool NeedsReanalysisOnOptionChanged(object sender, OptionChangedEventArgs e) - { - return false; - } - - public Task NewSolutionSnapshotAsync(Solution solution, CancellationToken cancellationToken) - { - if (solution.Id != _currentSolutionId) - { - _projectGuidCache.Clear(); - _errorDetailCache.Clear(); - - _currentSolutionId = solution.Id; - } - - return SpecializedTasks.EmptyTask; - } - - public void RemoveDocument(DocumentId documentId) - { - _errorDetailCache.ClearCacheForDocument(documentId); - } - - public void RemoveProject(ProjectId projectId) - { - } - - private static string GetHashedString(string unhashedString, SHA256 hashProvider) - { - // The point of hashing here is to obscure customer data. - // So, if we get any empty values (noone knows why this happens for certain... has only been observed in dumps) - // an empty string is fine. It will appear as an extra semicolon in the MD value. - if (string.IsNullOrEmpty(unhashedString)) - { - return string.Empty; - } - - if (TelemetryHelper.DefaultTelemetrySession.CanCollectPrivateInformation()) - { - return unhashedString; - } - - byte[] theHash = hashProvider.ComputeHash(Encoding.UTF8.GetBytes(unhashedString)); - StringBuilder sb = new StringBuilder(theHash.Length); - for (int i = 0; i < theHash.Length; i++) - { - sb.AppendFormat("{0:X}", theHash[i]); - } - - return sb.ToString(); - } - - private static bool IsArrayNullOrEmpty(Array list) - { - return (list == null) || (list.Length == 0); - } - } - - private class CompilationErrorDetailCache - { - private readonly Dictionary> _errorCache = new Dictionary>(); - private readonly object _lockObject = new object(); - - public IEnumerable GetErrorsToReportAndRecordErrors(DocumentId documentId, IEnumerable errors) - { - if (errors == null) - { - return Enumerable.Empty(); - } - - lock (_lockObject) - { - List ret = null; - if (!_errorCache.TryGetValue(documentId, out var cachedErrorsForDocument)) - { - cachedErrorsForDocument = new HashSet(); - _errorCache[documentId] = cachedErrorsForDocument; - } - - foreach (var error in errors) - { - if (!cachedErrorsForDocument.Contains(error)) - { - ret = ret ?? new List(); - ret.Add(error); - } - } - - // Only add errors to the cache after looping through the whole list. This is so that if there are multiple instances of the same error - // (with all the same data that we gather) in a document, that it willget reported multiple - if (ret != null) - { - foreach (var error in ret) - { - cachedErrorsForDocument.Add(error); - } - } - - return ret; - } - } - - public void ClearCacheForDocument(DocumentId documentId) - { - lock (_lockObject) - { - _errorCache.Remove(documentId); - } - } - - public void Clear() - { - lock (_lockObject) - { - _errorCache.Clear(); - } - } - } - - private class ProjectGuidCache - { - private readonly Dictionary _projectGuids = new Dictionary(); - private readonly object _lockObject = new object(); - - public void Clear() - { - lock (_lockObject) - { - _projectGuids.Clear(); - } - } - - public string GetProjectGuidFromProjectPath(string projectPath) - { - // misc project, web site and etc might not have project path. - if (string.IsNullOrEmpty(projectPath)) - { - return null; - } - - lock (_lockObject) - { - if (_projectGuids.TryGetValue(projectPath, out var ret)) - { - return ret; - } - - try - { - XDocument project = XDocument.Load(projectPath); - ret = (from xElement in project.Descendants() - where xElement.Name.LocalName.Equals("ProjectGuid", StringComparison.InvariantCultureIgnoreCase) && - xElement.Parent != null && - xElement.Parent.Name.LocalName.Equals("PropertyGroup", StringComparison.InvariantCultureIgnoreCase) - select xElement.Value).FirstOrDefault(); - if (ret != null) - { - _projectGuids[projectPath] = ret; - return ret; - } - } - catch - { - } - - return null; - } - } - } - } -} diff --git a/src/VisualStudio/CSharp/Impl/Telemetry/CompilationErrorDetailDiscoverer.cs b/src/VisualStudio/CSharp/Impl/Telemetry/CompilationErrorDetailDiscoverer.cs deleted file mode 100644 index b374c2477bea9409bee24c97a6c3b0f09432dea0..0000000000000000000000000000000000000000 --- a/src/VisualStudio/CSharp/Impl/Telemetry/CompilationErrorDetailDiscoverer.cs +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.LanguageServices; -using Microsoft.CodeAnalysis.Shared.Extensions; -using Microsoft.CodeAnalysis.Text; -using Roslyn.Utilities; - -namespace Microsoft.VisualStudio.LanguageServices.Telemetry -{ - internal class CompilationErrorDetailDiscoverer - { - /// - /// name does not exist in context - /// - private const string CS0103 = "CS0103"; - - /// - /// type or namespace could not be found - /// - private const string CS0246 = "CS0246"; - - /// - /// wrong number of type args - /// - private const string CS0305 = "CS0305"; - - /// - /// The non-generic type 'A' cannot be used with type arguments - /// - private const string CS0308 = "CS0308"; - - /// - /// An attempt was made to use a non-attribute class in an attribute block. All the attribute types need to be inherited from System.Attribute - /// - private const string CS0616 = "CS0616"; - - /// - /// type does not contain a definition of method or extension method - /// - private const string CS1061 = "CS1061"; - - /// - /// The type of one argument in a method does not match the type that was passed when the class was instantiated. This error typically appears along with CS1502 - /// Likely to occur when a type / member exists in a new framework but its specific overload is missing. - /// - private const string CS1503 = "CS1503"; - - /// - /// cannot find implementation of query pattern - /// - private const string CS1935 = "CS1935"; - - /// - /// Used to record generic argument types the semantic model doesn't know about - /// - private const string UnknownGenericArgumentTypeName = "Unknown"; - - /// - /// Used to record symbol names for error scenarios where GetSymbolInfo/GetTypeInfo returns no symbol. - /// - private const string UnknownSymbolName = "Unknown"; - - public async Task> GetCompilationErrorDetails(Document document, SyntaxNode bodyOpt, CancellationToken cancellationToken) - { - try - { - var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); - ImmutableArray diagnostics; - - // If we have the SyntaxNode bodyOpt, - // then we can use its fullSpan property to process a subset of the document. - if (bodyOpt == null) - { - diagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); - } - else - { - diagnostics = semanticModel.GetDiagnostics(bodyOpt.FullSpan, cancellationToken: cancellationToken); - } - - if (diagnostics.Length == 0) - { - return null; - } - - var syntaxFacts = document.Project.LanguageServices.GetService(); - - List ret = new List(); - - foreach (var diagnostic in diagnostics) - { - if (diagnostic.Severity != DiagnosticSeverity.Error || diagnostic.IsWarningAsError) - { - continue; - } - - if (!IsTrackedCompilationError(diagnostic)) - { - continue; - } - - string errorDetailsFilename = diagnostic.Location.GetLineSpan().Path; - string errorDetailsUnresolvedMemberName = null; - string errorDetailsMethodName = null; - string errorDetailsLeftExpressionDocId = null; - string[] errorDetailsGenericArguments = null; - string[] errorDetailsArgumentTypes = null; - string[] errorDetailsLeftExpressionBaseTypeDocIds = null; - - TextSpan span = diagnostic.Location.SourceSpan; - - var node = root.FindNode(span); - if (node == null) - { - continue; - } - - // If the expression binds, this could just be an extension method so we will continue and not - // log, as it's not actually an error. - if (ExpressionBinds(node, semanticModel, cancellationToken, checkForExtensionMethods: true)) - { - continue; - } - // This is used to get unresolved member names. It will not alway find a member name, but has been tested to do so - // in the cases where the error code needs it. - syntaxFacts.GetNameAndArityOfSimpleName(node, out var name, out var arity); - errorDetailsUnresolvedMemberName = name; - - // Here we reuse the unresolved member name field for attribute classes that can't be resolved as - // actually being attributes. Could factor this into a separate field for readability later. - AttributeSyntax attributeSyntax = node as AttributeSyntax; - if (attributeSyntax != null) - { - errorDetailsUnresolvedMemberName = semanticModel.GetTypeInfo(attributeSyntax, cancellationToken).Type.GetDocumentationCommentId(); - } - - GenericNameSyntax genericNameSyntax = node as GenericNameSyntax; - if (genericNameSyntax != null) - { - List genericArgumentDocIds = new List(); - foreach (var genericArgument in genericNameSyntax.TypeArgumentList.Arguments) - { - var semanticInfo = semanticModel.GetTypeInfo(genericArgument, cancellationToken); - if (semanticInfo.Type != null) - { - genericArgumentDocIds.Add(GetDocId(semanticInfo.Type)); - } - else - { - genericArgumentDocIds.Add(UnknownGenericArgumentTypeName); - } - } - - errorDetailsGenericArguments = genericArgumentDocIds.ToArray(); - } - - ArgumentSyntax argumentSyntax = node as ArgumentSyntax; - if (argumentSyntax != null) - { - var argumentListSyntax = argumentSyntax.GetAncestor().Arguments; - var invocationExpression = argumentSyntax.GetAncestor(); - - errorDetailsArgumentTypes = (from argument in argumentListSyntax - select GetDocId(semanticModel.GetTypeInfo(argument.Expression, cancellationToken).Type)).ToArray(); - - if (invocationExpression != null) - { - var memberAccessExpression = invocationExpression.Expression as ExpressionSyntax; - var symbolInfo = semanticModel.GetSymbolInfo(memberAccessExpression, cancellationToken); - - if (symbolInfo.CandidateSymbols.Length > 0) - { - // In this case, there is argument mismatch of some sort. - // Here we are getting the method name of any candidate symbols, then - // getting the docid of the type where the argument mismatch happened and storing this in LeftExpressionDocId. - - errorDetailsMethodName = symbolInfo.CandidateSymbols.First().Name; - errorDetailsLeftExpressionDocId = GetDocId(symbolInfo.CandidateSymbols.First().ContainingType); - } - } - } - - if (syntaxFacts.IsSimpleMemberAccessExpression(node.Parent)) - { - var expression = node.Parent; - - var leftExpression = syntaxFacts.GetExpressionOfMemberAccessExpression(expression); - if (leftExpression != null) - { - var semanticInfo = semanticModel.GetTypeInfo(leftExpression, cancellationToken); - - var leftExpressionType = semanticInfo.Type; - if (leftExpressionType != null) - { - errorDetailsLeftExpressionDocId = GetDocId(leftExpressionType); - - IEnumerable baseTypeDocids = leftExpressionType.GetBaseTypes().Select(t => GetDocId(t)); - errorDetailsLeftExpressionBaseTypeDocIds = baseTypeDocids.ToArray(); - } - } - } - - ret.Add(new CompilationErrorDetails(diagnostic.Id, errorDetailsFilename, errorDetailsMethodName, errorDetailsUnresolvedMemberName, - errorDetailsLeftExpressionDocId, errorDetailsLeftExpressionBaseTypeDocIds, errorDetailsGenericArguments, errorDetailsArgumentTypes)); - } - - return ret; - } - catch (Exception e) - { - List ret = new List(); - ret.Add(new CompilationErrorDetails("EXCEPTION", e.Message, e.StackTrace, null, null, null, null, null)); - return ret; - } - } - - private string GetDocId(ISymbol symbol) - { - if (symbol == null) - { - return UnknownSymbolName; - } - - if (symbol is INamedTypeSymbol) - { - var typeSymbol = (INamedTypeSymbol)symbol; - if (typeSymbol.IsGenericType && typeSymbol.OriginalDefinition != null) - { - return typeSymbol.OriginalDefinition.GetDocumentationCommentId(); - } - } - else if (symbol is IMethodSymbol) - { - var methodSymbol = (IMethodSymbol)symbol; - if (methodSymbol.IsGenericMethod && methodSymbol.OriginalDefinition != null) - { - return methodSymbol.OriginalDefinition.GetDocumentationCommentId(); - } - } - - return symbol.GetDocumentationCommentId(); - } - - private bool IsTrackedCompilationError(Diagnostic diagnostic) - { - return diagnostic.Id == CS0103 || - diagnostic.Id == CS0246 || - diagnostic.Id == CS0305 || - diagnostic.Id == CS0308 || - diagnostic.Id == CS0616 || - diagnostic.Id == CS1061 || - diagnostic.Id == CS1503 || - diagnostic.Id == CS1935; - } - - private bool ExpressionBinds(SyntaxNode expression, SemanticModel semanticModel, CancellationToken cancellationToken, bool checkForExtensionMethods = false) - { - // See if the name binds to something other then the error type. If it does, there's nothing further we need to do. - // For extension methods, however, we will continue to search if there exists any better matched method. - cancellationToken.ThrowIfCancellationRequested(); - var symbolInfo = semanticModel.GetSymbolInfo(expression, cancellationToken); - if (symbolInfo.CandidateReason == CandidateReason.OverloadResolutionFailure && !checkForExtensionMethods) - { - return true; - } - - return symbolInfo.Symbol != null; - } - } -} diff --git a/src/VisualStudio/CSharp/Impl/Telemetry/CompilationErrorDetails.cs b/src/VisualStudio/CSharp/Impl/Telemetry/CompilationErrorDetails.cs deleted file mode 100644 index 703c56994dd710ab3bb94a91ad57c9ae5836810f..0000000000000000000000000000000000000000 --- a/src/VisualStudio/CSharp/Impl/Telemetry/CompilationErrorDetails.cs +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Internal.VisualStudio.Shell; -using Microsoft.Internal.VisualStudio.Shell.Interop; -using Roslyn.Utilities; - -namespace Microsoft.VisualStudio.LanguageServices.Telemetry -{ - internal struct CompilationErrorDetails : IEquatable - { - public CompilationErrorDetails(string errorId, string fileName, string methodName, string unresolvedMemberName, - string leftExpressionDocId, string[] leftExpressionBaseTypeDocIds, string[] genericArguments, string[] argumentTypes) - { - ErrorId = errorId; - Filename = fileName; - MethodName = methodName; - UnresolvedMemberName = unresolvedMemberName; - LeftExpressionDocId = leftExpressionDocId; - LeftExpressionBaseTypeDocIds = leftExpressionBaseTypeDocIds; - GenericArguments = genericArguments; - ArgumentTypes = argumentTypes; - _hashCode = null; - } - - public readonly string Filename; - public readonly string ErrorId; - public readonly string MethodName; - public readonly string UnresolvedMemberName; - public readonly string LeftExpressionDocId; - public readonly string[] LeftExpressionBaseTypeDocIds; - public readonly string[] GenericArguments; - public readonly string[] ArgumentTypes; - - private int? _hashCode; - - public override int GetHashCode() - { - if (_hashCode.HasValue) - { - return _hashCode.Value; - } - - _hashCode = Hash.Combine(Filename, - Hash.Combine(ErrorId, - Hash.Combine(MethodName, - Hash.Combine(UnresolvedMemberName, - Hash.Combine(LeftExpressionDocId, - Hash.CombineValues(LeftExpressionBaseTypeDocIds, - Hash.CombineValues(GenericArguments, - Hash.CombineValues(ArgumentTypes, 0)))))))); - - return _hashCode.Value; - } - - public override bool Equals(object obj) - { - if (obj is CompilationErrorDetails) - { - return Equals((CompilationErrorDetails)obj); - } - - return base.Equals(obj); - } - - public bool Equals(CompilationErrorDetails other) - { - // Avoid string comparisons unless the hashcodes match - if (GetHashCode() != other.GetHashCode()) - { - return false; - } - - return Filename == other.Filename && - ErrorId == other.ErrorId && - MethodName == other.MethodName && - UnresolvedMemberName == other.UnresolvedMemberName && - LeftExpressionDocId == other.LeftExpressionDocId && - SameStringArray(LeftExpressionBaseTypeDocIds, other.LeftExpressionBaseTypeDocIds) && - SameStringArray(GenericArguments, other.GenericArguments) && - SameStringArray(ArgumentTypes, other.ArgumentTypes); - } - - private static bool SameStringArray(string[] stringArray1, string[] stringArray2) - { - if (stringArray1 == null && stringArray2 == null) - { - return true; - } - else if (stringArray1 == null || stringArray2 == null) - { - return false; - } - - if (stringArray1.Length != stringArray2.Length) - { - return false; - } - - for (int i = 0; i < stringArray1.Length; i++) - { - if (stringArray1[i] != stringArray2[i]) - { - return false; - } - } - - return true; - } - } -} diff --git a/src/VisualStudio/Core/Def/Implementation/CompilationErrorTelemetry/CompilationErrorTelemetryIncrementalAnalyzer.cs b/src/VisualStudio/Core/Def/Implementation/CompilationErrorTelemetry/CompilationErrorTelemetryIncrementalAnalyzer.cs deleted file mode 100644 index 40fd85d5d820df8a1ddaf94978791ec14725577c..0000000000000000000000000000000000000000 --- a/src/VisualStudio/Core/Def/Implementation/CompilationErrorTelemetry/CompilationErrorTelemetryIncrementalAnalyzer.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Composition; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.SolutionCrawler; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.CompilationErrorTelemetry -{ - // Disabled compilation error telemetry per discussion with .net team. - // tracking bug - https://github.com/dotnet/roslyn/issues/11133 - // [ExportIncrementalAnalyzerProvider(WorkspaceKind.Host), Shared] - internal class CompilationErrorTelemetryIncrementalAnalyzer : IncrementalAnalyzerProviderBase - { - public const string Name = "CompilationErrorTelemetryIncrementalAnalyzer"; - - [ImportingConstructor] - public CompilationErrorTelemetryIncrementalAnalyzer( - [ImportMany] IEnumerable> perLanguageProviders) : - base(Name, perLanguageProviders) - { - } - } -} diff --git a/src/VisualStudio/Core/Def/ServicesVisualStudio.csproj b/src/VisualStudio/Core/Def/ServicesVisualStudio.csproj index f36dab656d30d2ed18f53daa8a16be9896f71f13..7927ee48df87b3353936294240460d5bd3553364 100644 --- a/src/VisualStudio/Core/Def/ServicesVisualStudio.csproj +++ b/src/VisualStudio/Core/Def/ServicesVisualStudio.csproj @@ -57,7 +57,6 @@ -