/// <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); } }
protected override void AddTrackedEntities(ImmutableArray <AnalysisEntity> .Builder builder) => builder.AddRange(CurrentAnalysisData.Keys);
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); } }
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())); }
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())); }
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(); } }
private void Append(IEnumerable <byte> bytes) => _builder.AddRange(bytes);
public static ImmutableArray <byte> AddRange(this ImmutableArray <byte> source, params int[] args) { return(source.AddRange(args.Select(i => Convert.ToByte(i)))); }
/// <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); } }
/// <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); }
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(); } }
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()); }
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)); }
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)); }
/// <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);
public void AddMetadataReferences(IEnumerable <MetadataReference> references) { _metadataReferences.AddRange(references); ScriptOptions = ScriptOptions.AddReferences(references); }
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(); }
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))); } }
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); }
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()); } }
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(">"); } }
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); }
/// <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); }