Пример #1
0
        /// <summary>
        /// Invoked by <see cref="InteractiveHost"/> when a new process is being started.
        /// </summary>
        private void ProcessStarting(bool initialize)
        {
            var textView = GetCurrentWindowOrThrow().TextView;

            var dispatcher = ((FrameworkElement)textView).Dispatcher;
            if (!dispatcher.CheckAccess())
            {
                dispatcher.BeginInvoke(new Action(() => ProcessStarting(initialize)));
                return;
            }

            // Freeze all existing classifications and then clear the list of submission buffers we have.
            _submissionBuffers.Remove(_currentSubmissionBuffer); // if present
            foreach (var textBuffer in _submissionBuffers)
            {
                InertClassifierProvider.CaptureExistingClassificationSpans(_classifierAggregator, textView, textBuffer);
            }
            _submissionBuffers.Clear();

            // We always start out empty
            _workspace.ClearSolution();
            _currentSubmissionProjectId = null;
            _previousSubmissionProjectId = null;

            var metadataService = _workspace.CurrentSolution.Services.MetadataService;
            var mscorlibRef = metadataService.GetReference(typeof(object).Assembly.Location, MetadataReferenceProperties.Assembly);
            var interactiveHostObjectRef = metadataService.GetReference(typeof(InteractiveScriptGlobals).Assembly.Location, Script.HostAssemblyReferenceProperties);

            _responseFileReferences = ImmutableArray.Create<MetadataReference>(mscorlibRef, interactiveHostObjectRef);
            _responseFileImports = ImmutableArray<string>.Empty;
            _initialScriptFileOpt = null;
            ReferenceSearchPaths = ImmutableArray<string>.Empty;
            SourceSearchPaths = ImmutableArray<string>.Empty;

            if (initialize && File.Exists(_responseFilePath))
            {
                // The base directory for relative paths is the directory that contains the .rsp file.
                // Note that .rsp files included by this .rsp file will share the base directory (Dev10 behavior of csc/vbc).
                var responseFileDirectory = Path.GetDirectoryName(_responseFilePath);
                var args = this.CommandLineParser.Parse(new[] { "@" + _responseFilePath }, responseFileDirectory, RuntimeEnvironment.GetRuntimeDirectory(), null);

                if (args.Errors.Length == 0)
                {
                    var metadataResolver = CreateMetadataReferenceResolver(metadataService, args.ReferencePaths, responseFileDirectory);
                    var sourceResolver = CreateSourceReferenceResolver(args.SourcePaths, responseFileDirectory);

                    // ignore unresolved references, they will be reported in the interactive window:
                    var responseFileReferences = args.ResolveMetadataReferences(metadataResolver).Where(r => !(r is UnresolvedMetadataReference));

                    _initialScriptFileOpt = args.SourceFiles.IsEmpty ? null : args.SourceFiles[0].Path;

                    ReferenceSearchPaths = args.ReferencePaths;
                    SourceSearchPaths = args.SourcePaths;

                    _responseFileReferences = _responseFileReferences.AddRange(responseFileReferences);
                    _responseFileImports = CommandLineHelpers.GetImports(args);
                }
            }

            _metadataReferenceResolver = CreateMetadataReferenceResolver(metadataService, ReferenceSearchPaths, _initialWorkingDirectory);
            _sourceReferenceResolver = CreateSourceReferenceResolver(SourceSearchPaths, _initialWorkingDirectory);

            // create the first submission project in the workspace after reset:
            if (_currentSubmissionBuffer != null)
            {
                AddSubmission(_currentSubmissionBuffer, this.LanguageName);
            }
        }
Пример #2
0
 protected override void AddTrackedEntities(ImmutableArray <AnalysisEntity> .Builder builder) => builder.AddRange(CurrentAnalysisData.Keys);
Пример #3
0
        private static void AddNonLocalDiagnostics(
            ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>> nonLocalDiagnostics,
            ImmutableHashSet<DiagnosticAnalyzer> excludedAnalyzers,
            ImmutableArray<Diagnostic>.Builder builder)
        {
            foreach (var diagnosticsByAnalyzer in nonLocalDiagnostics)
            {
                if (excludedAnalyzers.Contains(diagnosticsByAnalyzer.Key))
                {
                    continue;
                }

                builder.AddRange(diagnosticsByAnalyzer.Value);
            }
        }
Пример #4
0
        private async Task <DiagnosticFixResult> FixDiagnosticsAsync(
            DiagnosticDescriptor descriptor,
            ImmutableArray <DiagnosticAnalyzer> analyzers,
            ImmutableArray <CodeFixProvider> fixers,
            Project project,
            CancellationToken cancellationToken)
        {
            ImmutableArray <Diagnostic> .Builder fixedDiagnostics = ImmutableArray.CreateBuilder <Diagnostic>();

            ImmutableArray <Diagnostic> diagnostics              = ImmutableArray <Diagnostic> .Empty;
            ImmutableArray <Diagnostic> previousDiagnostics      = ImmutableArray <Diagnostic> .Empty;
            ImmutableArray <Diagnostic> previousDiagnosticsToFix = ImmutableArray <Diagnostic> .Empty;

            int length  = 0;
            var fixKind = DiagnosticFixKind.NotFixed;

            while (true)
            {
                Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                ImmutableArray <Diagnostic> compilerDiagnostics = compilation.GetDiagnostics(cancellationToken);

                if (!VerifyCompilerDiagnostics(compilerDiagnostics, project))
                {
                    fixKind = DiagnosticFixKind.CompilerError;

                    if (!previousDiagnostics.Any())
                    {
                        break;
                    }
                }

                if (analyzers.IsDefault)
                {
                    diagnostics = compilerDiagnostics;
                }
                else
                {
                    diagnostics = await GetAnalyzerDiagnosticsAsync(compilation, analyzers, project.AnalyzerOptions, cancellationToken).ConfigureAwait(false);
                }

                diagnostics = diagnostics
                              .Where(f => f.Id == descriptor.Id && f.Severity >= Options.SeverityLevel)
                              .ToImmutableArray();

                if (fixKind == DiagnosticFixKind.CompilerError)
                {
                    break;
                }
                else if (fixKind == DiagnosticFixKind.Success)
                {
                    if (Options.BatchSize <= 0 ||
                        length <= Options.BatchSize)
                    {
                        break;
                    }
                }
                else if (previousDiagnostics.Any() &&
                         fixKind != DiagnosticFixKind.PartiallyFixed)
                {
                    break;
                }

                length = diagnostics.Length;

                if (length == 0)
                {
                    break;
                }

                if (length == previousDiagnostics.Length &&
                    !diagnostics.Except(previousDiagnostics, DiagnosticDeepEqualityComparer.Instance).Any())
                {
                    break;
                }

                fixedDiagnostics.AddRange(previousDiagnosticsToFix.Except(diagnostics, DiagnosticDeepEqualityComparer.Instance));

                previousDiagnostics = diagnostics;

                if (Options.FixAllScope == FixAllScope.Document)
                {
                    foreach (IGrouping <SyntaxTree, Diagnostic> grouping in diagnostics
                             .GroupBy(f => f.Location.SourceTree)
                             .OrderByDescending(f => f.Count()))
                    {
                        IEnumerable <Diagnostic> syntaxTreeDiagnostics = grouping.AsEnumerable();

                        if (Options.BatchSize > 0)
                        {
                            syntaxTreeDiagnostics = syntaxTreeDiagnostics.Take(Options.BatchSize);
                        }

                        ImmutableArray <Diagnostic> diagnosticsCandidate = syntaxTreeDiagnostics.ToImmutableArray();

                        DiagnosticFixKind fixKindCandidate = await FixDiagnosticsAsync(diagnosticsCandidate, descriptor, fixers, project, cancellationToken).ConfigureAwait(false);

                        if (fixKindCandidate == DiagnosticFixKind.Success ||
                            fixKindCandidate == DiagnosticFixKind.PartiallyFixed)
                        {
                            diagnostics = diagnosticsCandidate;
                            fixKind     = fixKindCandidate;
                            break;
                        }
                    }
                }
                else
                {
                    if (Options.BatchSize > 0 &&
                        length > Options.BatchSize)
                    {
                        diagnostics = ImmutableArray.CreateRange(diagnostics, 0, Options.BatchSize, f => f);
                    }

                    fixKind = await FixDiagnosticsAsync(diagnostics, descriptor, fixers, project, cancellationToken).ConfigureAwait(false);
                }

                previousDiagnosticsToFix = diagnostics;

                project = CurrentSolution.GetProject(project.Id);
            }

            fixedDiagnostics.AddRange(previousDiagnosticsToFix.Except(diagnostics, DiagnosticDeepEqualityComparer.Instance));

            return(new DiagnosticFixResult(fixKind, fixedDiagnostics.ToImmutableArray()));
        }
