protected static Diagnostic[] GetSortedDiagnostics(FileAndSource[] sources, string language, DiagnosticAnalyzer analyzer, TestValidationMode validationMode = DefaultTestValidationMode, bool addLanguageSpecificCodeAnalysisReference = true, bool allowUnsafeCode = false, string projectName = TestProjectName, IEnumerable<TestAdditionalDocument> additionalFiles = null)
 {
     Tuple<Document[], bool, TextSpan?[]> documentsAndUseSpan = GetDocumentsAndSpans(sources, language, addLanguageSpecificCodeAnalysisReference, projectName, allowUnsafeCode);
     Document[] documents = documentsAndUseSpan.Item1;
     bool useSpans = documentsAndUseSpan.Item2;
     TextSpan?[] spans = documentsAndUseSpan.Item3;
     return GetSortedDiagnostics(analyzer, documents, useSpans ? spans : null, validationMode, additionalFiles);
 }
        private static Project CreateProject(
            FileAndSource[] sources,
            string language = LanguageNames.CSharp,
            bool addLanguageSpecificCodeAnalysisReference = true,
            Solution addToSolution = null,
            string projectName = TestProjectName,
            bool allowUnsafeCode = false)
        {
            string fileNamePrefix = DefaultFilePathPrefix;
            string fileExt = language == LanguageNames.CSharp ? CSharpDefaultFileExt : VisualBasicDefaultExt;
            CompilationOptions options = language == LanguageNames.CSharp
                ? (allowUnsafeCode ? s_CSharpUnsafeCodeDefaultOptions : s_CSharpDefaultOptions)
                : s_visualBasicDefaultOptions;

            ProjectId projectId = ProjectId.CreateNewId(debugName: projectName);

            Project project = (addToSolution ?? new AdhocWorkspace().CurrentSolution)
                .AddProject(projectId, projectName, projectName, language)
                .AddMetadataReference(projectId, s_corlibReference)
                .AddMetadataReference(projectId, s_systemCoreReference)
                .AddMetadataReference(projectId, s_systemXmlReference)
                .AddMetadataReference(projectId, s_systemXmlDataReference)
                .AddMetadataReference(projectId, s_codeAnalysisReference)
                .AddMetadataReference(projectId, SystemRuntimeFacadeRef)
                .AddMetadataReference(projectId, SystemThreadingFacadeRef)
                .AddMetadataReference(projectId, SystemThreadingTaskFacadeRef)
                .AddMetadataReference(projectId, s_immutableCollectionsReference)
                .AddMetadataReference(projectId, s_workspacesReference)
                .AddMetadataReference(projectId, s_systemDiagnosticsDebugReference)
                .AddMetadataReference(projectId, s_systemDataReference)
                .WithProjectCompilationOptions(projectId, options)
                .GetProject(projectId);

            // Enable IOperation Feature on the project
            var parseOptions = project.ParseOptions.WithFeatures(project.ParseOptions.Features.Concat(SpecializedCollections.SingletonEnumerable(KeyValuePair.Create("IOperation", "true"))));
            project = project.WithParseOptions(parseOptions);

            if (addLanguageSpecificCodeAnalysisReference)
            {
                MetadataReference symbolsReference = language == LanguageNames.CSharp ? s_csharpSymbolsReference : s_visualBasicSymbolsReference;
                project = project.AddMetadataReference(symbolsReference);
            }

            if (language == LanguageNames.VisualBasic)
            {
                project = project.AddMetadataReference(s_visualBasicReference);
            }

            int count = 0;
            foreach (FileAndSource source in sources)
            {
                string newFileName = source.FilePath ?? fileNamePrefix + count++ + "." + fileExt;
                DocumentId documentId = DocumentId.CreateNewId(projectId, debugName: newFileName);
                project = project.AddDocument(newFileName, SourceText.From(source.Source)).Project;
            }

            return project;
        }
        private static Tuple<Document[], bool, TextSpan?[]> GetDocumentsAndSpans(FileAndSource[] sources, string language, bool addLanguageSpecificCodeAnalysisReference = true, string projectName = TestProjectName, bool allowUnsafeCode = false)
        {
            Assert.True(language == LanguageNames.CSharp || language == LanguageNames.VisualBasic, "Unsupported language");

            var spans = new TextSpan?[sources.Length];
            bool useSpans = false;

            for (int i = 0; i < sources.Length; i++)
            {
                string source;
                int? pos;
                TextSpan? span;
                MarkupTestFile.GetPositionAndSpan(sources[i].Source, out source, out pos, out span);

                sources[i].Source = source;
                spans[i] = span;

                if (span != null)
                {
                    useSpans = true;
                }
            }

            Project project = CreateProject(sources, language, addLanguageSpecificCodeAnalysisReference, null, projectName, allowUnsafeCode);
            Document[] documents = project.Documents.ToArray();
            Assert.Equal(sources.Length, documents.Length);

            return Tuple.Create(documents, useSpans, spans);
        }
 private void Verify(FileAndSource[] sources, string language, DiagnosticAnalyzer analyzer, TestValidationMode validationMode, bool allowUnsafeCode, params DiagnosticResult[] expected)
 {
     var diagnostics = GetSortedDiagnostics(sources, language, analyzer, validationMode, allowUnsafeCode: allowUnsafeCode);
     diagnostics.Verify(analyzer, PrintActualDiagnosticsOnFailure, ExpectedDiagnosticsAssertionTemplate, expected);
 }
 protected void VerifyBasic(FileAndSource[] sources, params DiagnosticResult[] expected)
 {
     Verify(sources, LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), DefaultTestValidationMode, false, expected);
 }
 protected void VerifyCSharp(FileAndSource[] sources, params DiagnosticResult[] expected)
 {
     Verify(sources, LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), DefaultTestValidationMode, false, expected);
 }