Exemplo n.º 1
0
        internal ProjectState(ProjectState sourceState)
        {
            Name                = sourceState.Name;
            Language            = sourceState.Language;
            ReferenceAssemblies = sourceState.ReferenceAssemblies;
            OutputKind          = sourceState.OutputKind;
            DocumentationMode   = sourceState.DocumentationMode;
            DefaultPrefix       = sourceState.DefaultPrefix;
            DefaultExtension    = sourceState.DefaultExtension;
            Sources             = new SourceFileList(DefaultPrefix, DefaultExtension);

            Sources.AddRange(sourceState.Sources);
            AdditionalFiles.AddRange(sourceState.AdditionalFiles);
            AdditionalFilesFactories.AddRange(sourceState.AdditionalFilesFactories);
            AdditionalProjectReferences.AddRange(sourceState.AdditionalProjectReferences);
        }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Processes the markup syntax for this <see cref="SolutionState"/> according to the current
        /// <see cref="MarkupHandling"/>, and returns a new <see cref="SolutionState"/> with the
        /// <see cref="ProjectState.Sources"/>, <see cref="ProjectState.AdditionalFiles"/>,
        /// <see cref="ProjectState.AnalyzerConfigFiles"/>, and <see cref="ExpectedDiagnostics"/> updated accordingly.
        /// </summary>
        /// <param name="markupOptions">Additional options to apply during markup processing.</param>
        /// <param name="defaultDiagnostic">The diagnostic descriptor to use for markup spans without an explicit name,
        /// or <see langword="null"/> if no such default exists.</param>
        /// <param name="supportedDiagnostics">The diagnostics supported by analyzers used by the test.</param>
        /// <param name="fixableDiagnostics">The set of diagnostic IDs to treat as fixable. This value is only used when
        /// <see cref="MarkupHandling"/> is <see cref="MarkupMode.IgnoreFixable"/>.</param>
        /// <param name="defaultPath">The default file path for diagnostics reported in source code.</param>
        /// <returns>A new <see cref="SolutionState"/> with all markup processing completed according to the current
        /// <see cref="MarkupHandling"/>. The <see cref="MarkupHandling"/> of the returned instance is
        /// <see cref="MarkupMode.None"/>.</returns>
        /// <exception cref="InvalidOperationException">If <see cref="InheritanceMode"/> is not
        /// <see cref="StateInheritanceMode.Explicit"/>.</exception>
        public SolutionState WithProcessedMarkup(MarkupOptions markupOptions, DiagnosticDescriptor?defaultDiagnostic, ImmutableArray <DiagnosticDescriptor> supportedDiagnostics, ImmutableArray <string> fixableDiagnostics, string defaultPath)
        {
            if (InheritanceMode != StateInheritanceMode.Explicit)
            {
                throw new InvalidOperationException("Inheritance processing must complete before markup processing.");
            }

            var markupLocations = ImmutableDictionary <string, FileLinePositionSpan> .Empty;

            (var expected, var testSources)              = ProcessMarkupSources(Sources, ExpectedDiagnostics, ref markupLocations, markupOptions, defaultDiagnostic, supportedDiagnostics, fixableDiagnostics, defaultPath);
            var(additionalExpected1, additionalFiles)    = ProcessMarkupSources(AdditionalFiles.Concat(AdditionalFilesFactories.SelectMany(factory => factory())), expected, ref markupLocations, markupOptions, defaultDiagnostic, supportedDiagnostics, fixableDiagnostics, defaultPath);
            var(additionalExpected, analyzerConfigFiles) = ProcessMarkupSources(AnalyzerConfigFiles, additionalExpected1, ref markupLocations, markupOptions, defaultDiagnostic, supportedDiagnostics, fixableDiagnostics, defaultPath);

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

            result.MarkupHandling      = MarkupMode.None;
            result.InheritanceMode     = StateInheritanceMode.Explicit;
            result.ReferenceAssemblies = ReferenceAssemblies;
            result.OutputKind          = OutputKind;
            result.DocumentationMode   = DocumentationMode;
            result.Sources.AddRange(testSources);
            result.AdditionalFiles.AddRange(additionalFiles);
            result.AnalyzerConfigFiles.AddRange(analyzerConfigFiles);

            foreach (var(projectName, projectState) in AdditionalProjects)
            {
                var(correctedIntermediateDiagnostics, additionalProjectSources) = ProcessMarkupSources(projectState.Sources, additionalExpected, ref markupLocations, markupOptions, defaultDiagnostic, supportedDiagnostics, fixableDiagnostics, defaultPath);
                var(correctedDiagnostics1, additionalProjectAdditionalFiles)    = ProcessMarkupSources(projectState.AdditionalFiles.Concat(projectState.AdditionalFilesFactories.SelectMany(factory => factory())), correctedIntermediateDiagnostics, ref markupLocations, markupOptions, defaultDiagnostic, supportedDiagnostics, fixableDiagnostics, defaultPath);
                var(correctedDiagnostics, additionalProjectAnalyzerConfigFiles) = ProcessMarkupSources(projectState.AnalyzerConfigFiles, correctedDiagnostics1, ref markupLocations, markupOptions, defaultDiagnostic, supportedDiagnostics, fixableDiagnostics, defaultPath);

                var processedProjectState = new ProjectState(projectState);
                processedProjectState.Sources.Clear();
                processedProjectState.Sources.AddRange(additionalProjectSources);
                processedProjectState.AdditionalFiles.Clear();
                processedProjectState.AdditionalFilesFactories.Clear();
                processedProjectState.AdditionalFiles.AddRange(additionalProjectAdditionalFiles);
                processedProjectState.AnalyzerConfigFiles.Clear();
                processedProjectState.AnalyzerConfigFiles.AddRange(additionalProjectAnalyzerConfigFiles);

                result.AdditionalProjects.Add(projectName, processedProjectState);
                additionalExpected = correctedDiagnostics;
            }

            for (var i = 0; i < additionalExpected.Length; i++)
            {
                additionalExpected[i] = additionalExpected[i].WithAppliedMarkupLocations(markupLocations);
            }

            result.AdditionalProjectReferences.AddRange(AdditionalProjectReferences);
            result.AdditionalReferences.AddRange(AdditionalReferences);
            result.ExpectedDiagnostics.AddRange(additionalExpected);
            return(result);
        }