Пример #5
0
        private async Task <DiagnosticFixResult> FixDiagnosticsAsync(
            DiagnosticDescriptor descriptor,
            ImmutableArray <DiagnosticAnalyzer> analyzers,
            ImmutableArray <CodeFixProvider> fixers,
            Project project,
            CancellationToken cancellationToken)
        {
            ImmutableArray <Diagnostic> .Builder fixedDiagostics = ImmutableArray.CreateBuilder <Diagnostic>();

            ImmutableArray <Diagnostic> diagnostics              = ImmutableArray <Diagnostic> .Empty;
            ImmutableArray <Diagnostic> previousDiagnostics      = ImmutableArray <Diagnostic> .Empty;
            ImmutableArray <Diagnostic> previousDiagnosticsToFix = ImmutableArray <Diagnostic> .Empty;

            int length  = 0;
            var fixKind = DiagnosticFixKind.NotFixed;

            while (true)
            {
                Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                ImmutableArray <Diagnostic> compilerDiagnostics = compilation.GetDiagnostics(cancellationToken);

                if (!VerifyCompilerDiagnostics(compilerDiagnostics, project))
                {
                    fixKind = DiagnosticFixKind.CompilerError;

                    if (!previousDiagnostics.Any())
                    {
                        break;
                    }
                }

                if (analyzers.IsDefault)
                {
                    diagnostics = compilerDiagnostics;
                }
                else
                {
                    diagnostics = await compilation.GetAnalyzerDiagnosticsAsync(analyzers, Options.CompilationWithAnalyzersOptions, cancellationToken).ConfigureAwait(false);
                }

                diagnostics = diagnostics
                              .Where(f => f.Id == descriptor.Id && f.Severity >= Options.SeverityLevel)
                              .ToImmutableArray();

                if (fixKind == DiagnosticFixKind.CompilerError)
                {
                    break;
                }
                else if (fixKind == DiagnosticFixKind.Success)
                {
                    if (Options.BatchSize <= 0 ||
                        length <= Options.BatchSize)
                    {
                        break;
                    }
                }
                else if (previousDiagnostics.Any() &&
                         fixKind != DiagnosticFixKind.PartiallyFixed)
                {
                    break;
                }

                length = diagnostics.Length;

                if (length == 0)
                {
                    break;
                }

                if (length == previousDiagnostics.Length &&
                    !diagnostics.Except(previousDiagnostics, DiagnosticDeepEqualityComparer.Instance).Any())
                {
                    break;
                }

                fixedDiagostics.AddRange(previousDiagnosticsToFix.Except(diagnostics, DiagnosticDeepEqualityComparer.Instance));

                previousDiagnostics = diagnostics;

                if (Options.BatchSize > 0 &&
                    length > Options.BatchSize)
                {
                    diagnostics = ImmutableArray.CreateRange(diagnostics, 0, Options.BatchSize, f => f);
                }

                fixKind = await FixDiagnosticsAsync(diagnostics, descriptor, fixers, project, cancellationToken).ConfigureAwait(false);

                previousDiagnosticsToFix = diagnostics;

                project = CurrentSolution.GetProject(project.Id);
            }

            fixedDiagostics.AddRange(previousDiagnosticsToFix.Except(diagnostics, DiagnosticDeepEqualityComparer.Instance));

            return(new DiagnosticFixResult(fixKind, fixedDiagostics.ToImmutableArray()));
        }
Пример #6
0
 public static void AddRangeAsBuilders <TCore, TBuilder>(this ImmutableArray <TBuilder> .Builder builders, ImmutableArray <TCore> cores)
     where TCore : IBuildable <TCore, TBuilder>
     where TBuilder : IBuilder <TCore>
 {
     builders.AddRange(cores.Select(x => x.ToBuilder()));
 }
        private void ResolveAndBindMissingAssemblies(
            TCompilation compilation,
            ImmutableArray <AssemblyData> explicitAssemblies,
            ImmutableArray <PEModule> explicitModules,
            ImmutableArray <MetadataReference> explicitReferences,
            ImmutableArray <ResolvedReference> explicitReferenceMap,
            MetadataReferenceResolver resolver,
            MetadataImportOptions importOptions,
            bool supersedeLowerVersions,
            [In, Out] ArrayBuilder <AssemblyReferenceBinding[]> referenceBindings,
            [In, Out] Dictionary <string, List <ReferencedAssemblyIdentity> > assemblyReferencesBySimpleName,
            out ImmutableArray <AssemblyData> allAssemblies,
            out ImmutableArray <MetadataReference> metadataReferences,
            out ImmutableArray <ResolvedReference> resolvedReferences,
            DiagnosticBag resolutionDiagnostics)
        {
            Debug.Assert(explicitAssemblies[0] is AssemblyDataForAssemblyBeingBuilt);
            Debug.Assert(referenceBindings.Count == explicitAssemblies.Length);
            Debug.Assert(explicitReferences.Length == explicitReferenceMap.Length);

            // -1 for assembly being built:
            int totalReferencedAssemblyCount = explicitAssemblies.Length - 1;

            var implicitAssemblies = ArrayBuilder <AssemblyData> .GetInstance();

            // tracks identities we already asked the resolver to resolve:
            var requestedIdentities = PooledHashSet <AssemblyIdentity> .GetInstance();

            PooledDictionary <AssemblyIdentity, PortableExecutableReference> previouslyResolvedAssembliesOpt = null;

            // Avoid resolving previously resolved missing references. If we call to the resolver again we would create new assembly symbols for them,
            // which would not match the previously created ones. As a result we would get duplicate PE types and conversion errors.
            var previousScriptCompilation = compilation.ScriptCompilationInfo?.PreviousScriptCompilation;

            if (previousScriptCompilation != null)
            {
                previouslyResolvedAssembliesOpt = PooledDictionary <AssemblyIdentity, PortableExecutableReference> .GetInstance();

                foreach (var entry in previousScriptCompilation.GetBoundReferenceManager().GetImplicitlyResolvedAssemblyReferences())
                {
                    previouslyResolvedAssembliesOpt.Add(entry.Key, entry.Value);
                }
            }

            var metadataReferencesBuilder = ArrayBuilder <MetadataReference> .GetInstance();

            Dictionary <MetadataReference, MergedAliases> lazyAliasMap = null;

            // metadata references and corresponding bindings of their references, used to calculate a fixed point:
            var referenceBindingsToProcess = ArrayBuilder <ValueTuple <MetadataReference, ArraySegment <AssemblyReferenceBinding> > > .GetInstance();

            // collect all missing identities, resolve the assemblies and bind their references against explicit definitions:
            GetInitialReferenceBindingsToProcess(explicitModules, explicitReferences, explicitReferenceMap, referenceBindings, totalReferencedAssemblyCount, referenceBindingsToProcess);

            // NB: includes the assembly being built:
            int explicitAssemblyCount = explicitAssemblies.Length;

            try
            {
                while (referenceBindingsToProcess.Count > 0)
                {
                    var referenceAndBindings = referenceBindingsToProcess.Pop();
                    var requestingReference  = referenceAndBindings.Item1;
                    var bindings             = referenceAndBindings.Item2;

                    foreach (var binding in bindings)
                    {
                        // only attempt to resolve unbound references (regardless of version difference of the bound ones)
                        if (binding.IsBound)
                        {
                            continue;
                        }

                        if (!requestedIdentities.Add(binding.ReferenceIdentity))
                        {
                            continue;
                        }

                        PortableExecutableReference resolvedReference;
                        if (previouslyResolvedAssembliesOpt == null || !previouslyResolvedAssembliesOpt.TryGetValue(binding.ReferenceIdentity, out resolvedReference))
                        {
                            resolvedReference = resolver.ResolveMissingAssembly(requestingReference, binding.ReferenceIdentity);
                            if (resolvedReference == null)
                            {
                                continue;
                            }
                        }

                        var data = ResolveMissingAssembly(binding.ReferenceIdentity, resolvedReference, importOptions, resolutionDiagnostics);
                        if (data == null)
                        {
                            continue;
                        }

                        // The resolver may return different version than we asked for, so it may happen that
                        // it returns the same identity for two different input identities (e.g. if a higher version
                        // of an assembly is available than what the assemblies reference: "A, v1" -> "A, v3" and "A, v2" -> "A, v3").
                        // If such case occurs merge the properties (aliases) of the resulting references in the same way we do
                        // during initial explicit references resolution.

                        // -1 for assembly being built:
                        int index = explicitAssemblyCount - 1 + metadataReferencesBuilder.Count;

                        var existingReference = TryAddAssembly(data.Identity, resolvedReference, index, resolutionDiagnostics, Location.None, assemblyReferencesBySimpleName, supersedeLowerVersions);
                        if (existingReference != null)
                        {
                            MergeReferenceProperties(existingReference, resolvedReference, resolutionDiagnostics, ref lazyAliasMap);
                            continue;
                        }

                        metadataReferencesBuilder.Add(resolvedReference);
                        implicitAssemblies.Add(data);

                        var referenceBinding = data.BindAssemblyReferences(explicitAssemblies, IdentityComparer);
                        referenceBindings.Add(referenceBinding);
                        referenceBindingsToProcess.Push(ValueTuple.Create((MetadataReference)resolvedReference, new ArraySegment <AssemblyReferenceBinding>(referenceBinding)));
                    }
                }

                if (implicitAssemblies.Count == 0)
                {
                    Debug.Assert(lazyAliasMap == null);

                    resolvedReferences = ImmutableArray <ResolvedReference> .Empty;
                    metadataReferences = ImmutableArray <MetadataReference> .Empty;
                    allAssemblies      = explicitAssemblies;
                    return;
                }

                // Rebind assembly references that were initially missing. All bindings established above
                // are against explicitly specified references.

                allAssemblies = explicitAssemblies.AddRange(implicitAssemblies);

                for (int bindingsIndex = 0; bindingsIndex < referenceBindings.Count; bindingsIndex++)
                {
                    var referenceBinding = referenceBindings[bindingsIndex];

                    for (int i = 0; i < referenceBinding.Length; i++)
                    {
                        var binding = referenceBinding[i];

                        // We don't rebind references bound to a non-matching version of a reference that was explicitly
                        // specified, even if we have a better version now.
                        if (binding.IsBound)
                        {
                            continue;
                        }

                        // We only need to resolve against implicitly resolved assemblies,
                        // since we already resolved against explicitly specified ones.
                        referenceBinding[i] = ResolveReferencedAssembly(
                            binding.ReferenceIdentity,
                            allAssemblies,
                            explicitAssemblyCount,
                            IdentityComparer);
                    }
                }

                UpdateBindingsOfAssemblyBeingBuilt(referenceBindings, explicitAssemblyCount, implicitAssemblies);

                metadataReferences = metadataReferencesBuilder.ToImmutable();
                resolvedReferences = ToResolvedAssemblyReferences(metadataReferences, lazyAliasMap, explicitAssemblyCount);
            }
            finally
            {
                implicitAssemblies.Free();
                requestedIdentities.Free();
                referenceBindingsToProcess.Free();
                metadataReferencesBuilder.Free();
                previouslyResolvedAssembliesOpt?.Free();
            }
        }
