Пример #1
0
        private static bool HasAnyContentChanges(bool willInherit, SolutionState state, SolutionState baseState)
        {
            if (state == null)
            {
                throw new ArgumentNullException(nameof(state));
            }

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

            if ((!willInherit || state.Sources.Any()) && !ContentEqual(state.Sources, baseState.Sources))
            {
                return(true);
            }

            if ((!willInherit || state.GeneratedSources.Any()) && !ContentEqual(state.GeneratedSources, baseState.GeneratedSources))
            {
                return(true);
            }

            if ((!willInherit || state.AdditionalFiles.Any()) && !ContentEqual(state.AdditionalFiles, baseState.AdditionalFiles))
            {
                return(true);
            }

            if ((!willInherit || state.AnalyzerConfigFiles.Any()) && !ContentEqual(state.AnalyzerConfigFiles, baseState.AnalyzerConfigFiles))
            {
                return(true);
            }

            if ((!willInherit || state.AdditionalReferences.Any()) && !state.AdditionalReferences.SequenceEqual(baseState.AdditionalReferences))
            {
                return(true);
            }

            return(false);
        }
Пример #2
0
 /// <summary>
 /// Called to test a C# source generator when applied on the input source as a string.
 /// </summary>
 /// <param name="testState">The effective input test state.</param>
 /// <param name="fixedState">The effective test state after the source generators are applied.</param>
 /// <param name="verifier">The verifier to use for test assertions.</param>
 /// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param>
 /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
 protected async Task <ImmutableArray <Diagnostic> > VerifySourceGeneratorAsync(SolutionState testState, SolutionState fixedState, IVerifier verifier, CancellationToken cancellationToken)
 {
     return(await VerifySourceGeneratorAsync(Language, GetSourceGenerators().ToImmutableArray(), testState, fixedState, ApplySourceGeneratorAsync, verifier.PushContext("Source generator application"), cancellationToken));
 }
