internal static void LogDiagnostic(Diagnostic diagnostic, CultureInfo culture, ErrorLogger errorLogger) { if (errorLogger != null) { #pragma warning disable RS0013 // We need to invoke Diagnostic.Descriptor here to log all the metadata properties of the diagnostic. var issue = new Issue(diagnostic.Id, diagnostic.GetMessage(culture), diagnostic.Descriptor.Description.ToString(culture), diagnostic.Descriptor.Title.ToString(culture), diagnostic.Category, diagnostic.Descriptor.HelpLinkUri, diagnostic.IsEnabledByDefault, diagnostic.IsSuppressed, diagnostic.DefaultSeverity, diagnostic.Severity, diagnostic.WarningLevel, diagnostic.Location, diagnostic.AdditionalLocations, diagnostic.CustomTags, diagnostic.Properties); #pragma warning restore RS0013 errorLogger.LogIssue(issue); } }
public static Value Create(string value, ErrorLogger owner) { return new StringValue(value, owner); }
public bool ReportErrors(IEnumerable<Diagnostic> diagnostics, TextWriter consoleOutput, ErrorLogger errorLogger) { bool hasErrors = false; foreach (var diag in diagnostics) { if (_reportedDiagnostics.Contains(diag)) { // TODO: This invariant fails (at least) in the case where we see a member declaration "x = 1;". // First we attempt to parse a member declaration starting at "x". When we see the "=", we // create an IncompleteMemberSyntax with return type "x" and an error at the location of the "x". // Then we parse a member declaration starting at "=". This is an invalid member declaration start // so we attach an error to the "=" and attach it (plus following tokens) to the IncompleteMemberSyntax // we previously created. //this assert isn't valid if we change the design to not bail out after each phase. //System.Diagnostics.Debug.Assert(diag.Severity != DiagnosticSeverity.Error); continue; } else if (diag.Severity == DiagnosticSeverity.Hidden) { // Not reported from the command-line compiler. continue; } // We want to report diagnostics with source suppression in the error log file. // However, these diagnostics should not be reported on the console output. ErrorLogger.LogDiagnostic(diag, this.Culture, errorLogger); if (diag.IsSuppressed) { continue; } consoleOutput.WriteLine(DiagnosticFormatter.Format(diag, this.Culture)); if (diag.Severity == DiagnosticSeverity.Error) { hasErrors = true; } _reportedDiagnostics.Add(diag); } return hasErrors; }
private int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, CancellationToken cancellationToken) { Debug.Assert(!Arguments.IsScriptRunner); cancellationToken.ThrowIfCancellationRequested(); if (Arguments.DisplayLogo) { PrintLogo(consoleOutput); } if (Arguments.DisplayHelp) { PrintHelp(consoleOutput); return Succeeded; } if (ReportErrors(Arguments.Errors, consoleOutput, errorLogger)) { return Failed; } var touchedFilesLogger = (Arguments.TouchedFilesPath != null) ? new TouchedFileLogger() : null; Compilation compilation = CreateCompilation(consoleOutput, touchedFilesLogger, errorLogger); if (compilation == null) { return Failed; } var diagnostics = new List<DiagnosticInfo>(); var analyzers = ResolveAnalyzersFromArguments(diagnostics, MessageProvider, touchedFilesLogger); var additionalTextFiles = ResolveAdditionalFilesFromArguments(diagnostics, MessageProvider, touchedFilesLogger); if (ReportErrors(diagnostics, consoleOutput, errorLogger)) { return Failed; } cancellationToken.ThrowIfCancellationRequested(); CancellationTokenSource analyzerCts = null; AnalyzerManager analyzerManager = null; AnalyzerDriver analyzerDriver = null; try { Func<ImmutableArray<Diagnostic>> getAnalyzerDiagnostics = null; ConcurrentSet<Diagnostic> analyzerExceptionDiagnostics = null; if (!analyzers.IsDefaultOrEmpty) { analyzerCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); analyzerManager = new AnalyzerManager(); analyzerExceptionDiagnostics = new ConcurrentSet<Diagnostic>(); Action<Diagnostic> addExceptionDiagnostic = diagnostic => analyzerExceptionDiagnostics.Add(diagnostic); var analyzerOptions = new AnalyzerOptions(ImmutableArray<AdditionalText>.CastUp(additionalTextFiles)); analyzerDriver = AnalyzerDriver.CreateAndAttachToCompilation(compilation, analyzers, analyzerOptions, analyzerManager, addExceptionDiagnostic, Arguments.ReportAnalyzer, out compilation, analyzerCts.Token); getAnalyzerDiagnostics = () => analyzerDriver.GetDiagnosticsAsync(compilation).Result; } // Print the diagnostics produced during the parsing stage and exit if there were any errors. if (ReportErrors(compilation.GetParseDiagnostics(), consoleOutput, errorLogger)) { return Failed; } if (ReportErrors(compilation.GetDeclarationDiagnostics(), consoleOutput, errorLogger)) { return Failed; } EmitResult emitResult; // NOTE: as native compiler does, we generate the documentation file // NOTE: 'in place', replacing the contents of the file if it exists string finalPeFilePath; string finalPdbFilePath; string finalXmlFilePath; Stream xmlStreamOpt = null; cancellationToken.ThrowIfCancellationRequested(); finalXmlFilePath = Arguments.DocumentationPath; if (finalXmlFilePath != null) { xmlStreamOpt = OpenFile(finalXmlFilePath, consoleOutput, PortableShim.FileMode.OpenOrCreate, PortableShim.FileAccess.Write, PortableShim.FileShare.ReadWriteBitwiseOrDelete); if (xmlStreamOpt == null) { return Failed; } xmlStreamOpt.SetLength(0); } cancellationToken.ThrowIfCancellationRequested(); IEnumerable<DiagnosticInfo> errors; using (var win32ResourceStreamOpt = GetWin32Resources(Arguments, compilation, out errors)) using (xmlStreamOpt) { if (ReportErrors(errors, consoleOutput, errorLogger)) { return Failed; } cancellationToken.ThrowIfCancellationRequested(); string outputName = GetOutputFileName(compilation, cancellationToken); finalPeFilePath = Path.Combine(Arguments.OutputDirectory, outputName); finalPdbFilePath = Arguments.PdbPath ?? Path.ChangeExtension(finalPeFilePath, ".pdb"); // NOTE: Unlike the PDB path, the XML doc path is not embedded in the assembly, so we don't need to pass it to emit. var emitOptions = Arguments.EmitOptions. WithOutputNameOverride(outputName). WithPdbFilePath(finalPdbFilePath); using (var peStreamProvider = new CompilerEmitStreamProvider(this, finalPeFilePath)) using (var pdbStreamProviderOpt = Arguments.EmitPdb ? new CompilerEmitStreamProvider(this, finalPdbFilePath) : null) { emitResult = compilation.Emit( peStreamProvider, pdbStreamProviderOpt, (xmlStreamOpt != null) ? new Compilation.SimpleEmitStreamProvider(xmlStreamOpt) : null, (win32ResourceStreamOpt != null) ? new Compilation.SimpleEmitStreamProvider(win32ResourceStreamOpt) : null, Arguments.ManifestResources, emitOptions, debugEntryPoint: null, getHostDiagnostics: getAnalyzerDiagnostics, cancellationToken: cancellationToken); if (emitResult.Success && touchedFilesLogger != null) { if (pdbStreamProviderOpt != null) { touchedFilesLogger.AddWritten(finalPdbFilePath); } touchedFilesLogger.AddWritten(finalPeFilePath); } } } GenerateSqmData(Arguments.CompilationOptions, emitResult.Diagnostics); if (ReportErrors(emitResult.Diagnostics, consoleOutput, errorLogger)) { return Failed; } cancellationToken.ThrowIfCancellationRequested(); if (analyzerExceptionDiagnostics != null && ReportErrors(analyzerExceptionDiagnostics, consoleOutput, errorLogger)) { return Failed; } bool errorsReadingAdditionalFiles = false; foreach (var additionalFile in additionalTextFiles) { if (ReportErrors(additionalFile.Diagnostics, consoleOutput, errorLogger)) { errorsReadingAdditionalFiles = true; } } if (errorsReadingAdditionalFiles) { return Failed; } cancellationToken.ThrowIfCancellationRequested(); if (Arguments.TouchedFilesPath != null) { Debug.Assert(touchedFilesLogger != null); if (finalXmlFilePath != null) { touchedFilesLogger.AddWritten(finalXmlFilePath); } var readStream = OpenFile(Arguments.TouchedFilesPath + ".read", consoleOutput, mode: PortableShim.FileMode.OpenOrCreate); if (readStream == null) { return Failed; } using (var writer = new StreamWriter(readStream)) { touchedFilesLogger.WriteReadPaths(writer); } var writtenStream = OpenFile(Arguments.TouchedFilesPath + ".write", consoleOutput, mode: PortableShim.FileMode.OpenOrCreate); if (writtenStream == null) { return Failed; } using (var writer = new StreamWriter(writtenStream)) { touchedFilesLogger.WriteWrittenPaths(writer); } } } finally { // At this point analyzers are already complete in which case this is a no-op. Or they are // still running because the compilation failed before all of the compilation events were // raised. In the latter case the driver, and all its associated state, will be waiting around // for events that are never coming. Cancel now and let the clean up process begin. if (analyzerCts != null) { analyzerCts.Cancel(); if (analyzerManager != null) { // Clear cached analyzer descriptors and unregister exception handlers hooked up to the LocalizableString fields of the associated descriptors. analyzerManager.ClearAnalyzerState(analyzers); } if (Arguments.ReportAnalyzer && analyzerDriver != null && compilation != null) { ReportAnalyzerExecutionTime(consoleOutput, analyzerDriver, Culture, compilation.Options.ConcurrentBuild); } } } return Succeeded; }
public IntegerValue(int value, ErrorLogger owner) : base(owner) { _value = value; }
public bool ReportErrors(IEnumerable<DiagnosticInfo> diagnostics, TextWriter consoleOutput, ErrorLogger errorLoggerOpt) => ReportErrors(diagnostics.Select(info => Diagnostic.Create(info)), consoleOutput, errorLoggerOpt);
public abstract Compilation CreateCompilation(TextWriter consoleOutput, TouchedFileLogger touchedFilesLogger, ErrorLogger errorLogger);
public static Value Create(ImmutableArray<Value> values, ErrorLogger owner) { return new ListValue(values, owner); }
public bool ReportErrors(IEnumerable <DiagnosticInfo> diagnostics, TextWriter consoleOutput, ErrorLogger errorLogger) { bool hasErrors = false; if (diagnostics != null && diagnostics.Any()) { foreach (var diagnostic in diagnostics) { if (diagnostic.Severity == DiagnosticSeverity.Hidden) { // Not reported from the command-line compiler. continue; } PrintError(diagnostic, consoleOutput); ErrorLogger.LogDiagnostic(Diagnostic.Create(diagnostic), this.Culture, errorLogger); if (diagnostic.Severity == DiagnosticSeverity.Error) { hasErrors = true; } } } return(hasErrors); }
private int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, CancellationToken cancellationToken) { Debug.Assert(!Arguments.IsInteractive); cancellationToken.ThrowIfCancellationRequested(); if (Arguments.DisplayLogo) { PrintLogo(consoleOutput); } if (Arguments.DisplayHelp) { PrintHelp(consoleOutput); return(Succeeded); } if (ReportErrors(Arguments.Errors, consoleOutput, errorLogger)) { return(Failed); } var touchedFilesLogger = (Arguments.TouchedFilesPath != null) ? new TouchedFileLogger() : null; Compilation compilation = CreateCompilation(consoleOutput, touchedFilesLogger, errorLogger); if (compilation == null) { return(Failed); } var diagnostics = new List <DiagnosticInfo>(); var analyzers = ResolveAnalyzersFromArguments(diagnostics, MessageProvider, touchedFilesLogger); var additionalTextFiles = ResolveAdditionalFilesFromArguments(diagnostics, MessageProvider, touchedFilesLogger); if (ReportErrors(diagnostics, consoleOutput, errorLogger)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); CancellationTokenSource analyzerCts = null; AnalyzerManager analyzerManager = null; try { Func <ImmutableArray <Diagnostic> > getAnalyzerDiagnostics = null; if (!analyzers.IsDefaultOrEmpty) { analyzerCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); analyzerManager = new AnalyzerManager(); var analyzerExceptionDiagnostics = new ConcurrentSet <Diagnostic>(); Action <Diagnostic> addExceptionDiagnostic = diagnostic => analyzerExceptionDiagnostics.Add(diagnostic); var analyzerOptions = new AnalyzerOptions(ImmutableArray.Create <AdditionalText, AdditionalTextFile>(additionalTextFiles)); var analyzerDriver = AnalyzerDriver.Create(compilation, analyzers, analyzerOptions, analyzerManager, addExceptionDiagnostic, out compilation, analyzerCts.Token); getAnalyzerDiagnostics = () => { var analyzerDiagnostics = analyzerDriver.GetDiagnosticsAsync().Result; return(analyzerDiagnostics.AddRange(analyzerExceptionDiagnostics)); }; } // Print the diagnostics produced during the parsing stage and exit if there were any errors. if (ReportErrors(compilation.GetParseDiagnostics(), consoleOutput, errorLogger)) { return(Failed); } if (ReportErrors(compilation.GetDeclarationDiagnostics(), consoleOutput, errorLogger)) { return(Failed); } EmitResult emitResult; // NOTE: as native compiler does, we generate the documentation file // NOTE: 'in place', replacing the contents of the file if it exists string finalOutputPath; string finalPdbFilePath; string finalXmlFilePath; FileStream xmlStreamOpt = null; cancellationToken.ThrowIfCancellationRequested(); finalXmlFilePath = Arguments.DocumentationPath; if (finalXmlFilePath != null) { xmlStreamOpt = OpenFile(finalXmlFilePath, consoleOutput, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete); if (xmlStreamOpt == null) { return(Failed); } xmlStreamOpt.SetLength(0); } cancellationToken.ThrowIfCancellationRequested(); IEnumerable <DiagnosticInfo> errors; using (var win32ResourceStreamOpt = GetWin32Resources(Arguments, compilation, out errors)) using (xmlStreamOpt) { if (ReportErrors(errors, consoleOutput, errorLogger)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); string outputName = GetOutputFileName(compilation, cancellationToken); finalOutputPath = Path.Combine(Arguments.OutputDirectory, outputName); finalPdbFilePath = Arguments.PdbPath ?? Path.ChangeExtension(finalOutputPath, ".pdb"); // NOTE: Unlike the PDB path, the XML doc path is not embedded in the assembly, so we don't need to pass it to emit. var emitOptions = Arguments.EmitOptions. WithOutputNameOverride(outputName). WithPdbFilePath(finalPdbFilePath); using (var peStreamProvider = new CompilerEmitStreamProvider(this, finalOutputPath)) using (var pdbStreamProviderOpt = Arguments.EmitPdb ? new CompilerEmitStreamProvider(this, finalPdbFilePath) : null) { emitResult = compilation.Emit( peStreamProvider, pdbStreamProviderOpt, (xmlStreamOpt != null) ? new Compilation.SimpleEmitStreamProvider(xmlStreamOpt) : null, (win32ResourceStreamOpt != null) ? new Compilation.SimpleEmitStreamProvider(win32ResourceStreamOpt) : null, Arguments.ManifestResources, emitOptions, getAnalyzerDiagnostics, cancellationToken); if (emitResult.Success && touchedFilesLogger != null) { if (pdbStreamProviderOpt != null) { touchedFilesLogger.AddWritten(finalPdbFilePath); } touchedFilesLogger.AddWritten(finalOutputPath); } } } GenerateSqmData(Arguments.CompilationOptions, emitResult.Diagnostics); if (ReportErrors(emitResult.Diagnostics, consoleOutput, errorLogger)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); bool errorsReadingAdditionalFiles = false; foreach (var additionalFile in additionalTextFiles) { if (ReportErrors(additionalFile.Diagnostics, consoleOutput, errorLogger)) { errorsReadingAdditionalFiles = true; } } if (errorsReadingAdditionalFiles) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); if (Arguments.TouchedFilesPath != null) { Debug.Assert(touchedFilesLogger != null); if (finalXmlFilePath != null) { touchedFilesLogger.AddWritten(finalXmlFilePath); } var readStream = OpenFile(Arguments.TouchedFilesPath + ".read", consoleOutput, FileMode.OpenOrCreate); if (readStream == null) { return(Failed); } using (var writer = new StreamWriter(readStream)) { touchedFilesLogger.WriteReadPaths(writer); } var writtenStream = OpenFile(Arguments.TouchedFilesPath + ".write", consoleOutput, FileMode.OpenOrCreate); if (writtenStream == null) { return(Failed); } using (var writer = new StreamWriter(writtenStream)) { touchedFilesLogger.WriteWrittenPaths(writer); } } } finally { // At this point analyzers are already complete in which case this is a no-op. Or they are // still running because the compilation failed before all of the compilation events were // raised. In the latter case the driver, and all its associated state, will be waiting around // for events that are never coming. Cancel now and let the clean up process begin. if (analyzerCts != null) { analyzerCts.Cancel(); // Clear cached analyzer descriptors and unregister exception handlers hooked up to the LocalizableString fields of the associated descriptors. analyzerManager.ClearAnalyzerState(analyzers); } } return(Succeeded); }
public bool ReportErrors(IEnumerable <Diagnostic> diagnostics, TextWriter consoleOutput, ErrorLogger errorLogger) { bool hasErrors = false; foreach (var diag in diagnostics) { if (_reportedDiagnostics.Contains(diag)) { // TODO: This invariant fails (at least) in the case where we see a member declaration "x = 1;". // First we attempt to parse a member declaration starting at "x". When we see the "=", we // create an IncompleteMemberSyntax with return type "x" and an error at the location of the "x". // Then we parse a member declaration starting at "=". This is an invalid member declaration start // so we attach an error to the "=" and attach it (plus following tokens) to the IncompleteMemberSyntax // we previously created. //this assert isn't valid if we change the design to not bail out after each phase. //System.Diagnostics.Debug.Assert(diag.Severity != DiagnosticSeverity.Error); continue; } else if (diag.Severity == DiagnosticSeverity.Hidden) { // Not reported from the command-line compiler. continue; } consoleOutput.WriteLine(DiagnosticFormatter.Format(diag, this.Culture)); ErrorLogger.LogDiagnostic(diag, this.Culture, errorLogger); if (diag.Severity == DiagnosticSeverity.Error) { hasErrors = true; } _reportedDiagnostics.Add(diag); } return(hasErrors); }
internal int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, CancellationToken cancellationToken) { Debug.Assert(!Arguments.IsScriptRunner); cancellationToken.ThrowIfCancellationRequested(); if (Arguments.DisplayVersion) { PrintVersion(consoleOutput); return(Succeeded); } if (Arguments.DisplayLogo) { PrintLogo(consoleOutput); } if (Arguments.DisplayHelp) { PrintHelp(consoleOutput); return(Succeeded); } if (ReportErrors(Arguments.Errors, consoleOutput, errorLogger)) { return(Failed); } var touchedFilesLogger = (Arguments.TouchedFilesPath != null) ? new TouchedFileLogger() : null; Compilation compilation = CreateCompilation(consoleOutput, touchedFilesLogger, errorLogger); if (compilation == null) { return(Failed); } var diagnosticInfos = new List <DiagnosticInfo>(); ImmutableArray <DiagnosticAnalyzer> analyzers = ResolveAnalyzersFromArguments(diagnosticInfos, MessageProvider); var additionalTextFiles = ResolveAdditionalFilesFromArguments(diagnosticInfos, MessageProvider, touchedFilesLogger); if (ReportErrors(diagnosticInfos, consoleOutput, errorLogger)) { return(Failed); } var diagnostics = new List <Diagnostic>(); ImmutableArray <EmbeddedText> embeddedTexts = AcquireEmbeddedTexts(compilation, diagnostics); if (ReportErrors(diagnostics, consoleOutput, errorLogger)) { return(Failed); } bool reportAnalyzer = false; CancellationTokenSource analyzerCts = null; AnalyzerManager analyzerManager = null; AnalyzerDriver analyzerDriver = null; try { // Print the diagnostics produced during the parsing stage and exit if there were any errors. if (ReportErrors(compilation.GetParseDiagnostics(), consoleOutput, errorLogger)) { return(Failed); } ConcurrentSet <Diagnostic> analyzerExceptionDiagnostics = null; if (!analyzers.IsEmpty) { analyzerCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); analyzerManager = new AnalyzerManager(); analyzerExceptionDiagnostics = new ConcurrentSet <Diagnostic>(); Action <Diagnostic> addExceptionDiagnostic = diagnostic => analyzerExceptionDiagnostics.Add(diagnostic); var analyzerOptions = new AnalyzerOptions(ImmutableArray <AdditionalText> .CastUp(additionalTextFiles)); analyzerDriver = AnalyzerDriver.CreateAndAttachToCompilation(compilation, analyzers, analyzerOptions, analyzerManager, addExceptionDiagnostic, Arguments.ReportAnalyzer, out compilation, analyzerCts.Token); reportAnalyzer = Arguments.ReportAnalyzer && !analyzers.IsEmpty; } if (ReportErrors(compilation.GetDeclarationDiagnostics(), consoleOutput, errorLogger)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); string outputName = GetOutputFileName(compilation, cancellationToken); var finalPeFilePath = Path.Combine(Arguments.OutputDirectory, outputName); var finalPdbFilePath = Arguments.PdbPath ?? Path.ChangeExtension(finalPeFilePath, ".pdb"); var finalXmlFilePath = Arguments.DocumentationPath; var diagnosticBag = DiagnosticBag.GetInstance(); Stream sourceLinkStreamOpt = null; try { // NOTE: Unlike the PDB path, the XML doc path is not embedded in the assembly, so we don't need to pass it to emit. var emitOptions = Arguments.EmitOptions. WithOutputNameOverride(outputName). WithPdbFilePath(finalPdbFilePath); // The PDB path is emitted in it's entirety into the PE. This makes it impossible to have deterministic // builds that occur in different source directories. To enable this we shave all path information from // the PDB when specified by the user. // // This is a temporary work around to allow us to make progress with determinism. The following issue // tracks getting an official solution here. // // https://github.com/dotnet/roslyn/issues/9813 if (Arguments.ParseOptions.Features.ContainsKey("pdb-path-determinism") && !string.IsNullOrEmpty(emitOptions.PdbFilePath)) { emitOptions = emitOptions.WithPdbFilePath(Path.GetFileName(emitOptions.PdbFilePath)); } if (Arguments.SourceLink != null) { sourceLinkStreamOpt = OpenFile(Arguments.SourceLink, consoleOutput, FileMode.Open, FileAccess.Read, FileShare.Read); } var moduleBeingBuilt = compilation.CheckOptionsAndCreateModuleBuilder( diagnosticBag, Arguments.ManifestResources, emitOptions, debugEntryPoint: null, sourceLinkStream: sourceLinkStreamOpt, embeddedTexts: embeddedTexts, testData: null, cancellationToken: cancellationToken); if (moduleBeingBuilt != null) { bool success; try { success = compilation.CompileMethods( moduleBeingBuilt, Arguments.EmitPdb, diagnosticBag, filterOpt: null, cancellationToken: cancellationToken); if (success) { // NOTE: as native compiler does, we generate the documentation file // NOTE: 'in place', replacing the contents of the file if it exists Stream xmlStreamOpt = null; if (finalXmlFilePath != null) { xmlStreamOpt = OpenFile(finalXmlFilePath, consoleOutput, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete); if (xmlStreamOpt == null) { return(Failed); } xmlStreamOpt.SetLength(0); } using (xmlStreamOpt) { IEnumerable <DiagnosticInfo> errors; using (var win32ResourceStreamOpt = GetWin32Resources(Arguments, compilation, out errors)) { if (ReportErrors(errors, consoleOutput, errorLogger)) { return(Failed); } success = compilation.GenerateResourcesAndDocumentationComments( moduleBeingBuilt, xmlStreamOpt, win32ResourceStreamOpt, diagnosticBag, cancellationToken); } // only report unused usings if we have success. if (success) { compilation.ReportUnusedImports(null, diagnosticBag, cancellationToken); } } } compilation.CompleteTrees(null); if (analyzerDriver != null) { // GetDiagnosticsAsync is called after ReportUnusedImports // since that method calls EventQueue.TryComplete. Without // TryComplete, we may miss diagnostics. var hostDiagnostics = analyzerDriver.GetDiagnosticsAsync(compilation).Result; diagnosticBag.AddRange(hostDiagnostics); if (hostDiagnostics.Any(IsReportedError)) { success = false; } } } finally { moduleBeingBuilt.CompilationFinished(); } if (success) { bool emitPdbFile = Arguments.EmitPdb && emitOptions.DebugInformationFormat != Emit.DebugInformationFormat.Embedded; using (var peStreamProvider = new CompilerEmitStreamProvider(this, finalPeFilePath)) using (var pdbStreamProviderOpt = emitPdbFile ? new CompilerEmitStreamProvider(this, finalPdbFilePath) : null) { success = compilation.SerializeToPeStream( moduleBeingBuilt, peStreamProvider, pdbStreamProviderOpt, testSymWriterFactory: null, diagnostics: diagnosticBag, metadataOnly: emitOptions.EmitMetadataOnly, cancellationToken: cancellationToken); if (success && touchedFilesLogger != null) { if (pdbStreamProviderOpt != null) { touchedFilesLogger.AddWritten(finalPdbFilePath); } touchedFilesLogger.AddWritten(finalPeFilePath); } } } } var compileAndEmitDiagnostics = diagnosticBag.ToReadOnly(); if (ReportErrors(compileAndEmitDiagnostics, consoleOutput, errorLogger)) { return(Failed); } } finally { diagnosticBag.Free(); sourceLinkStreamOpt?.Dispose(); } cancellationToken.ThrowIfCancellationRequested(); if (analyzerExceptionDiagnostics != null && ReportErrors(analyzerExceptionDiagnostics, consoleOutput, errorLogger)) { return(Failed); } bool errorsReadingAdditionalFiles = false; foreach (var additionalFile in additionalTextFiles) { if (ReportErrors(additionalFile.Diagnostics, consoleOutput, errorLogger)) { errorsReadingAdditionalFiles = true; } } if (errorsReadingAdditionalFiles) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); if (Arguments.TouchedFilesPath != null) { Debug.Assert(touchedFilesLogger != null); if (finalXmlFilePath != null) { touchedFilesLogger.AddWritten(finalXmlFilePath); } var readStream = OpenFile(Arguments.TouchedFilesPath + ".read", consoleOutput, mode: FileMode.OpenOrCreate); if (readStream == null) { return(Failed); } using (var writer = new StreamWriter(readStream)) { touchedFilesLogger.WriteReadPaths(writer); } var writtenStream = OpenFile(Arguments.TouchedFilesPath + ".write", consoleOutput, mode: FileMode.OpenOrCreate); if (writtenStream == null) { return(Failed); } using (var writer = new StreamWriter(writtenStream)) { touchedFilesLogger.WriteWrittenPaths(writer); } } } finally { // At this point analyzers are already complete in which case this is a no-op. Or they are // still running because the compilation failed before all of the compilation events were // raised. In the latter case the driver, and all its associated state, will be waiting around // for events that are never coming. Cancel now and let the clean up process begin. if (analyzerCts != null) { analyzerCts.Cancel(); if (analyzerManager != null) { // Clear cached analyzer descriptors and unregister exception handlers hooked up to the LocalizableString fields of the associated descriptors. analyzerManager.ClearAnalyzerState(analyzers); } if (reportAnalyzer) { ReportAnalyzerExecutionTime(consoleOutput, analyzerDriver, Culture, compilation.Options.ConcurrentBuild); } } } return(Succeeded); }
public bool ReportErrors(IEnumerable <DiagnosticInfo> diagnostics, TextWriter consoleOutput, ErrorLogger errorLoggerOpt) => ReportErrors(diagnostics.Select(info => Diagnostic.Create(info)), consoleOutput, errorLoggerOpt);
public static Value Create(int value, ErrorLogger owner) { return new IntegerValue(value, owner); }
internal static void LogDiagnostic(Diagnostic diagnostic, CultureInfo culture, ErrorLogger errorLogger) { if (errorLogger != null) { #pragma warning disable RS0013 // We need to invoke Diagnostic.Descriptor here to log all the metadata properties of the diagnostic. var issue = new Issue(diagnostic.Id, diagnostic.GetMessage(culture), diagnostic.Descriptor.Description.ToString(culture), diagnostic.Descriptor.Title.ToString(culture), diagnostic.Category, diagnostic.Descriptor.HelpLinkUri, diagnostic.IsEnabledByDefault, diagnostic.DefaultSeverity, diagnostic.Severity, diagnostic.WarningLevel, diagnostic.Location, diagnostic.AdditionalLocations, diagnostic.CustomTags, diagnostic.Properties); #pragma warning restore RS0013 errorLogger.LogIssue(issue); } }
public static Value Create(ImmutableArray<KeyValuePair<string, Value>> values, ErrorLogger owner) { return new GroupValue(values, owner); }
public ListValue(ImmutableArray <Value> values, ErrorLogger owner) : base(owner) { _values = values; }
public StringValue(string value, ErrorLogger owner) : base(owner) { _value = value; }
protected Value(ErrorLogger owner) { Owner = owner; }
public GroupValue(ImmutableArray<KeyValuePair<string, Value>> keyValuePairs, ErrorLogger owner) : base(owner) { _keyValuePairs = keyValuePairs; }
public static Value Create(string value, ErrorLogger owner) { return(new StringValue(value, owner)); }
internal int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, CancellationToken cancellationToken) { Debug.Assert(!Arguments.IsScriptRunner); cancellationToken.ThrowIfCancellationRequested(); if (Arguments.DisplayVersion) { PrintVersion(consoleOutput); return Succeeded; } if (Arguments.DisplayLogo) { PrintLogo(consoleOutput); } if (Arguments.DisplayHelp) { PrintHelp(consoleOutput); return Succeeded; } if (ReportErrors(Arguments.Errors, consoleOutput, errorLogger)) { return Failed; } var touchedFilesLogger = (Arguments.TouchedFilesPath != null) ? new TouchedFileLogger() : null; Compilation compilation = CreateCompilation(consoleOutput, touchedFilesLogger, errorLogger); if (compilation == null) { return Failed; } var diagnosticInfos = new List<DiagnosticInfo>(); ImmutableArray<DiagnosticAnalyzer> analyzers = ResolveAnalyzersFromArguments(diagnosticInfos, MessageProvider); var additionalTextFiles = ResolveAdditionalFilesFromArguments(diagnosticInfos, MessageProvider, touchedFilesLogger); if (ReportErrors(diagnosticInfos, consoleOutput, errorLogger)) { return Failed; } var diagnostics = new List<Diagnostic>(); ImmutableArray<EmbeddedText> embeddedTexts = AcquireEmbeddedTexts(compilation, diagnostics); if (ReportErrors(diagnostics, consoleOutput, errorLogger)) { return Failed; } bool reportAnalyzer = false; CancellationTokenSource analyzerCts = null; AnalyzerManager analyzerManager = null; AnalyzerDriver analyzerDriver = null; try { // Print the diagnostics produced during the parsing stage and exit if there were any errors. if (ReportErrors(compilation.GetParseDiagnostics(), consoleOutput, errorLogger)) { return Failed; } ConcurrentSet<Diagnostic> analyzerExceptionDiagnostics = null; if (!analyzers.IsEmpty) { analyzerCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); analyzerManager = new AnalyzerManager(); analyzerExceptionDiagnostics = new ConcurrentSet<Diagnostic>(); Action<Diagnostic> addExceptionDiagnostic = diagnostic => analyzerExceptionDiagnostics.Add(diagnostic); var analyzerOptions = new AnalyzerOptions(ImmutableArray<AdditionalText>.CastUp(additionalTextFiles)); analyzerDriver = AnalyzerDriver.CreateAndAttachToCompilation(compilation, analyzers, analyzerOptions, analyzerManager, addExceptionDiagnostic, Arguments.ReportAnalyzer, out compilation, analyzerCts.Token); reportAnalyzer = Arguments.ReportAnalyzer && !analyzers.IsEmpty; } if (ReportErrors(compilation.GetDeclarationDiagnostics(), consoleOutput, errorLogger)) { return Failed; } cancellationToken.ThrowIfCancellationRequested(); string outputName = GetOutputFileName(compilation, cancellationToken); var finalPeFilePath = Path.Combine(Arguments.OutputDirectory, outputName); var finalPdbFilePath = Arguments.PdbPath ?? Path.ChangeExtension(finalPeFilePath, ".pdb"); var finalXmlFilePath = Arguments.DocumentationPath; var diagnosticBag = DiagnosticBag.GetInstance(); Stream sourceLinkStreamOpt = null; try { // NOTE: Unlike the PDB path, the XML doc path is not embedded in the assembly, so we don't need to pass it to emit. var emitOptions = Arguments.EmitOptions. WithOutputNameOverride(outputName). WithPdbFilePath(finalPdbFilePath); // The PDB path is emitted in it's entirety into the PE. This makes it impossible to have deterministic // builds that occur in different source directories. To enable this we shave all path information from // the PDB when specified by the user. // // This is a temporary work around to allow us to make progress with determinism. The following issue // tracks getting an official solution here. // // https://github.com/dotnet/roslyn/issues/9813 if (Arguments.ParseOptions.Features.ContainsKey("pdb-path-determinism") && !string.IsNullOrEmpty(emitOptions.PdbFilePath)) { emitOptions = emitOptions.WithPdbFilePath(Path.GetFileName(emitOptions.PdbFilePath)); } if (Arguments.SourceLink != null) { sourceLinkStreamOpt = OpenFile(Arguments.SourceLink, consoleOutput, FileMode.Open, FileAccess.Read, FileShare.Read); } var moduleBeingBuilt = compilation.CheckOptionsAndCreateModuleBuilder( diagnosticBag, Arguments.ManifestResources, emitOptions, debugEntryPoint: null, sourceLinkStream: sourceLinkStreamOpt, embeddedTexts: embeddedTexts, testData: null, cancellationToken: cancellationToken); if (moduleBeingBuilt != null) { bool success; try { success = compilation.CompileMethods( moduleBeingBuilt, Arguments.EmitPdb, diagnosticBag, filterOpt: null, cancellationToken: cancellationToken); if (success) { // NOTE: as native compiler does, we generate the documentation file // NOTE: 'in place', replacing the contents of the file if it exists Stream xmlStreamOpt = null; if (finalXmlFilePath != null) { xmlStreamOpt = OpenFile(finalXmlFilePath, consoleOutput, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete); if (xmlStreamOpt == null) { return Failed; } xmlStreamOpt.SetLength(0); } using (xmlStreamOpt) { IEnumerable<DiagnosticInfo> errors; using (var win32ResourceStreamOpt = GetWin32Resources(Arguments, compilation, out errors)) { if (ReportErrors(errors, consoleOutput, errorLogger)) { return Failed; } success = compilation.GenerateResourcesAndDocumentationComments( moduleBeingBuilt, xmlStreamOpt, win32ResourceStreamOpt, diagnosticBag, cancellationToken); } // only report unused usings if we have success. if (success) { compilation.ReportUnusedImports(null, diagnosticBag, cancellationToken); } } } compilation.CompleteTrees(null); if (analyzerDriver != null) { // GetDiagnosticsAsync is called after ReportUnusedImports // since that method calls EventQueue.TryComplete. Without // TryComplete, we may miss diagnostics. var hostDiagnostics = analyzerDriver.GetDiagnosticsAsync(compilation).Result; diagnosticBag.AddRange(hostDiagnostics); if (hostDiagnostics.Any(IsReportedError)) { success = false; } } } finally { moduleBeingBuilt.CompilationFinished(); } if (success) { bool emitPdbFile = Arguments.EmitPdb && emitOptions.DebugInformationFormat != Emit.DebugInformationFormat.Embedded; using (var peStreamProvider = new CompilerEmitStreamProvider(this, finalPeFilePath)) using (var pdbStreamProviderOpt = emitPdbFile ? new CompilerEmitStreamProvider(this, finalPdbFilePath) : null) { success = compilation.SerializeToPeStream( moduleBeingBuilt, peStreamProvider, pdbStreamProviderOpt, testSymWriterFactory: null, diagnostics: diagnosticBag, metadataOnly: emitOptions.EmitMetadataOnly, cancellationToken: cancellationToken); if (success && touchedFilesLogger != null) { if (pdbStreamProviderOpt != null) { touchedFilesLogger.AddWritten(finalPdbFilePath); } touchedFilesLogger.AddWritten(finalPeFilePath); } } } } var compileAndEmitDiagnostics = diagnosticBag.ToReadOnly(); if (ReportErrors(compileAndEmitDiagnostics, consoleOutput, errorLogger)) { return Failed; } } finally { diagnosticBag.Free(); sourceLinkStreamOpt?.Dispose(); } cancellationToken.ThrowIfCancellationRequested(); if (analyzerExceptionDiagnostics != null && ReportErrors(analyzerExceptionDiagnostics, consoleOutput, errorLogger)) { return Failed; } bool errorsReadingAdditionalFiles = false; foreach (var additionalFile in additionalTextFiles) { if (ReportErrors(additionalFile.Diagnostics, consoleOutput, errorLogger)) { errorsReadingAdditionalFiles = true; } } if (errorsReadingAdditionalFiles) { return Failed; } cancellationToken.ThrowIfCancellationRequested(); if (Arguments.TouchedFilesPath != null) { Debug.Assert(touchedFilesLogger != null); if (finalXmlFilePath != null) { touchedFilesLogger.AddWritten(finalXmlFilePath); } var readStream = OpenFile(Arguments.TouchedFilesPath + ".read", consoleOutput, mode: FileMode.OpenOrCreate); if (readStream == null) { return Failed; } using (var writer = new StreamWriter(readStream)) { touchedFilesLogger.WriteReadPaths(writer); } var writtenStream = OpenFile(Arguments.TouchedFilesPath + ".write", consoleOutput, mode: FileMode.OpenOrCreate); if (writtenStream == null) { return Failed; } using (var writer = new StreamWriter(writtenStream)) { touchedFilesLogger.WriteWrittenPaths(writer); } } } finally { // At this point analyzers are already complete in which case this is a no-op. Or they are // still running because the compilation failed before all of the compilation events were // raised. In the latter case the driver, and all its associated state, will be waiting around // for events that are never coming. Cancel now and let the clean up process begin. if (analyzerCts != null) { analyzerCts.Cancel(); if (analyzerManager != null) { // Clear cached analyzer descriptors and unregister exception handlers hooked up to the LocalizableString fields of the associated descriptors. analyzerManager.ClearAnalyzerState(analyzers); } if (reportAnalyzer) { ReportAnalyzerExecutionTime(consoleOutput, analyzerDriver, Culture, compilation.Options.ConcurrentBuild); } } } return Succeeded; }
public ListValue(ImmutableArray<Value> values, ErrorLogger owner) : base(owner) { _values = values; }
public bool ReportErrors(IEnumerable<DiagnosticInfo> diagnostics, TextWriter consoleOutput, ErrorLogger errorLogger) { bool hasErrors = false; if (diagnostics != null && diagnostics.Any()) { foreach (var diagnostic in diagnostics) { if (diagnostic.Severity == DiagnosticSeverity.Hidden) { // Not reported from the command-line compiler. continue; } PrintError(diagnostic, consoleOutput); ErrorLogger.LogDiagnostic(Diagnostic.Create(diagnostic), this.Culture, errorLogger); if (diagnostic.Severity == DiagnosticSeverity.Error) { hasErrors = true; } } } return hasErrors; }
private int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, CancellationToken cancellationToken) { Debug.Assert(!Arguments.IsScriptRunner); cancellationToken.ThrowIfCancellationRequested(); if (Arguments.DisplayLogo) { PrintLogo(consoleOutput); } if (Arguments.DisplayHelp) { PrintHelp(consoleOutput); return(Succeeded); } if (ReportErrors(Arguments.Errors, consoleOutput, errorLogger)) { return(Failed); } var touchedFilesLogger = (Arguments.TouchedFilesPath != null) ? new TouchedFileLogger() : null; Compilation compilation = CreateCompilation(consoleOutput, touchedFilesLogger, errorLogger); if (compilation == null) { return(Failed); } var diagnostics = new List <DiagnosticInfo>(); var analyzers = ResolveAnalyzersFromArguments(diagnostics, MessageProvider, touchedFilesLogger); var additionalTextFiles = ResolveAdditionalFilesFromArguments(diagnostics, MessageProvider, touchedFilesLogger); if (ReportErrors(diagnostics, consoleOutput, errorLogger)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); CancellationTokenSource analyzerCts = null; AnalyzerManager analyzerManager = null; AnalyzerDriver analyzerDriver = null; try { Func <ImmutableArray <Diagnostic> > getAnalyzerDiagnostics = null; ConcurrentSet <Diagnostic> analyzerExceptionDiagnostics = null; if (!analyzers.IsDefaultOrEmpty) { analyzerCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); analyzerManager = new AnalyzerManager(); analyzerExceptionDiagnostics = new ConcurrentSet <Diagnostic>(); Action <Diagnostic> addExceptionDiagnostic = diagnostic => analyzerExceptionDiagnostics.Add(diagnostic); var analyzerOptions = new AnalyzerOptions(ImmutableArray <AdditionalText> .CastUp(additionalTextFiles)); analyzerDriver = AnalyzerDriver.CreateAndAttachToCompilation(compilation, analyzers, analyzerOptions, analyzerManager, addExceptionDiagnostic, Arguments.ReportAnalyzer, out compilation, analyzerCts.Token); getAnalyzerDiagnostics = () => analyzerDriver.GetDiagnosticsAsync(compilation).Result; } // Print the diagnostics produced during the parsing stage and exit if there were any errors. if (ReportErrors(compilation.GetParseDiagnostics(), consoleOutput, errorLogger)) { return(Failed); } if (ReportErrors(compilation.GetDeclarationDiagnostics(), consoleOutput, errorLogger)) { return(Failed); } EmitResult emitResult; // NOTE: as native compiler does, we generate the documentation file // NOTE: 'in place', replacing the contents of the file if it exists string finalPeFilePath; string finalPdbFilePath; string finalXmlFilePath; Stream xmlStreamOpt = null; cancellationToken.ThrowIfCancellationRequested(); finalXmlFilePath = Arguments.DocumentationPath; if (finalXmlFilePath != null) { xmlStreamOpt = OpenFile(finalXmlFilePath, consoleOutput, PortableShim.FileMode.OpenOrCreate, PortableShim.FileAccess.Write, PortableShim.FileShare.ReadWriteBitwiseOrDelete); if (xmlStreamOpt == null) { return(Failed); } xmlStreamOpt.SetLength(0); } cancellationToken.ThrowIfCancellationRequested(); IEnumerable <DiagnosticInfo> errors; using (var win32ResourceStreamOpt = GetWin32Resources(Arguments, compilation, out errors)) using (xmlStreamOpt) { if (ReportErrors(errors, consoleOutput, errorLogger)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); string outputName = GetOutputFileName(compilation, cancellationToken); finalPeFilePath = Path.Combine(Arguments.OutputDirectory, outputName); finalPdbFilePath = Arguments.PdbPath ?? Path.ChangeExtension(finalPeFilePath, ".pdb"); // NOTE: Unlike the PDB path, the XML doc path is not embedded in the assembly, so we don't need to pass it to emit. var emitOptions = Arguments.EmitOptions. WithOutputNameOverride(outputName). WithPdbFilePath(finalPdbFilePath); // The PDB path is emitted in it's entirety into the PE. This makes it impossible to have deterministic // builds that occur in different source directories. To enable this we shave all path information from // the PDB when specified by the user. // // This is a temporary work around to allow us to make progress with determinism. The following issue // tracks getting an official solution here. // // https://github.com/dotnet/roslyn/issues/9813 if (Arguments.ParseOptions.Features.ContainsKey("pdb-path-determinism") && !string.IsNullOrEmpty(emitOptions.PdbFilePath)) { emitOptions = emitOptions.WithPdbFilePath(Path.GetFileName(emitOptions.PdbFilePath)); } using (var peStreamProvider = new CompilerEmitStreamProvider(this, finalPeFilePath)) using (var pdbStreamProviderOpt = Arguments.EmitPdb ? new CompilerEmitStreamProvider(this, finalPdbFilePath) : null) { emitResult = compilation.Emit( peStreamProvider, pdbStreamProviderOpt, (xmlStreamOpt != null) ? new Compilation.SimpleEmitStreamProvider(xmlStreamOpt) : null, (win32ResourceStreamOpt != null) ? new Compilation.SimpleEmitStreamProvider(win32ResourceStreamOpt) : null, Arguments.ManifestResources, emitOptions, debugEntryPoint: null, getHostDiagnostics: getAnalyzerDiagnostics, cancellationToken: cancellationToken); if (emitResult.Success && touchedFilesLogger != null) { if (pdbStreamProviderOpt != null) { touchedFilesLogger.AddWritten(finalPdbFilePath); } touchedFilesLogger.AddWritten(finalPeFilePath); } } } GenerateSqmData(Arguments.CompilationOptions, emitResult.Diagnostics); if (ReportErrors(emitResult.Diagnostics, consoleOutput, errorLogger)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); if (analyzerExceptionDiagnostics != null && ReportErrors(analyzerExceptionDiagnostics, consoleOutput, errorLogger)) { return(Failed); } bool errorsReadingAdditionalFiles = false; foreach (var additionalFile in additionalTextFiles) { if (ReportErrors(additionalFile.Diagnostics, consoleOutput, errorLogger)) { errorsReadingAdditionalFiles = true; } } if (errorsReadingAdditionalFiles) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); if (Arguments.TouchedFilesPath != null) { Debug.Assert(touchedFilesLogger != null); if (finalXmlFilePath != null) { touchedFilesLogger.AddWritten(finalXmlFilePath); } var readStream = OpenFile(Arguments.TouchedFilesPath + ".read", consoleOutput, mode: PortableShim.FileMode.OpenOrCreate); if (readStream == null) { return(Failed); } using (var writer = new StreamWriter(readStream)) { touchedFilesLogger.WriteReadPaths(writer); } var writtenStream = OpenFile(Arguments.TouchedFilesPath + ".write", consoleOutput, mode: PortableShim.FileMode.OpenOrCreate); if (writtenStream == null) { return(Failed); } using (var writer = new StreamWriter(writtenStream)) { touchedFilesLogger.WriteWrittenPaths(writer); } } } finally { // At this point analyzers are already complete in which case this is a no-op. Or they are // still running because the compilation failed before all of the compilation events were // raised. In the latter case the driver, and all its associated state, will be waiting around // for events that are never coming. Cancel now and let the clean up process begin. if (analyzerCts != null) { analyzerCts.Cancel(); if (analyzerManager != null) { // Clear cached analyzer descriptors and unregister exception handlers hooked up to the LocalizableString fields of the associated descriptors. analyzerManager.ClearAnalyzerState(analyzers); } if (Arguments.ReportAnalyzer && analyzerDriver != null && compilation != null) { ReportAnalyzerExecutionTime(consoleOutput, analyzerDriver, Culture, compilation.Options.ConcurrentBuild); } } } return(Succeeded); }