Пример #8
0
 private void Append(IEnumerable <byte> bytes) => _builder.AddRange(bytes);
Пример #9
0
 public static ImmutableArray <byte> AddRange(this ImmutableArray <byte> source, params int[] args)
 {
     return(source.AddRange(args.Select(i => Convert.ToByte(i))));
 }
Пример #10
0
        /// <summary>
        /// Invoked by <see cref="InteractiveHost"/> when a new process is being started.
        /// </summary>
        private void ProcessStarting(bool initialize)
        {
            var textView = GetCurrentWindowOrThrow().TextView;

            var dispatcher = ((FrameworkElement)textView).Dispatcher;

            if (!dispatcher.CheckAccess())
            {
                dispatcher.BeginInvoke(new Action(() => ProcessStarting(initialize)));
                return;
            }

            // Freeze all existing classifications and then clear the list of submission buffers we have.
            _submissionBuffers.Remove(_currentSubmissionBuffer); // if present
            foreach (var textBuffer in _submissionBuffers)
            {
                InertClassifierProvider.CaptureExistingClassificationSpans(_classifierAggregator, textView, textBuffer);
            }
            _submissionBuffers.Clear();

            // We always start out empty
            _workspace.ClearSolution();
            _currentSubmissionProjectId  = null;
            _previousSubmissionProjectId = null;

            var metadataService          = _workspace.CurrentSolution.Services.MetadataService;
            var mscorlibRef              = metadataService.GetReference(typeof(object).Assembly.Location, MetadataReferenceProperties.Assembly);
            var interactiveHostObjectRef = metadataService.GetReference(typeof(InteractiveScriptGlobals).Assembly.Location, Script.HostAssemblyReferenceProperties);

            _responseFileReferences = ImmutableArray.Create <MetadataReference>(mscorlibRef, interactiveHostObjectRef);
            _responseFileImports    = ImmutableArray <string> .Empty;
            _initialScriptFileOpt   = null;
            ReferenceSearchPaths    = ImmutableArray <string> .Empty;
            SourceSearchPaths       = ImmutableArray <string> .Empty;

            if (initialize && File.Exists(_responseFilePath))
            {
                // The base directory for relative paths is the directory that contains the .rsp file.
                // Note that .rsp files included by this .rsp file will share the base directory (Dev10 behavior of csc/vbc).
                var responseFileDirectory = Path.GetDirectoryName(_responseFilePath);
                var args = this.CommandLineParser.Parse(new[] { "@" + _responseFilePath }, responseFileDirectory, RuntimeEnvironment.GetRuntimeDirectory(), null);

                if (args.Errors.Length == 0)
                {
                    var metadataResolver = CreateMetadataReferenceResolver(metadataService, args.ReferencePaths, responseFileDirectory);
                    var sourceResolver   = CreateSourceReferenceResolver(args.SourcePaths, responseFileDirectory);

                    // ignore unresolved references, they will be reported in the interactive window:
                    var responseFileReferences = args.ResolveMetadataReferences(metadataResolver).Where(r => !(r is UnresolvedMetadataReference));

                    _initialScriptFileOpt = args.SourceFiles.IsEmpty ? null : args.SourceFiles[0].Path;

                    ReferenceSearchPaths = args.ReferencePaths;
                    SourceSearchPaths    = args.SourcePaths;

                    _responseFileReferences = _responseFileReferences.AddRange(responseFileReferences);
                    _responseFileImports    = CommandLineHelpers.GetImports(args);
                }
            }

            _metadataReferenceResolver = CreateMetadataReferenceResolver(metadataService, ReferenceSearchPaths, _initialWorkingDirectory);
            _sourceReferenceResolver   = CreateSourceReferenceResolver(SourceSearchPaths, _initialWorkingDirectory);

            // create the first submission project in the workspace after reset:
            if (_currentSubmissionBuffer != null)
            {
                AddSubmission(_currentSubmissionBuffer, this.LanguageName);
            }
        }
Пример #11
0
        /// <summary>
        /// Append analyzer actions from <paramref name="otherActions"/> to actions from this instance.
        /// </summary>
        /// <param name="otherActions">Analyzer actions to append</param>.
        public AnalyzerActions Append(AnalyzerActions otherActions, bool appendSymbolStartAndSymbolEndActions = true)
        {
            if (otherActions == null)
            {
                throw new ArgumentNullException(nameof(otherActions));
            }

            AnalyzerActions actions = new AnalyzerActions();

            actions._compilationStartActions    = _compilationStartActions.AddRange(otherActions._compilationStartActions);
            actions._compilationEndActions      = _compilationEndActions.AddRange(otherActions._compilationEndActions);
            actions._compilationActions         = _compilationActions.AddRange(otherActions._compilationActions);
            actions._syntaxTreeActions          = _syntaxTreeActions.AddRange(otherActions._syntaxTreeActions);
            actions._semanticModelActions       = _semanticModelActions.AddRange(otherActions._semanticModelActions);
            actions._symbolActions              = _symbolActions.AddRange(otherActions._symbolActions);
            actions._symbolStartActions         = appendSymbolStartAndSymbolEndActions ? _symbolStartActions.AddRange(otherActions._symbolStartActions) : _symbolStartActions;
            actions._symbolEndActions           = appendSymbolStartAndSymbolEndActions ? _symbolEndActions.AddRange(otherActions._symbolEndActions) : _symbolEndActions;
            actions._codeBlockStartActions      = _codeBlockStartActions.AddRange(otherActions._codeBlockStartActions);
            actions._codeBlockEndActions        = _codeBlockEndActions.AddRange(otherActions._codeBlockEndActions);
            actions._codeBlockActions           = _codeBlockActions.AddRange(otherActions._codeBlockActions);
            actions._syntaxNodeActions          = _syntaxNodeActions.AddRange(otherActions._syntaxNodeActions);
            actions._operationActions           = _operationActions.AddRange(otherActions._operationActions);
            actions._operationBlockStartActions = _operationBlockStartActions.AddRange(otherActions._operationBlockStartActions);
            actions._operationBlockEndActions   = _operationBlockEndActions.AddRange(otherActions._operationBlockEndActions);
            actions._operationBlockActions      = _operationBlockActions.AddRange(otherActions._operationBlockActions);
            actions._concurrent = actions._concurrent || otherActions.Concurrent;
            actions.IsEmpty     = IsEmpty && otherActions.IsEmpty;

            return(actions);
        }