Пример #3
0
 private async Task <ImmutableArray <Diagnostic> > VerifySourceGeneratorAsync(
     string language,
     ImmutableArray <ISourceGenerator> sourceGenerators,
     SolutionState oldState,
     SolutionState newState,
     Func <ImmutableArray <ISourceGenerator>, Project, IVerifier, CancellationToken, Task <(Project project, ImmutableArray <Diagnostic> diagnostics)> > getFixedProject,
Пример #4
0
 private static bool HasAnyChange(SolutionState oldState, SolutionState newState)
 {
     return(!oldState.Sources.SequenceEqual(newState.Sources, SourceFileEqualityComparer.Instance) ||
            !oldState.AdditionalFiles.SequenceEqual(newState.AdditionalFiles, SourceFileEqualityComparer.Instance));
 }
Пример #5
0
        /// <summary>
        /// Called to test a C# code fix when applied on the input source as a string.
        /// </summary>
        /// <param name="testState">The effective input test state.</param>
        /// <param name="fixedState">The effective test state after incremental code fixes are applied.</param>
        /// <param name="batchFixedState">The effective test state after batch code fixes are applied.</param>
        /// <param name="verifier">The verifier to use for test assertions.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        protected async Task VerifyFixAsync(SolutionState testState, SolutionState fixedState, SolutionState batchFixedState, IVerifier verifier, CancellationToken cancellationToken)
        {
            int numberOfIncrementalIterations;
            int numberOfFixAllIterations;
            int numberOfFixAllInDocumentIterations;

            if (NumberOfIncrementalIterations != null)
            {
                numberOfIncrementalIterations = NumberOfIncrementalIterations.Value;
            }
            else
            {
                if (!HasAnyChange(testState, fixedState))
                {
                    numberOfIncrementalIterations = 0;
                }
                else
                {
                    // Expect at most one iteration per fixable diagnostic
                    var fixers = GetCodeFixProviders().ToArray();
                    var fixableExpectedDiagnostics = testState.ExpectedDiagnostics.Count(diagnostic => fixers.Any(fixer => fixer.FixableDiagnosticIds.Contains(diagnostic.Id)));
                    numberOfIncrementalIterations = -fixableExpectedDiagnostics;
                }
            }

            if (NumberOfFixAllIterations != null)
            {
                numberOfFixAllIterations = NumberOfFixAllIterations.Value;
            }
            else
            {
                if (!HasAnyChange(testState, batchFixedState))
                {
                    numberOfFixAllIterations = 0;
                }
                else
                {
                    numberOfFixAllIterations = 1;
                }
            }

            if (NumberOfFixAllInDocumentIterations != null)
            {
                numberOfFixAllInDocumentIterations = NumberOfFixAllInDocumentIterations.Value;
            }
            else
            {
                numberOfFixAllInDocumentIterations = numberOfFixAllIterations;
            }

            var t1 = VerifyFixAsync(Language, GetDiagnosticAnalyzers().ToImmutableArray(), GetCodeFixProviders().ToImmutableArray(), testState, fixedState, numberOfIncrementalIterations, FixEachAnalyzerDiagnosticAsync, verifier.PushContext("Iterative code fix application"), cancellationToken).ConfigureAwait(false);

            var fixAllProvider = GetCodeFixProviders().Select(codeFixProvider => codeFixProvider.GetFixAllProvider()).Where(codeFixProvider => codeFixProvider != null).ToImmutableArray();

            if (fixAllProvider.IsEmpty)
            {
                await t1;
            }
            else
            {
                if (Debugger.IsAttached)
                {
                    await t1;
                }

                var t2 = VerifyFixAsync(Language, GetDiagnosticAnalyzers().ToImmutableArray(), GetCodeFixProviders().ToImmutableArray(), testState, batchFixedState, numberOfFixAllInDocumentIterations, FixAllAnalyzerDiagnosticsInDocumentAsync, verifier.PushContext("Fix all in document"), cancellationToken).ConfigureAwait(false);
                if (Debugger.IsAttached)
                {
                    await t2;
                }

                var t3 = VerifyFixAsync(Language, GetDiagnosticAnalyzers().ToImmutableArray(), GetCodeFixProviders().ToImmutableArray(), testState, batchFixedState, numberOfFixAllIterations, FixAllAnalyzerDiagnosticsInProjectAsync, verifier.PushContext("Fix all in project"), cancellationToken).ConfigureAwait(false);
                if (Debugger.IsAttached)
                {
                    await t3;
                }

                var t4 = VerifyFixAsync(Language, GetDiagnosticAnalyzers().ToImmutableArray(), GetCodeFixProviders().ToImmutableArray(), testState, batchFixedState, numberOfFixAllIterations, FixAllAnalyzerDiagnosticsInSolutionAsync, verifier.PushContext("Fix all in solution"), cancellationToken).ConfigureAwait(false);
                if (Debugger.IsAttached)
                {
                    await t4;
                }

                if (!Debugger.IsAttached)
                {
                    // Allow the operations to run in parallel
                    await t1;
                    await t2;
                    await t3;
                    await t4;
                }
            }
        }
Пример #6
0
 protected CodeFixTest()
 {
     FixedState      = new SolutionState(DefaultFilePathPrefix, DefaultFileExt);
     BatchFixedState = new SolutionState(DefaultFilePathPrefix, DefaultFileExt);
 }
Пример #7
0
 protected CodeRefactoringTest()
 {
     FixedState = new SolutionState(DefaultTestProjectName, Language, DefaultFilePathPrefix, DefaultFileExt);
 }
Пример #8
0
        /// <summary>
        /// Applies the <see cref="InheritanceMode"/> using a specified base state.
        /// </summary>
        /// <remarks>
        /// <para>This method evaluates <see cref="ProjectState.AdditionalFilesFactories"/>, and places the resulting
        /// additional files in the <see cref="ProjectState.AdditionalFiles"/> collection of the result before
        /// returning.</para>
        /// </remarks>
        /// <param name="baseState">The base state to inherit from, or <see langword="null"/> if the current state is
        /// the root state.</param>
        /// <param name="fixableDiagnostics">The set of diagnostic IDs to treat as fixable. Fixable diagnostics present
        /// in the <see cref="ExpectedDiagnostics"/> collection of the base state are only inherited for
        /// <see cref="StateInheritanceMode.AutoInheritAll"/>.</param>
        /// <returns>A new <see cref="SolutionState"/> representing the current state with inherited values applied
        /// where appropriate. The <see cref="InheritanceMode"/> of the result is
        /// <see cref="StateInheritanceMode.Explicit"/>.</returns>
        public SolutionState WithInheritedValuesApplied(SolutionState?baseState, ImmutableArray <string> fixableDiagnostics)
        {
            var inheritanceMode = InheritanceMode;
            var markupHandling  = MarkupHandling;

            if (inheritanceMode == null || markupHandling == null)
            {
                if (baseState == null)
                {
                    inheritanceMode = inheritanceMode ?? StateInheritanceMode.Explicit;
                    markupHandling  = markupHandling ?? MarkupMode.Allow;
                }
                else if (HasAnyContentChanges(willInherit: inheritanceMode != StateInheritanceMode.Explicit, this, baseState))
                {
                    inheritanceMode = inheritanceMode ?? StateInheritanceMode.AutoInherit;
                    markupHandling  = markupHandling ?? MarkupMode.IgnoreFixable;
                }
                else
                {
                    inheritanceMode = inheritanceMode ?? StateInheritanceMode.AutoInheritAll;
                    markupHandling  = markupHandling ?? baseState.MarkupHandling ?? MarkupMode.Allow;
                }
            }

            if (inheritanceMode != StateInheritanceMode.AutoInherit &&
                inheritanceMode != StateInheritanceMode.Explicit &&
                inheritanceMode != StateInheritanceMode.AutoInheritAll)
            {
                throw new InvalidOperationException($"Unexpected inheritance mode: {inheritanceMode}");
            }

            if (baseState?.AdditionalFilesFactories.Count > 0)
            {
                throw new InvalidOperationException("The base state should already have its inheritance state evaluated prior to its use as a base state.");
            }

            var result = new SolutionState(Name, Language, DefaultPrefix, DefaultExtension);

            result.ReferenceAssemblies = ReferenceAssemblies;
            result.OutputKind          = OutputKind;
            result.DocumentationMode   = DocumentationMode;

            if (inheritanceMode != StateInheritanceMode.Explicit && baseState != null)
            {
                result.ReferenceAssemblies ??= baseState.ReferenceAssemblies;
                result.OutputKind ??= baseState.OutputKind;
                result.DocumentationMode ??= baseState.DocumentationMode;

                if (Sources.Count == 0)
                {
                    result.Sources.AddRange(baseState.Sources);
                }

                if (AdditionalFiles.Count == 0)
                {
                    result.AdditionalFiles.AddRange(baseState.AdditionalFiles);
                }

                if (AnalyzerConfigFiles.Count == 0)
                {
                    result.AnalyzerConfigFiles.AddRange(baseState.AnalyzerConfigFiles);
                }

                if (AdditionalProjects.Count == 0)
                {
                    result.AdditionalProjects.AddRange(baseState.AdditionalProjects);
                }

                if (AdditionalProjectReferences.Count == 0)
                {
                    result.AdditionalProjectReferences.AddRange(baseState.AdditionalProjectReferences);
                }

                if (AdditionalReferences.Count == 0)
                {
                    result.AdditionalReferences.AddRange(baseState.AdditionalReferences);
                }

                if (ExpectedDiagnostics.Count == 0)
                {
                    if (inheritanceMode == StateInheritanceMode.AutoInherit)
                    {
                        result.ExpectedDiagnostics.AddRange(baseState.ExpectedDiagnostics.Where(diagnostic => !fixableDiagnostics.Contains(diagnostic.Id)));
                    }
                    else
                    {
                        result.ExpectedDiagnostics.AddRange(baseState.ExpectedDiagnostics);
                    }
                }
            }

            result.MarkupHandling  = markupHandling;
            result.InheritanceMode = StateInheritanceMode.Explicit;
            result.Sources.AddRange(Sources);
            result.AdditionalFiles.AddRange(AdditionalFiles);
            result.AnalyzerConfigFiles.AddRange(AnalyzerConfigFiles);
            result.AdditionalProjects.AddRange(AdditionalProjects);
            result.AdditionalProjectReferences.AddRange(AdditionalProjectReferences);
            result.AdditionalReferences.AddRange(AdditionalReferences);
            result.ExpectedDiagnostics.AddRange(ExpectedDiagnostics);
            result.AdditionalFiles.AddRange(AdditionalFilesFactories.SelectMany(factory => factory()));
            return(result);
        }
Пример #9
0
 protected AnalyzerTest()
 {
     TestState = new SolutionState(DefaultFilePathPrefix, DefaultFileExt);
 }
 protected CodeRefactoringTest()
 {
     FixedState = new SolutionState(DefaultFilePathPrefix, DefaultFileExt);
 }