private void EventSourceOnMessageRaised(object sender, BuildMessageEventArgs e) { if (e is TaskCommandLineEventArgs commandLine) { // We are only interested in CSharp and VisualBasic tasks string language; string extractedArguments; string error; bool success; switch (commandLine.TaskName) { case CscTaskName: language = LanguageNames.CSharp; success = TryGetArgumentsFromCommandLine(CscToolName, commandLine.CommandLine, out extractedArguments, out error); break; case VbcTaskName: language = LanguageNames.VisualBasic; success = TryGetArgumentsFromCommandLine(VbcToolName, commandLine.CommandLine, out extractedArguments, out error); break; default: return; } // We were able to split the compiler invocation from its arguments. This is the indicator // that something didn't go as expected. Since failing to parse the command line means we // are not catching all inputs/outputs properly, we have no option but to fail the corresponding pip if (!success) { throw new ArgumentException(error); } var parsedCommandLine = CompilerUtilities.GetParsedCommandLineArguments(language, extractedArguments, commandLine.ProjectFile); // In general we don't care about errors in the command line, since any error there will eventually fail the compiler call. // However, we do care about new switches that may represent file accesses that are introduced to the compiler and this logger // is not aware of. // This means that if the command line comes back with a bad switch error, but the compiler doesn't fail, we need to fail the call. // Error 2007 represents a bad switch. Unfortunately there doesn't seem to be any public enumeration that defines it properly. var badSwitchErrors = parsedCommandLine.Errors.Where(diagnostic => diagnostic.Id.Contains("2007")).ToList(); foreach (var badSwitch in badSwitchErrors) { // If we find a bad switch error, delay making a decision until we know if the compiler failed or not. m_badSwitchErrors.Add(badSwitch); } RegisterAccesses(parsedCommandLine); } }
private void EventSourceOnMessageRaised(object sender, BuildMessageEventArgs e) { if (e is TaskCommandLineEventArgs commandLine) { // We are only interested in CSharp and VisualBasic tasks string language; string extractedArguments; string error; bool success; switch (commandLine.TaskName) { case CscTaskName: language = LanguageNames.CSharp; success = TryGetArgumentsFromCommandLine(CscToolName, commandLine.CommandLine, out extractedArguments, out error); break; case VbcTaskName: language = LanguageNames.VisualBasic; success = TryGetArgumentsFromCommandLine(VbcToolName, commandLine.CommandLine, out extractedArguments, out error); break; default: return; } // We were able to split the compiler invocation from its arguments. This is the indicator // that something didn't go as expected. Since failing to parse the command line means we // are not catching all inputs/outputs properly, we have no option but to fail the corresponding pip if (!success) { throw new ArgumentException(error); } var parsedCommandLine = CompilerUtilities.GetParsedCommandLineArguments(language, extractedArguments, commandLine.ProjectFile); RegisterAccesses(parsedCommandLine); } }
private void EventSourceOnMessageRaised(object sender, BuildMessageEventArgs e) { if (e is TaskCommandLineEventArgs commandLine) { // We are only interested in CSharp and VisualBasic tasks string language; string extractedArguments; string error; bool success; switch (commandLine.TaskName) { case CscTaskName: language = LanguageNames.CSharp; success = TryGetArgumentsFromCommandLine(CscToolName, commandLine.CommandLine, out extractedArguments, out error); break; case VbcTaskName: language = LanguageNames.VisualBasic; success = TryGetArgumentsFromCommandLine(VbcToolName, commandLine.CommandLine, out extractedArguments, out error); break; default: return; } // We were able to split the compiler invocation from its arguments. This is the indicator // that something didn't go as expected. Since failing to parse the command line means we // are not catching all inputs/outputs properly, we have no option but to fail the corresponding pip if (!success) { throw new ArgumentException(error); } var parsedCommandLine = CompilerUtilities.GetParsedCommandLineArguments(language, extractedArguments, commandLine.ProjectFile, out string[] args); // In general we don't care about errors in the command line, since any error there will eventually fail the compiler call. // However, we do care about new switches that may represent file accesses that are introduced to the compiler and this logger // is not aware of. // This means that if the command line comes back with a bad switch error, but the compiler doesn't fail, we need to fail the call. // Error 2007 represents a bad switch. Unfortunately there doesn't seem to be any public enumeration that defines it properly. var badSwitchErrors = parsedCommandLine.Errors.Where(diagnostic => diagnostic.Id.Contains("2007")).ToList(); foreach (var badSwitch in badSwitchErrors) { // If we find a bad switch error, delay making a decision until we know if the compiler failed or not. m_badSwitchErrors.Add(badSwitch); } string[] embeddedResourceFilePaths = Array.Empty <string>(); // Determine the paths to the embedded resources. /resource: parameters end up in CommandLineArguments.ManifestResources, // but the returned class drops the file path (and is currently internal anyway). // We should be able to remove this if/when this gets resolved: https://github.com/dotnet/roslyn/issues/41372. if (parsedCommandLine.ManifestResources.Length > 0) { IEnumerable <string> embeddedResourcesArgs = args.Where( a => a.StartsWith("/resource:", StringComparison.OrdinalIgnoreCase) || a.StartsWith("/res:", StringComparison.Ordinal) || a.StartsWith("/linkresource:", StringComparison.Ordinal) || a.StartsWith("/linkres:", StringComparison.Ordinal)); embeddedResourceFilePaths = CompilerUtilities.GetEmbeddedResourceFilePaths( embeddedResourcesArgs, parsedCommandLine.BaseDirectory); } var result = new ParseResult() { ParsedArguments = parsedCommandLine, EmbeddedResourcePaths = embeddedResourceFilePaths }; RegisterAccesses(result); } }