Пример #12
0
            private static ImmutableArray <ImmutableArray <string> > FindCandidateFolders(
                FolderInfo currentFolderInfo,
                ImmutableArray <string> parts,
                ImmutableArray <string> currentFolder
                )
            {
                if (parts.IsEmpty)
                {
                    return(ImmutableArray.Create(currentFolder));
                }

                // Try to figure out all possible folder names that can match the target namespace.
                // For example, if the target is "A.B.C", then the matching folder names include
                // "A", "A.B" and "A.B.C". The item "index" in the result tuple is the number
                // of items in namespace parts used to construct iten "foldername".
                var candidates = Enumerable
                                 .Range(1, parts.Length)
                                 .Select(i => (foldername: string.Join(".", parts.Take(i)), index: i))
                                 .ToImmutableDictionary(t => t.foldername, t => t.index, PathUtilities.Comparer);

                var subFolders = currentFolderInfo.ChildFolders;

                var builder = ArrayBuilder <ImmutableArray <string> > .GetInstance();

                foreach (var(folderName, index) in candidates)
                {
                    if (subFolders.TryGetValue(folderName, out var matchingFolderInfo))
                    {
                        var newParts =
                            index >= parts.Length
                                ? ImmutableArray <string> .Empty
                                : ImmutableArray.Create(parts, index, parts.Length - index);
                        var newCurrentFolder = currentFolder.Add(matchingFolderInfo.Name);
                        builder.AddRange(
                            FindCandidateFolders(matchingFolderInfo, newParts, newCurrentFolder)
                            );
                    }
                }

                // Make sure we always have the default path as an available option to the user
                // (which might have been found by the search above, therefore the check here)
                // For example, if the target namespace is "A.B.C.D", and there's folder <ROOT>\A.B\,
                // the search above would only return "<ROOT>\A.B\C\D". We'd want to provide
                // "<ROOT>\A\B\C\D" as the default path.
                var defaultPathBasedOnCurrentFolder = currentFolder.AddRange(parts);

                if (
                    builder.All(
                        folders =>
                        !folders.SequenceEqual(
                            defaultPathBasedOnCurrentFolder,
                            PathUtilities.Comparer
                            )
                        )
                    )
                {
                    builder.Add(defaultPathBasedOnCurrentFolder);
                }

                return(builder.ToImmutableAndFree());
            }
        private void ResolveAndBindMissingAssemblies(
            ImmutableArray <AssemblyData> explicitAssemblies,
            MetadataReferenceResolver resolver,
            MetadataImportOptions importOptions,
            [In, Out] ArrayBuilder <AssemblyReferenceBinding[]> referenceBindings,
            out ImmutableArray <AssemblyData> allAssemblies,
            out ImmutableArray <MetadataReference> metadataReferences,
            out ImmutableArray <ResolvedReference> resolvedReferences,
            DiagnosticBag resolutionDiagnostics)
        {
            Debug.Assert(explicitAssemblies[0] is AssemblyDataForAssemblyBeingBuilt);

            var implicitAssemblies = ArrayBuilder <AssemblyData> .GetInstance();

            // tracks identities we already asked the resolver to resolve:
            var requestedIdentities = PooledHashSet <AssemblyIdentity> .GetInstance();

            // reference bindings of implicit assemblies, used to calculate a fixed point:
            var referenceBindingsToProcess = ArrayBuilder <AssemblyReferenceBinding[]> .GetInstance();

            var metadataReferencesBuilder = ArrayBuilder <MetadataReference> .GetInstance();

            Dictionary <string, List <ReferencedAssemblyIdentity> > lazyResolvedReferencesBySimpleName = null;
            Dictionary <MetadataReference, ArrayBuilder <string> >  lazyAliasMap = null;

            try
            {
                // collect all missing identities, resolve the assemblies and bind their references against explicit definitions:
                referenceBindingsToProcess.AddRange(referenceBindings);

                while (referenceBindingsToProcess.Count > 0)
                {
                    foreach (var binding in referenceBindingsToProcess.Pop())
                    {
                        // only attempt to resolve unbound references (regardless of version difference of the bound ones)
                        if (binding.IsBound)
                        {
                            continue;
                        }

                        if (!requestedIdentities.Add(binding.ReferenceIdentity))
                        {
                            continue;
                        }

                        var peReference = resolver.ResolveMissingAssembly(binding.ReferenceIdentity);
                        if (peReference == null)
                        {
                            continue;
                        }

                        var data = ResolveMissingAssembly(binding.ReferenceIdentity, peReference, importOptions, resolutionDiagnostics);
                        if (data == null)
                        {
                            continue;
                        }

                        // The resolver may return different version than we asked for, so it may happen that
                        // it returns the same identity for two different input identities (e.g. if a higher version
                        // of an assembly is available than what the assemblies reference: "A, v1" -> "A, v3" and "A, v2" -> "A, v3").
                        // If such case occurs merge the properties (aliases) of the resulting references in the same way we do
                        // during initial explicit references resolution.

                        var existingReference = TryAddAssembly(data.Identity, peReference, resolutionDiagnostics, Location.None, ref lazyResolvedReferencesBySimpleName);
                        if (existingReference != null)
                        {
                            MergeReferenceProperties(existingReference, peReference, resolutionDiagnostics, ref lazyAliasMap);
                            continue;
                        }

                        metadataReferencesBuilder.Add(peReference);
                        implicitAssemblies.Add(data);

                        var referenceBinding = data.BindAssemblyReferences(explicitAssemblies, IdentityComparer);
                        referenceBindings.Add(referenceBinding);
                        referenceBindingsToProcess.Push(referenceBinding);
                    }
                }

                if (implicitAssemblies.Count == 0)
                {
                    Debug.Assert(lazyAliasMap == null);
                    Debug.Assert(lazyResolvedReferencesBySimpleName == null);

                    resolvedReferences = ImmutableArray <ResolvedReference> .Empty;
                    metadataReferences = ImmutableArray <MetadataReference> .Empty;
                    allAssemblies      = explicitAssemblies;
                    return;
                }

                // Rebind assembly references that were initially missing. All bindings established above
                // are against explicitly specified references.

                // NB: includes the assembly being built:
                int explicitAssemblyCount = explicitAssemblies.Length;
                allAssemblies = explicitAssemblies.AddRange(implicitAssemblies);

                for (int bindingsIndex = 0; bindingsIndex < referenceBindings.Count; bindingsIndex++)
                {
                    var referenceBinding = referenceBindings[bindingsIndex];

                    for (int i = 0; i < referenceBinding.Length; i++)
                    {
                        var binding = referenceBinding[i];

                        // We don't rebind references bound to a non-matching version of a reference that was explicitly
                        // specified, even if we have a better version now.
                        if (binding.IsBound)
                        {
                            continue;
                        }

                        // We only need to resolve against implicitly resolved assemblies,
                        // since we already resolved against explicitly specified ones.
                        referenceBinding[i] = ResolveReferencedAssembly(
                            binding.ReferenceIdentity,
                            allAssemblies,
                            explicitAssemblyCount,
                            IdentityComparer);
                    }
                }

                UpdateBindingsOfAssemblyBeingBuilt(referenceBindings, explicitAssemblyCount, implicitAssemblies);

                metadataReferences = metadataReferencesBuilder.ToImmutable();
                resolvedReferences = ToResolvedAssemblyReferences(metadataReferences, lazyAliasMap, explicitAssemblyCount);
            }
            finally
            {
                implicitAssemblies.Free();
                requestedIdentities.Free();
                referenceBindingsToProcess.Free();
                metadataReferencesBuilder.Free();
            }
        }
