/// <summary> /// Determine the path of the output dll/exe. /// </summary> /// <param name="compilation">Information about the compilation.</param> /// <param name="cancel">Cancellation token required.</param> /// <returns>The filename.</returns> private static string GetOutputName(CSharpCompilation compilation, CSharpCommandLineArguments commandLineArguments) { // There's no apparent way to access the output filename from the compilation, // so we need to re-parse the command line arguments. if (commandLineArguments.OutputFileName == null) { // No output specified: Use name based on first filename var entry = compilation.GetEntryPoint(System.Threading.CancellationToken.None); if (entry == null) { if (compilation.SyntaxTrees.Length == 0) { throw new InvalidOperationException("No source files seen"); } // Probably invalid, but have a go anyway. var entryPointFile = compilation.SyntaxTrees.First().FilePath; return(Path.ChangeExtension(entryPointFile, ".exe")); } var entryPointFilename = entry.Locations.First().SourceTree.FilePath; return(Path.ChangeExtension(entryPointFilename, ".exe")); } return(Path.Combine(commandLineArguments.OutputDirectory, commandLineArguments.OutputFileName)); }
private static ImmutableDictionary <string, ReportDiagnostic> GetNullableWarningsFromCompiler() { string[] args = { "/warnaserror:nullable" }; CSharpCommandLineArguments commandLineArguments = CSharpCommandLineParser.Default.Parse(args, Environment.CurrentDirectory, Environment.CurrentDirectory); ImmutableDictionary <string, ReportDiagnostic> nullableWarnings = commandLineArguments.CompilationOptions.SpecificDiagnosticOptions; return(nullableWarnings); }
private static ImmutableDictionary <string, ReportDiagnostic> GetNullableWarningsFromCompiler() { string[] args = { "/warnaserror:nullable" }; CSharpCommandLineArguments commandLineArguments = CSharpCommandLineParser.Default.Parse(args, baseDirectory: Environment.CurrentDirectory, sdkDirectory: Environment.CurrentDirectory); ImmutableDictionary <string, ReportDiagnostic> nullableWarnings = commandLineArguments.CompilationOptions.SpecificDiagnosticOptions; // Workaround for https://github.com/dotnet/roslyn/issues/41610 nullableWarnings = nullableWarnings .SetItem("CS8632", ReportDiagnostic.Error) .SetItem("CS8669", ReportDiagnostic.Error); return(nullableWarnings); }
/// <summary> /// Initialize the analyser. /// </summary> /// <param name="commandLineArguments">Arguments passed to csc.</param> /// <param name="compilationIn">The Roslyn compilation.</param> /// <param name="options">Extractor options.</param> /// <param name="roslynArgs">The arguments passed to Roslyn.</param> public void Initialize( CSharpCommandLineArguments commandLineArguments, CSharpCompilation compilationIn, Options options, string[] roslynArgs) { compilation = compilationIn; layout = new Layout(); this.options = options; extractor = new Extraction.Extractor(false, GetOutputName(compilation, commandLineArguments), Logger); LogDiagnostics(roslynArgs); SetReferencePaths(); CompilationErrors += FilteredDiagnostics.Count(); }
/// <summary> /// End initialization of the analyser. /// </summary> /// <param name="commandLineArguments">Arguments passed to csc.</param> /// <param name="options">Extractor options.</param> /// <param name="compilation">The Roslyn compilation.</param> /// <returns>A Boolean indicating whether to proceed with extraction.</returns> public void EndInitialize( CSharpCommandLineArguments commandLineArguments, CommonOptions options, CSharpCompilation compilation) { if (!init) { throw new InternalError("EndInitialize called without BeginInitialize returning true"); } this.options = options; this.compilation = compilation; this.extractor = new TracingExtractor(GetOutputName(compilation, commandLineArguments), Logger, PathTransformer, options); LogDiagnostics(); SetReferencePaths(); CompilationErrors += FilteredDiagnostics.Count(); }
/// <summary> /// End initialization of the analyser. /// </summary> /// <param name="commandLineArguments">Arguments passed to csc.</param> /// <param name="options">Extractor options.</param> /// <param name="compilation">The Roslyn compilation.</param> /// <returns>A Boolean indicating whether to proceed with extraction.</returns> public void EndInitialize( CSharpCommandLineArguments commandLineArguments, Options options, CSharpCompilation compilation) { if (!init) { throw new InternalError("EndInitialize called without BeginInitialize returning true"); } layout = new Layout(); this.options = options; this.compilation = compilation; extractor = new Extraction.Extractor(false, GetOutputName(compilation, commandLineArguments), Logger); LogDiagnostics(); SetReferencePaths(); CompilationErrors += FilteredDiagnostics.Count(); }
private static ExitCode AnalyseTracing( TracingAnalyser analyser, CSharpCommandLineArguments compilerArguments, Options options, CanonicalPathCache canonicalPathCache, Stopwatch stopwatch) { return(Analyse(stopwatch, analyser, options, references => ResolveReferences(compilerArguments, analyser, canonicalPathCache, references), (analyser, syntaxTrees) => { return ReadSyntaxTrees( compilerArguments.SourceFiles.Select(src => canonicalPathCache.GetCanonicalPath(src.Path)), analyser, compilerArguments.ParseOptions, compilerArguments.Encoding, syntaxTrees); }, (syntaxTrees, references) => { // csc.exe (CSharpCompiler.cs) also provides CompilationOptions // .WithMetadataReferenceResolver(), // .WithXmlReferenceResolver() and // .WithSourceReferenceResolver(). // These would be needed if we hadn't explicitly provided the source/references // already. return CSharpCompilation.Create( compilerArguments.CompilationName, syntaxTrees, references, compilerArguments.CompilationOptions .WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default) .WithStrongNameProvider(new DesktopStrongNameProvider(compilerArguments.KeyFileSearchPaths)) .WithMetadataImportOptions(MetadataImportOptions.All) ); }, (compilation, options) => analyser.EndInitialize(compilerArguments, options, compilation), () => analyser.AnalyseCompilation(), performance => analyser.LogPerformance(performance), () => { })); }
private static void AssertSpecificDiagnostics(int[] expectedCodes, ReportDiagnostic[] expectedOptions, CSharpCommandLineArguments args) { var actualOrdered = args.CompilationOptions.SpecificDiagnosticOptions.OrderBy(entry => entry.Key); AssertEx.Equal( expectedCodes.Select(i => MessageProvider.Instance.GetIdForErrorCode(i)), actualOrdered.Select(entry => entry.Key)); AssertEx.Equal(expectedOptions, actualOrdered.Select(entry => entry.Value)); }
CodeCompilerResult CompileFileInternal( CodeCompilerArguments arguments, TextWriter log, CancellationToken token) { CSharpCommandLineArguments args = null; if (arguments.AdditionalArguments != null) { var splitArgs = CommandLineParser.SplitCommandLineIntoArguments(arguments.AdditionalArguments, false); if (splitArgs.Any()) { args = CSharpCommandLineParser.Default.Parse(splitArgs, arguments.TempDirectory, null, null); } } var references = new List <MetadataReference> (); foreach (var assemblyReference in AssemblyResolver.GetResolvedReferences(runtime, arguments.AssemblyReferences)) { references.Add(MetadataReference.CreateFromFile(assemblyReference)); } var parseOptions = args?.ParseOptions ?? new CSharpParseOptions(); if (arguments.LangVersion != null) { if (LanguageVersionFacts.TryParse(arguments.LangVersion, out var langVersion)) { parseOptions = parseOptions.WithLanguageVersion(langVersion); } else { throw new System.Exception($"Unknown value '{arguments.LangVersion}' for langversion"); } } else { // need to update this when updating referenced roslyn binaries CSharpLangVersionHelper.GetBestSupportedLangVersion(runtime, CSharpLangVersion.v9_0); } var syntaxTrees = new List <SyntaxTree> (); foreach (var sourceFile in arguments.SourceFiles) { using var stream = File.OpenRead(sourceFile); var sourceText = SourceText.From(stream, Encoding.UTF8, canBeEmbedded: true); SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sourceText, parseOptions, cancellationToken: token, path: sourceFile); syntaxTrees.Add(syntaxTree); } var compilationOptions = (args?.CompilationOptions ?? new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)) .WithOutputKind(OutputKind.DynamicallyLinkedLibrary); var compilation = CSharpCompilation.Create( "GeneratedTextTransformation", syntaxTrees, references, compilationOptions ); EmitOptions emitOptions = args?.EmitOptions ?? new EmitOptions(); if (arguments.Debug) { var embeddedTexts = syntaxTrees.Select(st => EmbeddedText.FromSource(st.FilePath, st.GetText())).ToList(); emitOptions = emitOptions.WithDebugInformationFormat(DebugInformationFormat.Embedded); } using var fs = File.OpenWrite(arguments.OutputPath); EmitResult result = compilation.Emit(fs, options: emitOptions, cancellationToken: token); if (result.Success) { return(new CodeCompilerResult { Output = new List <string> (), Success = true, Errors = new List <CodeCompilerError> () }); } var failures = result.Diagnostics.Where(x => x.IsWarningAsError || x.Severity == DiagnosticSeverity.Error); var errors = failures.Select(x => { var location = x.Location.GetMappedLineSpan(); var startLinePosition = location.StartLinePosition; var endLinePosition = location.EndLinePosition; return(new CodeCompilerError { Message = x.GetMessage(), Column = startLinePosition.Character, Line = startLinePosition.Line, EndLine = endLinePosition.Line, EndColumn = endLinePosition.Character, IsError = x.Severity == DiagnosticSeverity.Error, Origin = location.Path }); }).ToList(); return(new CodeCompilerResult { Success = false, Output = new List <string> (), Errors = errors }); }
/// <summary> /// Tries to get the associated <see cref="CSharpCommandLineArguments"/> to the specified project. /// </summary> /// <param name="project">The project</param> /// <param name="commandLineArguments">The output arguments if it was found.</param> /// <returns><c>true</c> if the project id has associated command line arguments.</returns> public bool TryGetCommandLineArguments(Project project, out CSharpCommandLineArguments commandLineArguments) { return(TryGetCommandLineArguments(project.Id, out commandLineArguments)); }
/// <summary> /// Tries to get the associated <see cref="CSharpCommandLineArguments"/> to the specified project id. /// </summary> /// <param name="projectId">The project id.</param> /// <param name="commandLineArguments">The output arguments if it was found.</param> /// <returns><c>true</c> if the project id has associated command line arguments.</returns> public bool TryGetCommandLineArguments(ProjectId projectId, out CSharpCommandLineArguments commandLineArguments) { return(_commandLineArguments.TryGetValue(projectId, out commandLineArguments)); }
/// <summary> /// Creates a Project and collect CSharp arguments from a compiler invocation. /// </summary> private Project GetCompilationOptionsAndFiles(Project project, Microsoft.Build.Logging.StructuredLogger.CompilerInvocation invocation, List <string> args, out CSharpCommandLineArguments arguments) { arguments = CSharpCommandLineParser.Default.Parse(args, invocation.ProjectDirectory, sdkDirectory: null); project = project.WithCompilationOptions(arguments.CompilationOptions); project = project.WithParseOptions(arguments.ParseOptions); project = project.WithMetadataReferences(arguments.MetadataReferences.Select(x => x.Reference).Select(GetOrCreateMetaDataReference)); foreach (var sourceFile in arguments.SourceFiles) { var filePath = sourceFile.Path; var name = filePath; if (name.StartsWith(invocation.ProjectDirectory)) { name = name.Substring(invocation.ProjectDirectory.Length); } var document = project.AddDocument(name, File.ReadAllText(filePath), filePath: filePath); project = document.Project; } return(project); }