Пример #14
0
        public static ImmutableArray <SymbolDisplayPart> GetDisplayParts(
            ISymbol symbol,
            SymbolDisplayFormat format,
            SymbolDisplayTypeDeclarationOptions typeDeclarationOptions = SymbolDisplayTypeDeclarationOptions.None,
            Func <INamedTypeSymbol, bool> isVisibleAttribute           = null,
            bool formatBaseList            = false,
            bool formatConstraints         = false,
            bool formatParameters          = false,
            bool splitAttributes           = true,
            bool includeAttributeArguments = false,
            bool omitIEnumerable           = false,
            bool useNameOnlyIfPossible     = false)
        {
            ImmutableArray <SymbolDisplayPart> parts;

            if (symbol is INamedTypeSymbol typeSymbol)
            {
                parts = typeSymbol.ToDisplayParts(format, typeDeclarationOptions);
            }
            else
            {
                parts      = symbol.ToDisplayParts(format);
                typeSymbol = null;
            }

            ImmutableArray <AttributeData> attributes = ImmutableArray <AttributeData> .Empty;
            bool hasAttributes = false;

            if (isVisibleAttribute != null)
            {
                attributes = symbol.GetAttributes();

                hasAttributes = attributes.Any(f => isVisibleAttribute(f.AttributeClass));
            }

            int baseListCount         = 0;
            INamedTypeSymbol baseType = null;
            ImmutableArray <INamedTypeSymbol> interfaces = default;

            if (typeSymbol != null)
            {
                if (typeSymbol.TypeKind.Is(TypeKind.Class, TypeKind.Interface))
                {
                    baseType = typeSymbol.BaseType;

                    if (baseType?.SpecialType == SpecialType.System_Object)
                    {
                        baseType = null;
                    }
                }

                interfaces = typeSymbol.Interfaces;

                if (omitIEnumerable &&
                    interfaces.Any(f => f.OriginalDefinition.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T))
                {
                    interfaces = interfaces.RemoveAll(f => f.SpecialType == SpecialType.System_Collections_IEnumerable);
                }

                baseListCount = interfaces.Length;

                if (baseType != null)
                {
                    baseListCount++;
                }
            }

            int constraintCount = 0;
            int whereIndex      = -1;

            for (int i = 0; i < parts.Length; i++)
            {
                if (parts[i].IsKeyword("where"))
                {
                    if (whereIndex == -1)
                    {
                        whereIndex = i;
                    }

                    constraintCount++;
                }
            }

            if (!hasAttributes &&
                baseListCount == 0 &&
                constraintCount == 0 &&
                (!formatParameters || symbol.GetParameters().Length <= 1))
            {
                return(parts);
            }

            INamespaceSymbol containingNamespace = (useNameOnlyIfPossible) ? symbol.ContainingNamespace : null;

            ImmutableArray <SymbolDisplayPart> .Builder builder = ImmutableArray.CreateBuilder <SymbolDisplayPart>(parts.Length);

            AddAttributes(builder, attributes, isVisibleAttribute, containingNamespace, splitAttributes: splitAttributes, includeAttributeArguments: includeAttributeArguments);

            if (baseListCount > 0)
            {
                if (whereIndex != -1)
                {
                    builder.AddRange(parts, whereIndex);
                }
                else
                {
                    builder.AddRange(parts);
                    builder.AddSpace();
                }

                builder.AddPunctuation(":");
                builder.AddSpace();

                if (baseType != null)
                {
                    builder.AddDisplayParts(baseType, containingNamespace);

                    if (interfaces.Any())
                    {
                        builder.AddPunctuation(",");

                        if (formatBaseList)
                        {
                            builder.AddLineBreak();
                            builder.AddIndentation();
                        }
                        else
                        {
                            builder.AddSpace();
                        }
                    }
                }

                interfaces = interfaces.Sort((x, y) =>
                {
                    INamespaceSymbol n1 = x.ContainingNamespace;
                    INamespaceSymbol n2 = y.ContainingNamespace;

                    if (!MetadataNameEqualityComparer <INamespaceSymbol> .Instance.Equals(n1, n2))
                    {
                        return(string.CompareOrdinal(
                                   n1.ToDisplayString(SymbolDisplayFormats.TypeNameAndContainingTypesAndNamespaces),
                                   n2.ToDisplayString(SymbolDisplayFormats.TypeNameAndContainingTypesAndNamespaces)));
                    }

                    return(string.CompareOrdinal(
                               ToDisplayString(x, containingNamespace),
                               ToDisplayString(y, containingNamespace)));
                });

                ImmutableArray <INamedTypeSymbol> .Enumerator en = interfaces.GetEnumerator();

                if (en.MoveNext())
                {
                    while (true)
                    {
                        builder.AddDisplayParts(en.Current, containingNamespace);

                        if (en.MoveNext())
                        {
                            builder.AddPunctuation(",");

                            if (formatBaseList)
                            {
                                builder.AddLineBreak();
                                builder.AddIndentation();
                            }
                            else
                            {
                                builder.AddSpace();
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                if (whereIndex != -1)
                {
                    if (!formatConstraints ||
                        (baseListCount == 1 && constraintCount == 1))
                    {
                        builder.AddSpace();
                    }
                }
            }
            else if (whereIndex != -1)
            {
                builder.AddRange(parts, whereIndex);
            }
            else
            {
                builder.AddRange(parts);
            }

            if (whereIndex != -1)
            {
                for (int i = whereIndex; i < parts.Length; i++)
                {
                    if (parts[i].IsKeyword("where"))
                    {
                        if (formatConstraints &&
                            (baseListCount > 1 || constraintCount > 1))
                        {
                            builder.AddLineBreak();
                            builder.AddIndentation();
                        }

                        builder.Add(parts[i]);
                    }
                    else if (parts[i].IsTypeName() &&
                             parts[i].Symbol is INamedTypeSymbol namedTypeSymbol)
                    {
                        builder.AddDisplayParts(namedTypeSymbol, containingNamespace);
                    }
                    else
                    {
                        builder.Add(parts[i]);
                    }
                }
            }

            if (formatParameters)
            {
                ImmutableArray <IParameterSymbol> parameters = symbol.GetParameters();

                if (parameters.Length > 1)
                {
                    FormatParameters(symbol, builder, DeclarationListOptions.DefaultValues.IndentChars);
                }
            }

            return(builder.ToImmutableArray());
        }
Пример #15
0
        private ImmutableArray <SymbolDisplayPart> AppendParameterAttributes(
            ImmutableArray <SymbolDisplayPart> parts,
            ISymbol symbol,
            ImmutableArray <IParameterSymbol> parameters)
        {
            int i = SymbolDeclarationBuilder.FindParameterListStart(symbol, parts);

            if (i == -1)
            {
                return(parts);
            }

            int parameterIndex = 0;

            IParameterSymbol parameter = parameters[parameterIndex];

            ImmutableArray <SymbolDisplayPart> attributeParts = SymbolDeclarationBuilder.GetAttributesParts(
                parameter.GetAttributes(),
                predicate: IsVisibleAttribute,
                splitAttributes: Options.SplitAttributes,
                includeAttributeArguments: Options.IncludeAttributeArguments,
                addNewLine: false);

            if (attributeParts.Any())
            {
                parts = parts.Insert(i + 1, SymbolDisplayPartFactory.Space());
                parts = parts.InsertRange(i + 1, attributeParts);
            }

            int parenthesesDepth   = 0;
            int bracesDepth        = 0;
            int bracketsDepth      = 0;
            int angleBracketsDepth = 0;

            ImmutableArray <SymbolDisplayPart> .Builder builder = null;

            int prevIndex = 0;

            AddParameterAttributes();

            if (builder != null)
            {
                while (prevIndex < parts.Length)
                {
                    builder.Add(parts[prevIndex]);
                    prevIndex++;
                }

                return(builder.ToImmutableArray());
            }

            return(parts);

            void AddParameterAttributes()
            {
                while (i < parts.Length)
                {
                    SymbolDisplayPart part = parts[i];

                    if (part.Kind == SymbolDisplayPartKind.Punctuation)
                    {
                        switch (part.ToString())
                        {
                        case ",":
                        {
                            if (((angleBracketsDepth == 0 && parenthesesDepth == 1 && bracesDepth == 0 && bracketsDepth == 0) ||
                                 (angleBracketsDepth == 0 && parenthesesDepth == 0 && bracesDepth == 0 && bracketsDepth == 1)) &&
                                i < parts.Length - 1)
                            {
                                SymbolDisplayPart nextPart = parts[i + 1];

                                if (nextPart.Kind == SymbolDisplayPartKind.Space)
                                {
                                    parameterIndex++;

                                    attributeParts = SymbolDeclarationBuilder.GetAttributesParts(
                                        parameters[parameterIndex].GetAttributes(),
                                        predicate: IsVisibleAttribute,
                                        splitAttributes: Options.SplitAttributes,
                                        includeAttributeArguments: Options.IncludeAttributeArguments,
                                        addNewLine: false);

                                    if (attributeParts.Any())
                                    {
                                        if (builder == null)
                                        {
                                            builder = ImmutableArray.CreateBuilder <SymbolDisplayPart>();

                                            builder.AddRange(parts, i + 1);
                                        }
                                        else
                                        {
                                            for (int j = prevIndex; j <= i; j++)
                                            {
                                                builder.Add(parts[j]);
                                            }
                                        }

                                        builder.Add(SymbolDisplayPartFactory.Space());
                                        builder.AddRange(attributeParts);

                                        prevIndex = i + 1;
                                    }
                                }
                            }

                            break;
                        }

                        case "(":
                        {
                            parenthesesDepth++;
                            break;
                        }

                        case ")":
                        {
                            Debug.Assert(parenthesesDepth >= 0);
                            parenthesesDepth--;

                            if (parenthesesDepth == 0 &&
                                symbol.IsKind(SymbolKind.Method, SymbolKind.NamedType))
                            {
                                return;
                            }

                            break;
                        }

                        case "[":
                        {
                            bracketsDepth++;
                            break;
                        }

                        case "]":
                        {
                            Debug.Assert(bracketsDepth >= 0);
                            bracketsDepth--;

                            if (bracketsDepth == 0 &&
                                symbol.Kind == SymbolKind.Property)
                            {
                                return;
                            }

                            break;
                        }

                        case "{":
                        {
                            bracesDepth++;
                            break;
                        }

                        case "}":
                        {
                            Debug.Assert(bracesDepth >= 0);
                            bracesDepth--;
                            break;
                        }

                        case "<":
                        {
                            angleBracketsDepth++;
                            break;
                        }

                        case ">":
                        {
                            Debug.Assert(angleBracketsDepth >= 0);
                            angleBracketsDepth--;
                            break;
                        }
                        }
                    }

                    i++;
                }
            }
        }
 internal static ImmutableArray <T> Concat <T>(this ImmutableArray <T> first, ImmutableArray <T> second)
 {
     return(first.AddRange(second));
 }
Пример #17
0
        private static async Task <int> FindSymbolsAsync(FindSymbolsCommandLineOptions options)
        {
            if (!options.TryGetProjectFilter(out ProjectFilter projectFilter))
            {
                return(ExitCodes.Error);
            }

            if (!TryParseOptionValueAsEnumFlags(options.SymbolGroups, ParameterNames.SymbolGroups, out SymbolGroupFilter symbolGroups, SymbolFinderOptions.Default.SymbolGroups))
            {
                return(ExitCodes.Error);
            }

            if (!TryParseOptionValueAsEnumFlags(options.Visibility, ParameterNames.Visibility, out VisibilityFilter visibility, SymbolFinderOptions.Default.Visibility))
            {
                return(ExitCodes.Error);
            }

            if (!TryParseMetadataNames(options.WithAttributes, out ImmutableArray <MetadataName> withAttributes))
            {
                return(ExitCodes.Error);
            }

            if (!TryParseMetadataNames(options.WithoutAttributes, out ImmutableArray <MetadataName> withoutAttributes))
            {
                return(ExitCodes.Error);
            }

            if (!TryParseOptionValueAsEnumFlags(options.WithFlags, ParameterNames.WithFlags, out SymbolFlags withFlags, SymbolFlags.None))
            {
                return(ExitCodes.Error);
            }

            if (!TryParseOptionValueAsEnumFlags(options.WithoutFlags, ParameterNames.WithoutFlags, out SymbolFlags withoutFlags, SymbolFlags.None))
            {
                return(ExitCodes.Error);
            }

            ImmutableArray <SymbolFilterRule> .Builder rules = ImmutableArray.CreateBuilder <SymbolFilterRule>();

            if (withAttributes.Any())
            {
                rules.Add(new WithAttributeFilterRule(withAttributes));
            }

            if (withoutAttributes.Any())
            {
                rules.Add(new WithoutAttributeFilterRule(withoutAttributes));
            }

            if (withFlags != SymbolFlags.None)
            {
                rules.AddRange(SymbolFilterRuleFactory.FromFlags(withFlags));
            }

            if (withoutFlags != SymbolFlags.None)
            {
                rules.AddRange(SymbolFilterRuleFactory.FromFlags(withoutFlags, invert: true));
            }

            var symbolFinderOptions = new SymbolFinderOptions(
                visibility: visibility,
                symbolGroups: symbolGroups,
                rules: rules,
                ignoreGeneratedCode: options.IgnoreGeneratedCode,
                unusedOnly: options.UnusedOnly);

            var command = new FindSymbolsCommand(
                options: options,
                symbolFinderOptions: symbolFinderOptions,
                projectFilter: projectFilter);

            CommandResult result = await command.ExecuteAsync(options.Path, options.MSBuildPath, options.Properties);

            return(GetExitCode(result));
        }
Пример #18
0
        /// <remarks>
        /// Internal for testing.
        /// </remarks>
        internal static bool ShouldTryAgainWithMoreMetadataBlocks(DkmUtilities.GetMetadataBytesPtrFunction getMetaDataBytesPtrFunction, ImmutableArray<AssemblyIdentity> missingAssemblyIdentities, ref ImmutableArray<MetadataBlock> references)
        {
            var newReferences = DkmUtilities.GetMetadataBlocks(getMetaDataBytesPtrFunction, missingAssemblyIdentities);
            if (newReferences.Length > 0)
            {
                references = references.AddRange(newReferences);
                return true;
            }

            return false;
        }
 protected override ImmutableArray <T> AddRange(ImmutableArray <T> values, ref ArraySegment <T> newValues, ISerializationContext context)
 => newValues.Count == 1 ? values.Add(newValues.Singleton()) : values.AddRange(newValues);
Пример #20
0
 public void AddMetadataReferences(IEnumerable <MetadataReference> references)
 {
     _metadataReferences.AddRange(references);
     ScriptOptions = ScriptOptions.AddReferences(references);
 }
Пример #21
0
 public void AddRange(ArrayBuilder <T> items)
 {
     _builder.AddRange(items._builder);
 }
 public void AddNativeLibraryProbingPaths(IReadOnlyList <DirectoryInfo> probingPaths)
 {
     _probingDirectories       = _probingDirectories.AddRange(probingPaths).Distinct().ToImmutableArray();
     _globalProbingDirectories = _globalProbingDirectories.AddRange(probingPaths).Distinct().ToImmutableArray();
 }
Пример #23
0
        private async Task <ProjectFixResult> FixProjectAsync(
            Project project,
            ImmutableArray <DiagnosticAnalyzer> analyzers,
            ImmutableArray <CodeFixProvider> fixers,
            CancellationToken cancellationToken)
        {
            if (!analyzers.Any())
            {
                WriteLine($"  No analyzers found to analyze '{project.Name}'", ConsoleColor.DarkGray, Verbosity.Normal);
                return(ProjectFixResult.NoAnalyzers);
            }

            if (!fixers.Any())
            {
                WriteLine($"  No fixers found to fix '{project.Name}'", ConsoleColor.DarkGray, Verbosity.Normal);
                return(new ProjectFixResult(ProjectFixKind.NoFixers, analyzers: analyzers, fixers: fixers));
            }

            Dictionary <string, ImmutableArray <CodeFixProvider> > fixersById = GetFixersById(fixers, Options);

            analyzers = analyzers
                        .Where(analyzer => analyzer.SupportedDiagnostics.Any(descriptor => fixersById.ContainsKey(descriptor.Id)))
                        .ToImmutableArray();

            if (!analyzers.Any())
            {
                WriteLine($"  No fixable analyzers found to analyze '{project.Name}'", ConsoleColor.DarkGray, Verbosity.Normal);
                return(new ProjectFixResult(ProjectFixKind.NoFixableAnalyzers, analyzers: analyzers, fixers: fixers));
            }

            Dictionary <string, ImmutableArray <DiagnosticAnalyzer> > analyzersById = GetAnalyzersById(analyzers);

            LogHelpers.WriteUsedAnalyzers(analyzers, ConsoleColor.DarkGray, Verbosity.Diagnostic);
            LogHelpers.WriteUsedFixers(fixers, ConsoleColor.DarkGray, Verbosity.Diagnostic);

            ImmutableArray <Diagnostic> .Builder fixedDiagnostics = ImmutableArray.CreateBuilder <Diagnostic>();

            ImmutableArray <Diagnostic> previousDiagnostics         = ImmutableArray <Diagnostic> .Empty;
            ImmutableArray <Diagnostic> previousPreviousDiagnostics = ImmutableArray <Diagnostic> .Empty;

            var fixKind = ProjectFixKind.Success;

            int iterationCount = 1;

            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();

                project = CurrentSolution.GetProject(project.Id);

                WriteLine($"  Compile '{project.Name}'{((iterationCount > 1) ? $" iteration {iterationCount}" : "")}", Verbosity.Normal);

                Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                ImmutableArray <Diagnostic> compilerDiagnostics = compilation.GetDiagnostics(cancellationToken);

                if (!VerifyCompilerDiagnostics(compilerDiagnostics, project))
                {
                    return(new ProjectFixResult(ProjectFixKind.CompilerError, fixedDiagnostics, analyzers: analyzers, fixers: fixers));
                }

                WriteLine($"  Analyze '{project.Name}'", Verbosity.Normal);

                ImmutableArray <Diagnostic> diagnostics = await compilation.GetAnalyzerDiagnosticsAsync(analyzers, Options.CompilationWithAnalyzersOptions, cancellationToken).ConfigureAwait(false);

                LogHelpers.WriteAnalyzerExceptionDiagnostics(diagnostics);

                diagnostics = GetFixableDiagnostics(diagnostics, compilerDiagnostics);

                int length = diagnostics.Length;

                if (length == 0)
                {
                    break;
                }

                if (length == previousDiagnostics.Length &&
                    !diagnostics.Except(previousDiagnostics, DiagnosticDeepEqualityComparer.Instance).Any())
                {
                    break;
                }

                if (length == previousPreviousDiagnostics.Length &&
                    !diagnostics.Except(previousPreviousDiagnostics, DiagnosticDeepEqualityComparer.Instance).Any())
                {
                    LogHelpers.WriteInfiniteLoopSummary(diagnostics, previousDiagnostics, project, FormatProvider);

                    fixKind = ProjectFixKind.InfiniteLoop;
                    break;
                }

                WriteLine($"  Found {length} {((length == 1) ? "diagnostic" : "diagnostics")} in '{project.Name}'", Verbosity.Normal);

                foreach (DiagnosticDescriptor descriptor in GetSortedDescriptors(diagnostics))
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    string diagnosticId = descriptor.Id;

                    DiagnosticFixResult result = await FixDiagnosticsAsync(
                        descriptor,
                        (descriptor.CustomTags.Contains(WellKnownDiagnosticTags.Compiler))
                        ?default(ImmutableArray <DiagnosticAnalyzer>)
                        : analyzersById[diagnosticId],
                        fixersById[diagnosticId],
                        CurrentSolution.GetProject(project.Id),
                        cancellationToken).ConfigureAwait(false);

                    if (result.Kind == DiagnosticFixKind.Success)
                    {
                        fixedDiagnostics.AddRange(result.FixedDiagnostics);
                    }
                    else if (result.Kind == DiagnosticFixKind.CompilerError)
                    {
                        return(new ProjectFixResult(ProjectFixKind.CompilerError, fixedDiagnostics, analyzers: analyzers, fixers: fixers));
                    }
                }

                if (iterationCount == Options.MaxIterations)
                {
                    break;
                }

                previousPreviousDiagnostics = previousDiagnostics;
                previousDiagnostics         = diagnostics;
                iterationCount++;
            }

            return(new ProjectFixResult(fixKind, fixedDiagnostics, analyzers: analyzers, fixers: fixers));

            ImmutableArray <Diagnostic> GetFixableDiagnostics(
                ImmutableArray <Diagnostic> diagnostics,
                ImmutableArray <Diagnostic> compilerDiagnostics)
            {
                IEnumerable <Diagnostic> fixableCompilerDiagnostics = compilerDiagnostics
                                                                      .Where(f => f.Severity != DiagnosticSeverity.Error &&
                                                                             !Options.IgnoredCompilerDiagnosticIds.Contains(f.Id) &&
                                                                             fixersById.ContainsKey(f.Id));

                return(diagnostics
                       .Where(f => Options.IsSupportedDiagnostic(f) &&
                              analyzersById.ContainsKey(f.Id) &&
                              fixersById.ContainsKey(f.Id))
                       .Concat(fixableCompilerDiagnostics)
                       .ToImmutableArray());
            }

            IEnumerable <DiagnosticDescriptor> GetSortedDescriptors(
                ImmutableArray <Diagnostic> diagnostics)
            {
                Dictionary <DiagnosticDescriptor, int> countByDescriptor = diagnostics
                                                                           .GroupBy(f => f.Descriptor, DiagnosticDescriptorComparer.Id)
                                                                           .ToDictionary(f => f.Key, f => f.Count());

                return(countByDescriptor
                       .Select(f => f.Key)
                       .OrderBy(f => f, new DiagnosticDescriptorFixComparer(countByDescriptor, fixersById)));
            }
        }
Пример #24
0
        private static bool TryParsePaths(IEnumerable <string> values, out ImmutableArray <string> paths)
        {
            paths = ImmutableArray <string> .Empty;

            if (values.Any())
            {
                if (!TryEnsureFullPath(values, out ImmutableArray <string> paths2))
                {
                    return(false);
                }

                paths = paths.AddRange(paths2);
            }

            if (Console.IsInputRedirected)
            {
                if (!TryEnsureFullPath(
                        ConsoleHelpers.ReadRedirectedInputAsLines().Where(f => !string.IsNullOrEmpty(f)),
                        out ImmutableArray <string> paths2))
                {
                    return(false);
                }

                paths = paths.AddRange(paths2);
            }

            if (!paths.IsEmpty)
            {
                return(true);
            }

            string directoryPath = Environment.CurrentDirectory;

            if (!TryFindFile(Directory.EnumerateFiles(directoryPath, "*.sln", SearchOption.TopDirectoryOnly), out string solutionPath))
            {
                WriteLine($"Multiple MSBuild solution files found in '{directoryPath}'", Verbosity.Quiet);
                return(false);
            }

            if (!TryFindFile(
                    Directory.EnumerateFiles(directoryPath, "*.*proj", SearchOption.TopDirectoryOnly)
                    .Where(f => !string.Equals(".xproj", Path.GetExtension(f), StringComparison.OrdinalIgnoreCase)),
                    out string projectPath))
            {
                WriteLine($"Multiple MSBuild projects files found in '{directoryPath}'", Verbosity.Quiet);
                return(false);
            }

            if (solutionPath != null)
            {
                if (projectPath != null)
                {
                    WriteLine($"Both MSBuild project file and solution file found in '{directoryPath}'", Verbosity.Quiet);
                    return(false);
                }

                paths = ImmutableArray.Create(solutionPath);
                return(true);
            }
            else if (projectPath != null)
            {
                paths = ImmutableArray.Create(projectPath);
                return(true);
            }
            else
            {
                WriteLine($"Could not find MSBuild project or solution file in '{directoryPath}'", Verbosity.Quiet);
                return(false);
            }
Пример #25
0
        public static ImmutableArray <SymbolDisplayPart> ToDisplayParts(this INamedTypeSymbol typeSymbol, SymbolDisplayFormat format, SymbolDisplayTypeDeclarationOptions typeDeclarationOptions)
        {
            if (typeDeclarationOptions == SymbolDisplayTypeDeclarationOptions.None)
            {
                return(typeSymbol.ToDisplayParts(format));
            }

            ImmutableArray <SymbolDisplayPart> parts = typeSymbol.ToDisplayParts(format);

            ImmutableArray <SymbolDisplayPart> .Builder builder = ImmutableArray.CreateBuilder <SymbolDisplayPart>(parts.Length);

            if ((typeDeclarationOptions & SymbolDisplayTypeDeclarationOptions.IncludeAccessibility) != 0)
            {
                switch (typeSymbol.DeclaredAccessibility)
                {
                case Accessibility.Public:
                {
                    AddKeyword(SyntaxKind.PublicKeyword);
                    break;
                }

                case Accessibility.ProtectedOrInternal:
                {
                    AddKeyword(SyntaxKind.ProtectedKeyword);
                    AddKeyword(SyntaxKind.InternalKeyword);
                    break;
                }

                case Accessibility.Internal:
                {
                    AddKeyword(SyntaxKind.InternalKeyword);
                    break;
                }

                case Accessibility.Protected:
                {
                    AddKeyword(SyntaxKind.ProtectedKeyword);
                    break;
                }

                case Accessibility.ProtectedAndInternal:
                {
                    AddKeyword(SyntaxKind.PrivateKeyword);
                    AddKeyword(SyntaxKind.ProtectedKeyword);
                    break;
                }

                case Accessibility.Private:
                {
                    AddKeyword(SyntaxKind.PrivateKeyword);
                    break;
                }

                default:
                {
                    throw new InvalidOperationException();
                }
                }
            }

            if ((typeDeclarationOptions & SymbolDisplayTypeDeclarationOptions.IncludeModifiers) != 0)
            {
                if (typeSymbol.IsStatic)
                {
                    AddKeyword(SyntaxKind.StaticKeyword);
                }

                if (typeSymbol.IsSealed &&
                    !typeSymbol.TypeKind.Is(TypeKind.Struct, TypeKind.Enum, TypeKind.Delegate))
                {
                    AddKeyword(SyntaxKind.SealedKeyword);
                }

                if (typeSymbol.IsAbstract &&
                    typeSymbol.TypeKind != TypeKind.Interface)
                {
                    AddKeyword(SyntaxKind.AbstractKeyword);
                }
            }

            builder.AddRange(parts);

            return(builder.ToImmutableArray());

            void AddKeyword(SyntaxKind kind)
            {
                builder.Add(SymbolDisplayPartFactory.Keyword(SyntaxFacts.GetText(kind)));
                AddSpace();
            }

            void AddSpace()
            {
                builder.Add(SymbolDisplayPartFactory.Space());
            }
        }
Пример #26
0
 protected virtual void AppendDiagnostics(IEnumerable <DiagnosticData> items)
 {
     _builder = _builder ?? ImmutableArray.CreateBuilder <DiagnosticData>();
     _builder.AddRange(items);
 }
 public void AddNotNullMember(ArrayBuilder <string> memberNames)
 {
     VerifySealed(expected: false);
     _memberNotNullAttributeData = _memberNotNullAttributeData.AddRange(memberNames);
     SetDataStored();
 }
        private static void AddDisplayParts(
            this ImmutableArray <SymbolDisplayPart> .Builder parts,
            ISymbol symbol,
            SymbolDisplayFormat format,
            SymbolDisplayAdditionalOptions additionalOptions,
            bool removeAttributeSuffix = false)
        {
            SymbolDisplayFormat format2;

            if (additionalOptions.HasOption(SymbolDisplayAdditionalOptions.OmitContainingNamespace))
            {
                format2 = SymbolDefinitionDisplayFormats.TypeNameAndContainingTypes;
            }
            else if (format.GlobalNamespaceStyle == SymbolDisplayGlobalNamespaceStyle.Included)
            {
                format2 = SymbolDefinitionDisplayFormats.TypeNameAndContainingTypesAndNamespacesAndGlobalNamespace;
            }
            else
            {
                format2 = SymbolDefinitionDisplayFormats.TypeNameAndContainingTypesAndNamespaces;
            }

            parts.AddRange(symbol.ToDisplayParts(format2));

            if (!(symbol is INamedTypeSymbol typeSymbol))
            {
                return;
            }

            if (removeAttributeSuffix)
            {
                SymbolDisplayPart last = parts.Last();

                if (last.Kind == SymbolDisplayPartKind.ClassName)
                {
                    const string attributeSuffix = "Attribute";

                    string text = last.ToString();
                    if (text.EndsWith(attributeSuffix, StringComparison.Ordinal))
                    {
                        parts[parts.Count - 1] = last.WithText(text.Remove(text.Length - attributeSuffix.Length));
                    }
                }
            }

            ImmutableArray <ITypeSymbol> typeArguments = typeSymbol.TypeArguments;

            ImmutableArray <ITypeSymbol> .Enumerator en = typeArguments.GetEnumerator();

            if (en.MoveNext())
            {
                parts.AddPunctuation("<");

                while (true)
                {
                    if (en.Current.Kind == SymbolKind.NamedType)
                    {
                        parts.AddDisplayParts((INamedTypeSymbol)en.Current, format, additionalOptions);
                    }
                    else
                    {
                        Debug.Assert(en.Current.Kind == SymbolKind.TypeParameter, en.Current.Kind.ToString());

                        parts.Add(new SymbolDisplayPart(SymbolDisplayPartKind.TypeParameterName, en.Current, en.Current.Name));
                    }

                    if (en.MoveNext())
                    {
                        parts.AddPunctuation(",");
                        parts.AddSpace();
                    }
                    else
                    {
                        break;
                    }
                }

                parts.AddPunctuation(">");
            }
        }
Пример #29
0
        private static void AddDiagnostics_NoLock(
            Dictionary<DiagnosticAnalyzer, List<Diagnostic>> diagnostics,
            AnalysisScope analysisScope,
            ImmutableArray<Diagnostic>.Builder builder)
        {
            Debug.Assert(diagnostics != null);

            foreach (var analyzer in analysisScope.Analyzers)
            {
                List<Diagnostic> diagnosticsByAnalyzer;
                if (diagnostics.TryGetValue(analyzer, out diagnosticsByAnalyzer))
                {
                    builder.AddRange(diagnosticsByAnalyzer);
                }
            }
        }
        public static ImmutableArray <SymbolDisplayPart> GetDisplayParts(
            ISymbol symbol,
            SymbolDisplayFormat format,
            SymbolDisplayTypeDeclarationOptions typeDeclarationOptions = SymbolDisplayTypeDeclarationOptions.None,
            SymbolDisplayAdditionalOptions additionalOptions           = SymbolDisplayAdditionalOptions.None,
            Func <ISymbol, AttributeData, bool> shouldDisplayAttribute = null)
        {
            ImmutableArray <SymbolDisplayPart> parts;

            if (symbol is INamedTypeSymbol typeSymbol)
            {
                parts = typeSymbol.ToDisplayParts(format, typeDeclarationOptions);
            }
            else
            {
                parts      = symbol.ToDisplayParts(format);
                typeSymbol = null;
            }

            IEnumerable <AttributeData> attributes = (additionalOptions.HasOption(SymbolDisplayAdditionalOptions.IncludeAttributes))
                ? GetAttributes(symbol, shouldDisplayAttribute)
                : ImmutableArray <AttributeData> .Empty;

            ImmutableArray <SymbolDisplayPart> .Builder builder = default;

            INamedTypeSymbol baseType = null;
            ImmutableArray <INamedTypeSymbol> interfaces = ImmutableArray <INamedTypeSymbol> .Empty;

            if (typeSymbol != null &&
                (typeDeclarationOptions & SymbolDisplayTypeDeclarationOptions.BaseList) != 0)
            {
                if ((typeDeclarationOptions & SymbolDisplayTypeDeclarationOptions.BaseType) != 0 &&
                    typeSymbol.TypeKind.Is(TypeKind.Class, TypeKind.Interface))
                {
                    baseType = typeSymbol.BaseType;

                    if (baseType?.SpecialType == SpecialType.System_Object)
                    {
                        baseType = null;
                    }
                }

                if ((typeDeclarationOptions & SymbolDisplayTypeDeclarationOptions.Interfaces) != 0)
                {
                    interfaces = typeSymbol.Interfaces;

                    if (additionalOptions.HasOption(SymbolDisplayAdditionalOptions.OmitIEnumerable) &&
                        interfaces.Any(f => f.OriginalDefinition.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T))
                    {
                        interfaces = interfaces.RemoveAll(f => f.SpecialType == SpecialType.System_Collections_IEnumerable);
                    }
                }
            }

            int baseListCount = interfaces.Length;

            if (baseType != null)
            {
                baseListCount++;
            }

            int constraintCount = 0;
            int whereIndex      = -1;

            for (int i = 0; i < parts.Length; i++)
            {
                if (parts[i].IsKeyword("where"))
                {
                    if (whereIndex == -1)
                    {
                        whereIndex = i;
                    }

                    constraintCount++;
                }
            }

            if (baseListCount > 0)
            {
                InitializeBuilder();

                if (whereIndex != -1)
                {
                    builder.AddRange(parts, whereIndex);
                }
                else
                {
                    builder.AddRange(parts);
                    builder.AddSpace();
                }

                builder.AddPunctuation(":");
                builder.AddSpace();

                if (baseType != null)
                {
                    builder.AddDisplayParts(baseType, format, additionalOptions);

                    if (interfaces.Any())
                    {
                        builder.AddPunctuation(",");

                        if (additionalOptions.HasOption(SymbolDisplayAdditionalOptions.FormatBaseList))
                        {
                            builder.AddLineBreak();
                            builder.AddIndentation();
                        }
                        else
                        {
                            builder.AddSpace();
                        }
                    }
                }

                IComparer <INamedTypeSymbol> comparer = (additionalOptions.HasOption(SymbolDisplayAdditionalOptions.OmitContainingNamespace))
                    ? SymbolDefinitionComparer.SystemFirstOmitContainingNamespace.TypeComparer
                    : SymbolDefinitionComparer.SystemFirst.TypeComparer;

                interfaces = interfaces.Sort(comparer);

                ImmutableArray <INamedTypeSymbol> .Enumerator en = interfaces.GetEnumerator();

                if (en.MoveNext())
                {
                    while (true)
                    {
                        builder.AddDisplayParts(en.Current, format, additionalOptions);

                        if (en.MoveNext())
                        {
                            builder.AddPunctuation(",");

                            if (additionalOptions.HasOption(SymbolDisplayAdditionalOptions.FormatBaseList))
                            {
                                builder.AddLineBreak();
                                builder.AddIndentation();
                            }
                            else
                            {
                                builder.AddSpace();
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                if (whereIndex != -1)
                {
                    if (!additionalOptions.HasOption(SymbolDisplayAdditionalOptions.FormatConstraints) ||
                        (baseListCount == 1 && constraintCount == 1))
                    {
                        builder.AddSpace();
                    }
                }
            }

            if (whereIndex != -1)
            {
                InitializeBuilder();

                if (baseListCount == 0)
                {
                    builder.AddRange(parts, whereIndex);
                }

                for (int i = whereIndex; i < parts.Length; i++)
                {
                    if (parts[i].IsKeyword("where") &&
                        additionalOptions.HasOption(SymbolDisplayAdditionalOptions.FormatConstraints) &&
                        (baseListCount > 1 || constraintCount > 1))
                    {
                        builder.AddLineBreak();
                        builder.AddIndentation();
                    }

                    builder.Add(parts[i]);
                }
            }

            if (builder == null &&
                attributes.Any())
            {
                builder = ImmutableArray.CreateBuilder <SymbolDisplayPart>(parts.Length);

                AddAttributes(builder, attributes, format, additionalOptions, includeTrailingNewLine: true);

                builder.AddRange(parts);
            }

            bool hasEventAccessorList = false;

            if (additionalOptions.HasOption(SymbolDisplayAdditionalOptions.IncludeAccessorAttributes))
            {
                if (symbol.Kind == SymbolKind.Property)
                {
                    var propertySymbol = (IPropertySymbol)symbol;

                    IMethodSymbol getMethod = propertySymbol.GetMethod;
                    if (getMethod != null)
                    {
                        builder = builder ?? parts.ToBuilder();

                        AddAccessorAttributes(builder, getMethod, format, additionalOptions, shouldDisplayAttribute: shouldDisplayAttribute);
                    }

                    IMethodSymbol setMethod = propertySymbol.SetMethod;
                    if (setMethod != null)
                    {
                        builder = builder ?? parts.ToBuilder();

                        AddAccessorAttributes(builder, setMethod, format, additionalOptions, shouldDisplayAttribute: shouldDisplayAttribute);
                    }
                }
                else if (symbol.Kind == SymbolKind.Event)
                {
                    var eventSymbol = (IEventSymbol)symbol;

                    IEnumerable <AttributeData> addAttributes    = GetAttributes(eventSymbol.AddMethod, shouldDisplayAttribute);
                    IEnumerable <AttributeData> removeAttributes = GetAttributes(eventSymbol.RemoveMethod, shouldDisplayAttribute);

                    if (addAttributes.Any() ||
                        removeAttributes.Any())
                    {
                        hasEventAccessorList = true;

                        builder = builder ?? parts.ToBuilder();

                        AddEventAccessorAttributes(builder, addAttributes, removeAttributes, format, additionalOptions);
                    }
                }
            }

            ImmutableArray <IParameterSymbol> parameters = symbol.GetParameters();

            if (additionalOptions.HasOption(SymbolDisplayAdditionalOptions.IncludeParameterAttributes) &&
                parameters.Any(f => GetAttributes(f, shouldDisplayAttribute).Any()))
            {
                builder = builder ?? parts.ToBuilder();

                AddParameterAttributes(builder, symbol, parameters, format, additionalOptions, shouldDisplayAttribute);
            }

            if (additionalOptions.HasOption(SymbolDisplayAdditionalOptions.FormatParameters) &&
                parameters.Length > 1)
            {
                builder = builder ?? parts.ToBuilder();

                FormatParameters(symbol, builder, DefinitionListFormat.Default.IndentChars);
            }

            if (additionalOptions.HasOption(SymbolDisplayAdditionalOptions.PreferDefaultLiteral))
            {
                if ((format.ParameterOptions & SymbolDisplayParameterOptions.IncludeDefaultValue) != 0 &&
                    parameters.Any(f => f.HasExplicitDefaultValue && HasDefaultExpression(f.Type, f.ExplicitDefaultValue)))
                {
                    builder = builder ?? parts.ToBuilder();

                    builder = ReplaceDefaultExpressionWithDefaultLiteral(symbol, builder);
                }

                if ((format.MemberOptions & SymbolDisplayMemberOptions.IncludeConstantValue) != 0 &&
                    symbol.IsKind(SymbolKind.Field))
                {
                    var fieldSymbol = (IFieldSymbol)symbol;

                    if (fieldSymbol.IsConst &&
                        fieldSymbol.HasConstantValue &&
                        HasDefaultExpression(fieldSymbol.Type, fieldSymbol.ConstantValue))
                    {
                        builder = builder ?? parts.ToBuilder();

                        builder = ReplaceDefaultExpressionWithDefaultLiteral(symbol, builder);
                    }
                }
            }

            if (ShouldAddTrailingSemicolon())
            {
                if (builder == null)
                {
                    parts = parts.Add(new SymbolDisplayPart(SymbolDisplayPartKind.Punctuation, null, ";"));
                }
                else
                {
                    builder.AddPunctuation(";");
                }
            }

            return(builder?.ToImmutableArray() ?? parts);

            void InitializeBuilder()
            {
                if (builder == null)
                {
                    builder = ImmutableArray.CreateBuilder <SymbolDisplayPart>(parts.Length);

                    if (attributes.Any())
                    {
                        AddAttributes(builder, attributes, format, additionalOptions, includeTrailingNewLine: true);
                    }
                }
            }

            bool ShouldAddTrailingSemicolon()
            {
                if (additionalOptions.HasOption(SymbolDisplayAdditionalOptions.IncludeTrailingSemicolon))
                {
                    if (typeSymbol?.TypeKind == TypeKind.Delegate)
                    {
                        return(true);
                    }

                    switch (symbol.Kind)
                    {
                    case SymbolKind.Event:
                        return(!hasEventAccessorList);

                    case SymbolKind.Field:
                        return(symbol.ContainingType?.TypeKind != TypeKind.Enum);

                    case SymbolKind.Method:
                        return(true);
                    }
                }

                return(false);
            }
        }
 protected virtual void AppendDiagnostics(IEnumerable<DiagnosticData> items)
 {
     _builder = _builder ?? ImmutableArray.CreateBuilder<DiagnosticData>();
     _builder.AddRange(items);
 }
Пример #32
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NamingSettings"/> class.
        /// </summary>
        /// <param name="namingSettingsObject">The JSON object containing the settings.</param>
        /// <param name="analyzerConfigOptions">The <strong>.editorconfig</strong> options to use if
        /// <strong>stylecop.json</strong> does not provide values.</param>
        protected internal NamingSettings(JsonObject namingSettingsObject, AnalyzerConfigOptionsWrapper analyzerConfigOptions)
        {
            bool?allowCommonHungarianPrefixes = null;

            ImmutableArray <string> .Builder allowedHungarianPrefixes   = null;
            ImmutableArray <string> .Builder allowedNamespaceComponents = null;
            bool?includeInferredTupleElementNames       = null;
            TupleElementNameCase?tupleElementNameCasing = null;

            foreach (var kvp in namingSettingsObject)
            {
                switch (kvp.Key)
                {
                case "allowCommonHungarianPrefixes":
                    allowCommonHungarianPrefixes = kvp.ToBooleanValue();
                    break;

                case "allowedHungarianPrefixes":
                    kvp.AssertIsArray();
                    allowedHungarianPrefixes = ImmutableArray.CreateBuilder <string>();
                    foreach (var prefixJsonValue in kvp.Value.AsJsonArray)
                    {
                        var prefix = prefixJsonValue.ToStringValue(kvp.Key);

                        if (!Regex.IsMatch(prefix, "^[a-z]{1,2}$"))
                        {
                            continue;
                        }

                        allowedHungarianPrefixes.Add(prefix);
                    }

                    break;

                case "allowedNamespaceComponents":
                    kvp.AssertIsArray();
                    allowedNamespaceComponents = ImmutableArray.CreateBuilder <string>();
                    allowedNamespaceComponents.AddRange(kvp.Value.AsJsonArray.Select(x => x.ToStringValue(kvp.Key)));
                    break;

                case "includeInferredTupleElementNames":
                    includeInferredTupleElementNames = kvp.ToBooleanValue();
                    break;

                case "tupleElementNameCasing":
                    tupleElementNameCasing = kvp.ToEnumValue <TupleElementNameCase>();
                    break;

                default:
                    break;
                }
            }

            allowCommonHungarianPrefixes ??= AnalyzerConfigHelper.TryGetBooleanValue(analyzerConfigOptions, "stylecop.naming.allowCommonHungarianPrefixes");
            allowedHungarianPrefixes ??= AnalyzerConfigHelper.TryGetStringListValue(analyzerConfigOptions, "stylecop.naming.allowedHungarianPrefixes")
            ?.Where(value => Regex.IsMatch(value, "^[a-z]{1,2}$"))
            .ToImmutableArray()
            .ToBuilder();
            allowedNamespaceComponents ??= AnalyzerConfigHelper.TryGetStringListValue(analyzerConfigOptions, "stylecop.naming.allowedNamespaceComponents")?.ToBuilder();
            includeInferredTupleElementNames ??= AnalyzerConfigHelper.TryGetBooleanValue(analyzerConfigOptions, "stylecop.naming.includeInferredTupleElementNames");
            tupleElementNameCasing ??= AnalyzerConfigHelper.TryGetStringValue(analyzerConfigOptions, "stylecop.naming.tupleElementNameCasing") switch
            {
                "camelCase" => TupleElementNameCase.CamelCase,
                "pascalCase" => TupleElementNameCase.PascalCase,
                _ => null,
            };

            this.AllowCommonHungarianPrefixes = allowCommonHungarianPrefixes.GetValueOrDefault(true);
            this.AllowedHungarianPrefixes     = allowedHungarianPrefixes?.ToImmutable() ?? ImmutableArray <string> .Empty;
            this.AllowedNamespaceComponents   = allowedNamespaceComponents?.ToImmutable() ?? ImmutableArray <string> .Empty;

            this.IncludeInferredTupleElementNames = includeInferredTupleElementNames.GetValueOrDefault(false);
            this.TupleElementNameCasing           = tupleElementNameCasing.GetValueOrDefault(TupleElementNameCase.PascalCase);
        }