/// <summary> /// Parses a single line of text to identify any errors or warnings in canonical format. /// </summary> /// <param name="singleLine">A single line of text for the method to parse.</param><param name="messageImportance">A value of <see cref="T:Microsoft.Build.Framework.MessageImportance"/> that indicates the importance level with which to log the message.</param> protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) { if (!string.IsNullOrEmpty(singleLine)) { base.LogEventsFromTextOutput(singleLine, messageImportance); } }
/// <summary> /// Handle a raised message. /// </summary> /// <param name="message"> /// The message. /// </param> /// <param name="importance"> /// The importance. /// </param> public void HandleMessage(string message, MessageImportance importance = MessageImportance.Normal) { if (this.OutputMessage(importance)) { NotificationWriter.Write(message); } }
protected void LogMessage(string message, MessageImportance importance = MessageImportance.High) { if (BuildEngine != null) { BuildEngine.LogMessageEvent(new BuildMessageEventArgs("CrmCross: " + message, "CrmCross", "CrmCross", importance)); } }
/// <summary> /// Log a comment /// </summary> /// <param name="buildEventContext">Event context information which describes who is logging the event</param> /// <param name="importance">How important is the message, this will determine which verbosities the message will show up on. /// The higher the importance the lower the verbosity needs to be for the message to be seen</param> /// <param name="message">Message to log</param> /// <exception cref="InternalErrorException">BuildEventContext is null</exception> /// <exception cref="InternalErrorException">Message is null</exception> public void LogCommentFromText(BuildEventContext buildEventContext, MessageImportance importance, string message) { lock (_lockObject) { this.LogCommentFromText(buildEventContext, importance, message, null); } }
protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) { if (singleLine.StartsWith("Successfully created package")) { var outputPackage = singleLine.Split('\'').Skip(1).First(); var outputPackageItem = new TaskItem(outputPackage); if (outputPackage.EndsWith(".symbols.nupkg", StringComparison.OrdinalIgnoreCase)) { OutputSymbolsPackage = new[] { outputPackageItem }; } else { OutputPackage = new[] { outputPackageItem }; } } if (messageImportance == MessageImportance.High) { Log.LogError(singleLine); return; } if (singleLine.StartsWith("Issue:") || singleLine.StartsWith("Description:") || singleLine.StartsWith("Solution:")) { Log.LogWarning(singleLine); return; } base.LogEventsFromTextOutput(singleLine, messageImportance); }
public TaskCommandLineEventArgs (string commandLine, string taskName, MessageImportance importance) : base (commandLine, null, null, importance) { this.taskName = taskName; this.commandLine = commandLine; }
/// <summary> /// Initializes a new instance of the OutputEventArgs class. /// </summary> /// <param name="text">The output text.</param> /// <param name="importance">The level of importance for this output event.</param> public OutputEventArgs(string text, MessageImportance importance) { Param.RequireNotNull(text, "text"); Param.Ignore(importance); this.Output = text; this.Importance = importance; }
private static void LogItemMetadata(Task task, ITaskItem item, MessageImportance importance) { var metadata = item.CloneCustomMetadata(); foreach (var name in metadata.Keys.Cast<string>()) { LogMetadata(task, name, (string)metadata[name], importance); } }
public BuildMessageEventArgs(string message, string helpKeyword, string senderName, MessageImportance importance) : base(message, helpKeyword, senderName) { this.importance = importance; }
public static void LogInputs(this Task task, MessageImportance importance) { task.Log.LogMessage(importance, "Inputs:"); foreach (var propertyInfo in GetInputProperties(task)) { LogProperty(propertyInfo, importance, task); } }
private static void LogTaskItems(ITaskItem[] taskItems, string itemGroup, MessageImportance importance, Task task) { task.Log.LogMessage(importance, " {0} =", itemGroup); foreach (var item in taskItems) { LogTaskItem(task, item, importance); } }
protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) { if ((Set == null || Set.Length == 0) && !String.IsNullOrWhiteSpace(singleLine) && !singleLine.StartsWith("WARNING", StringComparison.OrdinalIgnoreCase)) { Value = singleLine; } base.LogEventsFromTextOutput(singleLine, messageImportance); }
/// <summary> /// Parse the output of the console and gets the Branch or Tag. /// </summary> /// <param name="singleLine">the line being parsed</param> /// <param name="messageImportance">message importance</param> protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) { bool isError = messageImportance == StandardErrorLoggingImportance; if (isError) base.LogEventsFromTextOutput(singleLine, messageImportance); else if (IsBranchStatusLine(singleLine)) Branch = ParseStatusLineOutput(singleLine); }
public ConcurrentLoggingHelper (TaskLoggingHelper taskLog, StreamReader messageStream, MessageImportance messageImportance) { this.taskLog = taskLog; this.messageStream = messageStream; this.messageImportance = messageImportance; this.hasLoggedErrors = false; }
/// <summary> /// Parses a single line of text to identify any errors or warnings in canonical format. /// </summary> /// <param name="singleLine">A single line of text for the method to parse.</param> /// <param name="messageImportance">A value of <see cref="T:Microsoft.Build.Framework.MessageImportance"/> that indicates the importance level with which to log the message.</param> protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) { bool isError = messageImportance == StandardErrorLoggingImportance; if (isError) base.LogEventsFromTextOutput(singleLine, messageImportance); else CommitHash = singleLine.Trim(); }
protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) { if (CommandVerbosity != CommandVerbosity.Detailed) { var match = SingleLineNuGetPackageRegex.Match(singleLine); if (match.Success) { _packages.Add(new TaskItem($"{match.Groups["id"].Value}.{match.Groups["version"].Value}", new Dictionary<string, string> { {"Id", match.Groups["id"].Value}, {"Version", match.Groups["version"].Value}, })); } } else { if (_lastTaskItem == null) { var match = MultiLineNuGetPackageIdRegex.Match(singleLine); if (match.Success) { _lastTaskItem = new TaskItem(match.Groups["id"].Value, new Dictionary<string, string> { {"Id", match.Groups["id"].Value} }); } } else { if (String.Empty.Equals(singleLine)) { _packages.Add(_lastTaskItem); _lastTaskItem = null; } else { var match = MultiLineNuGetPackageVersionRegex.Match(singleLine); if (match.Success) { _lastTaskItem.ItemSpec = $"{_lastTaskItem.ItemSpec}.{match.Groups["version"].Value}"; _lastTaskItem.SetMetadata("Version", match.Groups["version"].Value); } else { _lastTaskItem.SetMetadata("Description", singleLine.Trim()); } } } } base.LogEventsFromTextOutput(singleLine, messageImportance); }
private StringBuilder SelectStringBuilder(MessageImportance messageImportance) { switch (messageImportance) { case MessageImportance.High: return this._highImportanceStringBuilder; case MessageImportance.Normal: return this._normalImportanceStringBuilder; case MessageImportance.Low: return this._lowImportanceStringBuilder; default: throw new ArgumentOutOfRangeException("messageImportance"); } }
public virtual void Initialise(string messageImportance) { stringBuilder = new StringBuilder(); MessageImportance messageImportanceEnum; if (!Enum.TryParse(messageImportance, out messageImportanceEnum)) { throw new WeavingException(string.Format("Invalid MessageImportance in config. Should be 'Low', 'Normal' or 'High' but was '{0}'.", messageImportance)); } MessageImportance = messageImportanceEnum; }
/// <summary> /// Logs the specified message. /// </summary> /// <param name="task"> /// A task to provide actual logger. /// </param> /// <param name="message"> /// Message. /// </param> /// <param name="messageImportance"> /// Message importance. /// </param> public void Log(Task task, string message, MessageImportance messageImportance) { if (task == null) throw new ArgumentNullException("task"); if (message == null) throw new ArgumentNullException("message"); task.Log.LogMessageFromText(message, messageImportance); }
/// <summary> /// This constuctor allows all event data to be initialized /// </summary> /// <param name="message">text message</param> /// <param name="helpKeyword">help keyword </param> /// <param name="senderName">name of event sender</param> /// <param name="importance">importance of the message</param> public BuildMessageEventArgs ( string message, string helpKeyword, string senderName, MessageImportance importance ) : this(message, helpKeyword, senderName, importance, DateTime.UtcNow) { }
public void LogMessage(MessageImportance importance, string message) { System.Console.ResetColor(); System.Console.ForegroundColor = ConsoleColor.DarkGray; if (importance == MessageImportance.High) { System.Console.ForegroundColor = ConsoleColor.Gray; } System.Console.WriteLine(message); }
/// <summary> /// Creates an instance of this class for the given task command line. /// </summary> /// <param name="commandLine">The command line used by a task to launch /// its underlying tool/executable.</param> /// <param name="taskName">The name of the task raising this event.</param> /// <param name="importance">Importance of command line -- controls whether /// the command line will be displayed by less verbose loggers.</param> public TaskCommandLineEventArgs ( string commandLine, string taskName, MessageImportance importance ) : this(commandLine, taskName, importance, DateTime.UtcNow) { // do nothing }
/// <summary> /// Creates an instance of this class for the given task command line. This constructor allows the timestamp to be set /// </summary> /// <param name="commandLine">The command line used by a task to launch /// its underlying tool/executable.</param> /// <param name="taskName">The name of the task raising this event.</param> /// <param name="importance">Importance of command line -- controls whether /// the command line will be displayed by less verbose loggers.</param> /// <param name="eventTimestamp">Timestamp when the event was created</param> public TaskCommandLineEventArgs ( string commandLine, string taskName, MessageImportance importance, DateTime eventTimestamp ) : base(commandLine, null, taskName, importance, eventTimestamp) { // do nothing }
protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) { var flag = messageImportance == this.StandardErrorLoggingImportance; if (flag) { base.LogEventsFromTextOutput(singleLine, messageImportance); return; } this.HandleOutput(singleLine); }
/// <summary> /// Logs a comment (BuildMessageEventArgs) with a certain MessageImportance level /// </summary> /// <param name="buildEventContext">Event context information which describes who is logging the event</param> /// <param name="importance">How important is the message, this will determine which verbosities the message will show up on. /// The higher the importance the lower the verbosity needs to be for the message to be seen</param> /// <param name="messageResourceName">String which identifies the message in the string resx</param> /// <param name="messageArgs">Arguments for the format string indexed by messageResourceName</param> /// <exception cref="InternalErrorException">MessageResourceName is null</exception> public void LogComment(BuildEventContext buildEventContext, MessageImportance importance, string messageResourceName, params object[] messageArgs) { lock (_lockObject) { if (!OnlyLogCriticalEvents) { ErrorUtilities.VerifyThrow(!string.IsNullOrEmpty(messageResourceName), "Need resource string for comment message."); LogCommentFromText(buildEventContext, importance, ResourceUtilities.GetResourceString(messageResourceName), messageArgs); } } }
protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) { bool isError = messageImportance == StandardErrorLoggingImportance; if (isError) { base.LogEventsFromTextOutput(singleLine, messageImportance); _errorBuffer.AppendLine(singleLine); return; } _outputBuffer.Append(singleLine); }
private static void LogProperty(PropertyInfo propertyInfo, MessageImportance importance, Task task) { string name = propertyInfo.Name; var value = propertyInfo.GetValue(task); if (value is ITaskItem[]) { LogTaskItems(value as ITaskItem[], name, importance, task); } else { task.Log.LogMessage(importance, " {0} = {1}", name, value); } }
protected ToolTask() { this.timeout = -1; this.eventCloseLock = new object(); this.standardOutputImportanceToUse = MessageImportance.Low; this.standardErrorImportanceToUse = MessageImportance.Normal; this.logPrivate = new TaskLoggingHelper(this); this.logPrivate.TaskResources = AssemblyResources.PrimaryResources; this.logPrivate.HelpKeywordPrefix = "MSBuild."; this.logShared = new TaskLoggingHelper(this); this.logShared.TaskResources = AssemblyResources.SharedResources; this.logShared.HelpKeywordPrefix = "MSBuild."; this.TaskProcessTerminationTimeout = 0x1388; this.ToolCanceled = new ManualResetEvent(false); }
protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) { if (messageImportance == MessageImportance.High) { Log.LogError(singleLine); return; } if (singleLine.StartsWith("Issue:") || singleLine.StartsWith("Description:") || singleLine.StartsWith("Solution:")) { Log.LogWarning(singleLine); return; } base.LogEventsFromTextOutput(singleLine, messageImportance); }
private bool MessageIsImportantEnough(MessageImportance messageImportance) { if (messageImportance == MessageImportance.High) return true; if (messageImportance == MessageImportance.Normal && (Verbosity == LoggerVerbosity.Normal || Verbosity == LoggerVerbosity.Detailed || Verbosity == LoggerVerbosity.Diagnostic)) { return true; } if (messageImportance == MessageImportance.Low && (Verbosity == LoggerVerbosity.Diagnostic || Verbosity == LoggerVerbosity.Detailed)) { return true; } return false; }
// log them as is, regardless of message importance. Javadoc compilation errors should never be reported as errors. protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) { Log.LogDebugMessage(singleLine); }
protected bool LogAapt2EventsFromOutput(string singleLine, MessageImportance messageImportance, bool apptResult) { if (string.IsNullOrEmpty(singleLine)) { return(true); } var match = AndroidRunToolTask.AndroidErrorRegex.Match(singleLine.Trim()); if (match.Success) { var file = match.Groups ["file"].Value; int line = 0; if (!string.IsNullOrEmpty(match.Groups ["line"]?.Value)) { line = int.Parse(match.Groups ["line"].Value.Trim()) + 1; } var level = match.Groups ["level"].Value.ToLowerInvariant(); var message = match.Groups ["message"].Value; // Handle the following which is NOT an error :( // W/ResourceType(23681): For resource 0x0101053d, entry index(1341) is beyond type entryCount(733) // W/ResourceType( 3681): For resource 0x0101053d, entry index(1341) is beyond type entryCount(733) if (file.StartsWith("W/", StringComparison.OrdinalIgnoreCase)) { LogCodedWarning(GetErrorCode(singleLine), singleLine); return(true); } if (message.StartsWith("unknown option", StringComparison.OrdinalIgnoreCase)) { // we need to filter out the remailing help lines somehow. LogCodedError("APT0001", $"{message}. This is the result of using `aapt` command line arguments with `aapt2`. The arguments are not compatible."); return(false); } if (message.Contains("in APK") && message.Contains("is compressed.")) { LogMessage(singleLine, messageImportance); return(true); } if (message.Contains("fakeLogOpen")) { LogMessage(singleLine, messageImportance); return(true); } if (message.Contains("note:")) { LogMessage(singleLine, messageImportance); return(true); } if (message.Contains("warn:")) { LogCodedWarning(GetErrorCode(singleLine), singleLine); return(true); } if (level.Contains("note")) { LogMessage(message, messageImportance); return(true); } if (level.Contains("warning") || level.StartsWith($"{ToolName} W", StringComparison.OrdinalIgnoreCase)) { LogCodedWarning(GetErrorCode(singleLine), singleLine); return(true); } // Try to map back to the original resource file, so when the user // double clicks the error, it won't take them to the obj/Debug copy if (ResourceDirectories != null) { foreach (var dir in ResourceDirectories) { var resourceDirectory = dir.ItemSpec; var resourceDirectoryFullPath = ResourceDirectoryFullPath(resourceDirectory); string newfile = MonoAndroidHelper.FixUpAndroidResourcePath(file, resourceDirectory, resourceDirectoryFullPath, resource_name_case_map); if (!string.IsNullOrEmpty(newfile)) { file = newfile; break; } } } // Strip any "Error:" text from aapt's output if (message.StartsWith("error: ", StringComparison.InvariantCultureIgnoreCase)) { message = message.Substring("error: ".Length); } if (level.Contains("error") || (line != 0 && !string.IsNullOrEmpty(file))) { LogCodedError(GetErrorCode(message), message, file, line); return(true); } } if (!apptResult) { var message = string.Format("{0} \"{1}\".", singleLine.Trim(), singleLine.Substring(singleLine.LastIndexOfAny(new char [] { '\\', '/' }) + 1)); LogCodedError(GetErrorCode(message), message, ToolName); } else { LogCodedWarning(GetErrorCode(singleLine), singleLine); } return(true); }
public void WriteMessage(string message, MessageImportance messageImportance) { Console.WriteLine(message); }
protected void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance, bool apptResult) { if (string.IsNullOrEmpty(singleLine)) { return; } var match = AndroidRunToolTask.AndroidErrorRegex.Match(singleLine.Trim()); if (match.Success) { var file = match.Groups["file"].Value; int line = 0; if (!string.IsNullOrEmpty(match.Groups["line"]?.Value)) { line = int.Parse(match.Groups["line"].Value.Trim()) + 1; } var level = match.Groups["level"].Value.ToLowerInvariant(); var message = match.Groups ["message"].Value; if (message.Contains("fakeLogOpen")) { LogMessage(singleLine, MessageImportance.Normal); return; } if (level.Contains("warning")) { LogCodedWarning(GetErrorCode(singleLine), singleLine); return; } // Try to map back to the original resource file, so when the user // double clicks the error, it won't take them to the obj/Debug copy string newfile = MonoAndroidHelper.FixUpAndroidResourcePath(file, resourceDirectory, string.Empty, resource_name_case_map); if (!string.IsNullOrEmpty(newfile)) { file = newfile; } // Strip any "Error:" text from aapt's output if (message.StartsWith("error: ", StringComparison.InvariantCultureIgnoreCase)) { message = message.Substring("error: ".Length); } if (level.Contains("error") || (line != 0 && !string.IsNullOrEmpty(file))) { LogCodedError(GetErrorCode(message), message, file, line); return; } } if (!apptResult) { var message = string.Format("{0} \"{1}\".", singleLine.Trim(), singleLine.Substring(singleLine.LastIndexOfAny(new char [] { '\\', '/' }) + 1)); LogCodedError(GetErrorCode(message), message, ToolName); } else { LogCodedWarning(GetErrorCode(singleLine), singleLine); } }
public void LogInfo <T>(MessageImportance msgImportance, IEnumerable <T> IEnumInfoToLog) //where T : class { LogInfo <T>(msgImportance, IEnumInfoToLog, (i) => i.ToString()); }
protected virtual void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) { if (singleLine.Length == 0) { Log.LogMessage(singleLine, messageImportance); return; } if (singleLine.StartsWith("Unhandled Exception: System.TypeLoadException") || singleLine.StartsWith("Unhandled Exception: System.IO.FileNotFoundException")) { typeLoadException = true; } // When IncludeDebugInformation is true, prevents the debug symbols stats from braeking this. if (singleLine.StartsWith("WROTE SYMFILE") || singleLine.StartsWith("OffsetTable") || singleLine.StartsWith("Compilation succeeded") || singleLine.StartsWith("Compilation failed")) { return; } var result = MSBuildErrorParser.TryParseLine(singleLine); if (result == null) { Log.LogMessage(messageImportance, singleLine); return; } string filename = result.Origin ?? GetType().Name.ToUpper(); if (result.IsError) { Log.LogError( result.Subcategory, result.Code, null, filename, result.Line, result.Column, result.EndLine, result.EndColumn, result.Message ); } else { Log.LogWarning( result.Subcategory, result.Code, null, filename, result.Line, result.Column, result.EndLine, result.EndColumn, result.Message ); } }
protected override void LogEventsFromTextOutput(string singleLine, MessageImportance importance) { // System.Diagnostics.Trace.Assert(false); var get_location = new Func <string, Location> ( (before) => { var str = singleLine.Substring(0, singleLine.IndexOf(before)); if (string.IsNullOrEmpty(str)) { return(new Location()); } // Path can contain ':'. We should skip it... var dir = str.StartsWith(":") ? "" : Path.GetDirectoryName(str); // Find first location separator (it's a end of path) var locIndex = str.IndexOf(':', dir.Length); var path = (locIndex <= 0) ? dir : str.Substring(0, locIndex); var locStr = str.Substring(locIndex); var parts = locStr.Trim().Trim(':').Split(':'); switch (parts.Length) { case 2: var line = int.Parse(parts[0]); var pos = int.Parse(parts[1]); return(new Location { File = path, StartLine = line, StartPos = pos, EndLine = line, EndPos = pos + 1 }); case 4: return(new Location { File = path, StartLine = int.Parse(parts[0]), StartPos = int.Parse(parts[1]), EndLine = int.Parse(parts[2]), EndPos = int.Parse(parts[3]) }); default: return(new Location { File = path }); } }); var try_report = new Func <string, Action <Location, string>, bool>( (tag, action) => { var index = singleLine.IndexOf(tag); if (index < 0) { return(false); } var loc = get_location(tag); action(loc, singleLine.Substring((tag == "hint:") ? index : index + tag.Length + 1)); return(true); }); var log_error = new Action <Location, string>( (loc, msg) => { Log.LogError(null, null, null, loc.File, loc.StartLine, loc.StartPos, loc.EndLine, loc.EndPos, msg); }); var log_warning = new Action <Location, string>( (loc, msg) => { Log.LogWarning(null, null, null, loc.File, loc.StartLine, loc.StartPos, loc.EndLine, loc.EndPos, msg); }); var _ = try_report("error:", log_error) || try_report("warning:", log_warning) || try_report("debug:", log_error) || try_report("hint:", log_warning) || Log.LogMessageFromText(singleLine, MessageImportance.High); }
static bool?CompileCore(IBuildEngine engine, CecilTypeSystem typeSystem, string projectDirectory, bool verifyIl, MessageImportance logImportance , bool debuggerLaunch = false) { if (debuggerLaunch) { // According this https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.debugger.launch?view=net-6.0#remarks // documentation, on not windows platform Debugger.Launch() always return true without running a debugger. if (System.Diagnostics.Debugger.Launch()) { // Set timeout at 1 minut. var time = new System.Diagnostics.Stopwatch(); var timeout = TimeSpan.FromMinutes(1); time.Start(); // wait for the debugger to be attacked or timeout. while (!System.Diagnostics.Debugger.IsAttached && time.Elapsed < timeout) { engine.LogMessage($"[PID:{System.Diagnostics.Process.GetCurrentProcess().Id}] Wating attach debugger. Elapsed {time.Elapsed}...", MessageImportance.High); System.Threading.Thread.Sleep(100); } time.Stop(); if (time.Elapsed >= timeout) { engine.LogMessage("Wating attach debugger timeout.", MessageImportance.Normal); } } else { engine.LogMessage("Debugging cancelled.", MessageImportance.Normal); } } var asm = typeSystem.TargetAssemblyDefinition; var emres = new EmbeddedResources(asm); var avares = new AvaloniaResources(asm, projectDirectory); if (avares.Resources.Count(CheckXamlName) == 0 && emres.Resources.Count(CheckXamlName) == 0) { // Nothing to do return(null); } var clrPropertiesDef = new TypeDefinition("CompiledAvaloniaXaml", "XamlIlHelpers", TypeAttributes.Class, asm.MainModule.TypeSystem.Object); asm.MainModule.Types.Add(clrPropertiesDef); var indexerAccessorClosure = new TypeDefinition("CompiledAvaloniaXaml", "!IndexerAccessorFactoryClosure", TypeAttributes.Class, asm.MainModule.TypeSystem.Object); asm.MainModule.Types.Add(indexerAccessorClosure); var trampolineBuilder = new TypeDefinition("CompiledAvaloniaXaml", "XamlIlTrampolines", TypeAttributes.Class, asm.MainModule.TypeSystem.Object); asm.MainModule.Types.Add(trampolineBuilder); var(xamlLanguage, emitConfig) = AvaloniaXamlIlLanguage.Configure(typeSystem); var compilerConfig = new AvaloniaXamlIlCompilerConfiguration(typeSystem, typeSystem.TargetAssembly, xamlLanguage, XamlXmlnsMappings.Resolve(typeSystem, xamlLanguage), AvaloniaXamlIlLanguage.CustomValueConverter, new XamlIlClrPropertyInfoEmitter(typeSystem.CreateTypeBuilder(clrPropertiesDef)), new XamlIlPropertyInfoAccessorFactoryEmitter(typeSystem.CreateTypeBuilder(indexerAccessorClosure)), new XamlIlTrampolineBuilder(typeSystem.CreateTypeBuilder(trampolineBuilder)), new DeterministicIdGenerator()); var contextDef = new TypeDefinition("CompiledAvaloniaXaml", "XamlIlContext", TypeAttributes.Class, asm.MainModule.TypeSystem.Object); asm.MainModule.Types.Add(contextDef); var contextClass = XamlILContextDefinition.GenerateContextClass(typeSystem.CreateTypeBuilder(contextDef), typeSystem, xamlLanguage, emitConfig); var compiler = new AvaloniaXamlIlCompiler(compilerConfig, emitConfig, contextClass) { EnableIlVerification = verifyIl }; var editorBrowsableAttribute = typeSystem .GetTypeReference(typeSystem.FindType("System.ComponentModel.EditorBrowsableAttribute")) .Resolve(); var editorBrowsableCtor = asm.MainModule.ImportReference(editorBrowsableAttribute.GetConstructors() .First(c => c.Parameters.Count == 1)); var runtimeHelpers = typeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.XamlIlRuntimeHelpers"); var createRootServiceProviderMethod = asm.MainModule.ImportReference( typeSystem.GetTypeReference(runtimeHelpers).Resolve().Methods .First(x => x.Name == "CreateRootServiceProviderV2")); var loaderDispatcherDef = new TypeDefinition("CompiledAvaloniaXaml", "!XamlLoader", TypeAttributes.Class, asm.MainModule.TypeSystem.Object); loaderDispatcherDef.CustomAttributes.Add(new CustomAttribute(editorBrowsableCtor) { ConstructorArguments = { new CustomAttributeArgument(editorBrowsableCtor.Parameters[0].ParameterType, 1) } }); var loaderDispatcherMethod = new MethodDefinition("TryLoad", MethodAttributes.Static | MethodAttributes.Public, asm.MainModule.TypeSystem.Object) { Parameters = { new ParameterDefinition(asm.MainModule.TypeSystem.String) } }; loaderDispatcherDef.Methods.Add(loaderDispatcherMethod); asm.MainModule.Types.Add(loaderDispatcherDef); var stringEquals = asm.MainModule.ImportReference(asm.MainModule.TypeSystem.String.Resolve().Methods.First( m => m.IsStatic && m.Name == "Equals" && m.Parameters.Count == 2 && m.ReturnType.FullName == "System.Boolean" && m.Parameters[0].ParameterType.FullName == "System.String" && m.Parameters[1].ParameterType.FullName == "System.String")); bool CompileGroup(IResourceGroup group) { var typeDef = new TypeDefinition("CompiledAvaloniaXaml", "!" + group.Name, TypeAttributes.Class, asm.MainModule.TypeSystem.Object); typeDef.CustomAttributes.Add(new CustomAttribute(editorBrowsableCtor) { ConstructorArguments = { new CustomAttributeArgument(editorBrowsableCtor.Parameters[0].ParameterType, 1) } }); asm.MainModule.Types.Add(typeDef); var builder = typeSystem.CreateTypeBuilder(typeDef); foreach (var res in group.Resources.Where(CheckXamlName).OrderBy(x => x.FilePath.ToLowerInvariant())) { try { engine.LogMessage($"XAMLIL: {res.Name} -> {res.Uri}", logImportance); // StreamReader is needed here to handle BOM var xaml = new StreamReader(new MemoryStream(res.FileContents)).ReadToEnd(); var parsed = XDocumentXamlParser.Parse(xaml); var initialRoot = (XamlAstObjectNode)parsed.Root; var precompileDirective = initialRoot.Children.OfType <XamlAstXmlDirective>() .FirstOrDefault(d => d.Namespace == XamlNamespaces.Xaml2006 && d.Name == "Precompile"); if (precompileDirective != null) { var precompileText = (precompileDirective.Values[0] as XamlAstTextNode)?.Text.Trim() .ToLowerInvariant(); if (precompileText == "false") { continue; } if (precompileText != "true") { throw new XamlParseException("Invalid value for x:Precompile", precompileDirective); } } var classDirective = initialRoot.Children.OfType <XamlAstXmlDirective>() .FirstOrDefault(d => d.Namespace == XamlNamespaces.Xaml2006 && d.Name == "Class"); IXamlType classType = null; if (classDirective != null) { if (classDirective.Values.Count != 1 || !(classDirective.Values[0] is XamlAstTextNode tn)) { throw new XamlParseException("x:Class should have a string value", classDirective); } classType = typeSystem.TargetAssembly.FindType(tn.Text); if (classType == null) { throw new XamlParseException($"Unable to find type `{tn.Text}`", classDirective); } compiler.OverrideRootType(parsed, new XamlAstClrTypeReference(classDirective, classType, false)); initialRoot.Children.Remove(classDirective); } compiler.Transform(parsed); var populateName = classType == null ? "Populate:" + res.Name : "!XamlIlPopulate"; var buildName = classType == null ? "Build:" + res.Name : null; var classTypeDefinition = classType == null ? null : typeSystem.GetTypeReference(classType).Resolve(); var populateBuilder = classTypeDefinition == null ? builder : typeSystem.CreateTypeBuilder(classTypeDefinition); compiler.Compile(parsed, contextClass, compiler.DefinePopulateMethod(populateBuilder, parsed, populateName, classTypeDefinition == null), buildName == null ? null : compiler.DefineBuildMethod(builder, parsed, buildName, true), builder.DefineSubType(compilerConfig.WellKnownTypes.Object, "NamespaceInfo:" + res.Name, true), (closureName, closureBaseType) => populateBuilder.DefineSubType(closureBaseType, closureName, false), (closureName, returnType, parameterTypes) => populateBuilder.DefineDelegateSubType(closureName, false, returnType, parameterTypes), res.Uri, res ); if (classTypeDefinition != null) { var compiledPopulateMethod = typeSystem.GetTypeReference(populateBuilder).Resolve() .Methods.First(m => m.Name == populateName); var designLoaderFieldType = typeSystem .GetType("System.Action`1") .MakeGenericType(typeSystem.GetType("System.Object")); var designLoaderFieldTypeReference = (GenericInstanceType)typeSystem.GetTypeReference(designLoaderFieldType); designLoaderFieldTypeReference.GenericArguments[0] = asm.MainModule.ImportReference(designLoaderFieldTypeReference.GenericArguments[0]); designLoaderFieldTypeReference = (GenericInstanceType) asm.MainModule.ImportReference(designLoaderFieldTypeReference); var designLoaderLoad = typeSystem.GetMethodReference( designLoaderFieldType.Methods.First(m => m.Name == "Invoke")); designLoaderLoad = asm.MainModule.ImportReference(designLoaderLoad); designLoaderLoad.DeclaringType = designLoaderFieldTypeReference; var designLoaderField = new FieldDefinition("!XamlIlPopulateOverride", FieldAttributes.Static | FieldAttributes.Private, designLoaderFieldTypeReference); classTypeDefinition.Fields.Add(designLoaderField); const string TrampolineName = "!XamlIlPopulateTrampoline"; var trampoline = new MethodDefinition(TrampolineName, MethodAttributes.Static | MethodAttributes.Private, asm.MainModule.TypeSystem.Void); trampoline.Parameters.Add(new ParameterDefinition(classTypeDefinition)); classTypeDefinition.Methods.Add(trampoline); var regularStart = Instruction.Create(OpCodes.Call, createRootServiceProviderMethod); trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Ldsfld, designLoaderField)); trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Brfalse, regularStart)); trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Ldsfld, designLoaderField)); trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Call, designLoaderLoad)); trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); trampoline.Body.Instructions.Add(regularStart); trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Call, compiledPopulateMethod)); trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); CopyDebugDocument(trampoline, compiledPopulateMethod); var foundXamlLoader = false; // Find AvaloniaXamlLoader.Load(this) and replace it with !XamlIlPopulateTrampoline(this) foreach (var method in classTypeDefinition.Methods .Where(m => !m.Attributes.HasFlag(MethodAttributes.Static))) { var i = method.Body.Instructions; for (var c = 1; c < i.Count; c++) { if (i[c].OpCode == OpCodes.Call) { var op = i[c].Operand as MethodReference; // TODO: Throw an error // This usually happens when the same XAML resource was added twice for some weird reason // We currently support it for dual-named default theme resources if (op != null && op.Name == TrampolineName) { foundXamlLoader = true; break; } if (op != null && op.Name == "Load" && op.Parameters.Count == 1 && op.Parameters[0].ParameterType.FullName == "System.Object" && op.DeclaringType.FullName == "Avalonia.Markup.Xaml.AvaloniaXamlLoader") { if (MatchThisCall(i, c - 1)) { i[c].Operand = trampoline; foundXamlLoader = true; } } } } } if (!foundXamlLoader) { var ctors = classTypeDefinition.GetConstructors() .Where(c => !c.IsStatic).ToList(); // We can inject xaml loader into default constructor if (ctors.Count == 1 && ctors[0].Body.Instructions.Count(o => o.OpCode != OpCodes.Nop) == 3) { var i = ctors[0].Body.Instructions; var retIdx = i.IndexOf(i.Last(x => x.OpCode == OpCodes.Ret)); i.Insert(retIdx, Instruction.Create(OpCodes.Call, trampoline)); i.Insert(retIdx, Instruction.Create(OpCodes.Ldarg_0)); } else { throw new InvalidProgramException( $"No call to AvaloniaXamlLoader.Load(this) call found anywhere in the type {classType.FullName} and type seems to have custom constructors."); } } } if (buildName != null || classTypeDefinition != null) { var compiledBuildMethod = buildName == null ? null : typeSystem.GetTypeReference(builder).Resolve() .Methods.First(m => m.Name == buildName); var parameterlessConstructor = compiledBuildMethod != null ? null : classTypeDefinition.GetConstructors().FirstOrDefault(c => c.IsPublic && !c.IsStatic && !c.HasParameters); if (compiledBuildMethod != null || parameterlessConstructor != null) { var i = loaderDispatcherMethod.Body.Instructions; var nop = Instruction.Create(OpCodes.Nop); i.Add(Instruction.Create(OpCodes.Ldarg_0)); i.Add(Instruction.Create(OpCodes.Ldstr, res.Uri)); i.Add(Instruction.Create(OpCodes.Call, stringEquals)); i.Add(Instruction.Create(OpCodes.Brfalse, nop)); if (parameterlessConstructor != null) { i.Add(Instruction.Create(OpCodes.Newobj, parameterlessConstructor)); } else { i.Add(Instruction.Create(OpCodes.Call, createRootServiceProviderMethod)); i.Add(Instruction.Create(OpCodes.Call, compiledBuildMethod)); } i.Add(Instruction.Create(OpCodes.Ret)); i.Add(nop); } } } catch (Exception e) { int lineNumber = 0, linePosition = 0; if (e is XamlParseException xe) { lineNumber = xe.LineNumber; linePosition = xe.LinePosition; } engine.LogErrorEvent(new BuildErrorEventArgs("Avalonia", "XAMLIL", res.FilePath, lineNumber, linePosition, lineNumber, linePosition, e.Message, "", "Avalonia")); return(false); } res.Remove(); } // Technically that's a hack, but it fixes corert incompatibility caused by deterministic builds int dupeCounter = 1; foreach (var grp in typeDef.NestedTypes.GroupBy(x => x.Name)) { if (grp.Count() > 1) { foreach (var dupe in grp) { dupe.Name += "_dup" + dupeCounter++; } } } return(true); } if (emres.Resources.Count(CheckXamlName) != 0) { if (!CompileGroup(emres)) { return(false); } } if (avares.Resources.Count(CheckXamlName) != 0) { if (!CompileGroup(avares)) { return(false); } avares.Save(); } loaderDispatcherMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldnull)); loaderDispatcherMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); return(true); }
protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) { this.Log.LogMessage(MessageImportance.Normal, singleLine); }
public void LogCommentFromText(MSBuildContext buildEventContext, MessageImportance messageImportance, string message) { LoggingService.LogInfo("[MSBuild] " + message); }
/// <summary> /// Display a test-generator message to the user via the MSBuild logger. /// </summary> /// <param name="sender">The sender of the message.</param> /// <param name="e">Arguments for the message event.</param> private void DisplayMessage(object sender, DisplayEventArgs e) { MessageImportance importance = (MessageLevel.Error == e.Level || MessageLevel.Warning == e.Level) ? MessageImportance.High : MessageImportance.Normal; this.Log.LogMessage(importance, e.Message); }
public override bool Execute() { Importance = Verbose ? MessageImportance.Normal : MessageImportance.Low; if (FudgeFactor >= 0 && Timeout < int.MaxValue) { Timeout *= FudgeFactor; } var retVal = true; if (Timeout == int.MaxValue) { Log.LogMessage(MessageImportance.Normal, "Running {0}", TestProgramName); } else { Log.LogMessage(MessageImportance.Normal, "Running {0} (timeout = {1} seconds)", TestProgramName, (Timeout / 1000.0).ToString("F1")); } Thread outputThread = null; Thread errorThread = null; var dtStart = DateTime.Now; try { // Start the external process var process = StartProcess(); outputThread = new Thread(StreamReaderThread_Output); errorThread = new Thread(StreamReaderThread_Error); _stdOut = process.StandardOutput; _stdError = process.StandardError; outputThread.Start(); errorThread.Start(); // Wait for the process to terminate process.WaitForExit(Timeout); // Wait for the threads to terminate outputThread.Join(2000); errorThread.Join(2000); var fTimedOut = !process.WaitForExit(0); // returns false immediately if still running. if (fTimedOut) { try { process.Kill(); } catch { // ignore possible exceptions that are thrown when the // process is terminated } } var delta = DateTime.Now - dtStart; Log.LogMessage(MessageImportance.Normal, "Total time for running {0} = {1}", TestProgramName, delta); try { ProcessOutput(fTimedOut, delta); } catch //(Exception e) { //Console.WriteLine("CAUGHT EXCEPTION: {0}", e.Message); //Console.WriteLine("STACK: {0}", e.StackTrace); } // If the test timed out, it was killed and its ExitCode is not available. // So check for a timeout first. if (fTimedOut) { Log.LogError("The tests in {0} did not finish in {1} milliseconds.", TestProgramName, Timeout); FailedSuites = FailedSuiteNames; retVal = false; } else if (process.ExitCode != 0) { Log.LogWarning("{0} returned with exit code {1}", TestProgramName, process.ExitCode); FailedSuites = FailedSuiteNames; if (process.ExitCode < 0 && _failTaskIfNegativeExitCode) { retVal = false; } if (process.ExitCode > 0 && _failTaskIfPositiveExitCode) { retVal = false; } // Return true in this case - at least NUnit returns non-zero exit code when // a test fails, but we don't want to stop the build. } } catch (Exception e) { Log.LogErrorFromException(e, true); retVal = false; } finally { // ensure outputThread is always aborted if (outputThread != null && outputThread.IsAlive) { outputThread.Abort(); } // ensure errorThread is always aborted if (errorThread != null && errorThread.IsAlive) { errorThread.Abort(); } } // If we logged errors we never want to return true. Test failures will be reported // as warnings, not as errors. return(retVal && !Log.HasLoggedErrors); }
public void LogMessage(MessageImportance importance, string format, params string[] args) => Log(CreateMessage(importance.ToLevel(), format, args));
protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) { toolOutput.Append(singleLine); Log.LogMessage(messageImportance, "{0}", singleLine); }
void LogWithPrecedingNewLine(MessageImportance importance, string format, params object [] args) { Log.LogMessage(importance, String.Empty); Log.LogMessage(importance, format, args); }
protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) { // TODO: do proper parsing of error messages and such Log.LogMessage(messageImportance, "{0}", singleLine); }
protected ToolTask() : this(null, null) { this.standardErrorLoggingImportance = MessageImportance.High; this.standardOutputLoggingImportance = MessageImportance.Normal; }
/// <summary> /// Logs a message of the given importance using the specified string. /// </summary> /// <remarks>This method is not thread-safe.</remarks> /// <param name="Log">The Log to log to.</param> /// <param name="importance">The importance level of the message.</param> /// <param name="message">The message string.</param> /// <param name="messageArgs">Optional arguments for formatting the message string.</param> /// <exception cref="ArgumentNullException">Thrown when <c>message</c> is null.</exception> internal static void LogMessage(TaskLoggingHelper Log, MessageImportance importance, string message, params object[] messageArgs) { // Only log when we have been passed a TaskLoggingHelper Log?.LogMessage(importance, message, messageArgs); }
protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) { if (UsageError) { return; } int i = singleLine.IndexOf(string.Format("{0}:", ToolName)); if (i != -1) { i += (ToolName.Length + 1); Log.LogError("", "", "", "", 0, 0, 0, 0, string.Format("{0}: {1}", Path.GetFileName(ToolName), singleLine.Substring(i))); UsageError = true; } else { string s = singleLine.Trim(); if (s.StartsWith(WorkingDirectory)) { s = s.Substring(WorkingDirectory.Length); } string file = ""; int line = 0; string description = ""; // // Skip the drive letter // i = s.IndexOf(":"); if (i <= 1 && s.Length > i + 1) { i = s.IndexOf(":", i + 1); } if (i != -1) { file = Path.GetFullPath(s.Substring(0, i).Trim().Trim('"')); if (file.IndexOf(WorkingDirectory) != -1) { file = file.Substring(WorkingDirectory.Length) .Trim(Path.DirectorySeparatorChar); } if (s.Length > i + 1) { s = s.Substring(i + 1); i = s.IndexOf(":"); if (i != -1) { if (int.TryParse(s.Substring(0, i), out line)) { if (s.Length > i + 1) { s = s.Substring(i + 1); } } else { s = s.Substring(i); } } description = s.Trim(); description += Environment.NewLine; } } if (description.IndexOf("warning:") == 0) { // // Don't emit warnings while parsing dependencies otherwise // they will appear twices in the Error List and Output. // if (!Depend) { Log.LogWarning("", "", "", file, line - 1, 0, 0, 0, description.Substring("warning:".Length)); } } else if (description.IndexOf("error:") == 0) { Log.LogError("", "", "", file, line - 1, 0, 0, 0, description.Substring("error:".Length)); } else if (!string.IsNullOrEmpty(description)) { Log.LogError("", "", "", file, line - 1, 0, 0, 0, description); } } }
/// <summary> /// Log each of the messages in the given output with the given importance. /// We assume each line is a message to log. /// </summary> /// <remarks> /// Should be "private protected" visibility once it is introduced into C#. /// </remarks> internal abstract void LogMessages(string output, MessageImportance messageImportance);
public void LogMessage(MessageImportance importance, string message) { Context.Logger.LogMessage(importance, message); }
public void LogInfo(MessageImportance msgImp, string outputFormat, params string[] infoParam) { LogInfo(msgImp, string.Format(outputFormat, infoParam)); }
public void LogInfo <T>(MessageImportance msgImportance, IEnumerable <T> IEnumInfoToLog, string logMessagePriorToPrintCollection, params string[] infoParam) { LogInfo(msgImportance, logMessagePriorToPrintCollection, infoParam); LogInfo(msgImportance, IEnumInfoToLog); }
public void LogMessage(string message, MessageImportance level) { this.buildEngine.LogMessageEvent(new BuildMessageEventArgs(FormatMessage(message), string.Empty, SenderName, level)); }
public void LogInfo(MessageImportance msgImportance, Dictionary <string, string> dictionary, string infoMessageFormat, params string[] infoParam) { LogInfo(msgImportance, infoMessageFormat, infoParam); LogInfo(msgImportance, dictionary); }
/// <summary> /// Write a "standard" Message Log the translator /// </summary> private void WriteBuildMessageEventToStream(BuildMessageEventArgs buildMessageEventArgs, ITranslator translator) { MessageImportance importance = buildMessageEventArgs.Importance; translator.TranslateEnum(ref importance, (int)importance); }
public NetSdkBuildTaskLogger(Task taskInstance, MessageImportance msgImportance) : this(taskInstance.Log) { DefaultMessageImportance = msgImportance; UnderlyingTask = taskInstance; }
public static string RunProcess( string path, string args = "", IDictionary <string, string>?envVars = null, string?workingDir = null, bool ignoreErrors = false, bool silent = true, MessageImportance outputMessageImportance = MessageImportance.High, MessageImportance debugMessageImportance = MessageImportance.High) { LogInfo($"Running: {path} {args}", debugMessageImportance); var outputBuilder = new StringBuilder(); var errorBuilder = new StringBuilder(); var processStartInfo = new ProcessStartInfo { FileName = path, UseShellExecute = false, CreateNoWindow = true, RedirectStandardError = true, RedirectStandardOutput = true, Arguments = args, }; if (workingDir != null) { processStartInfo.WorkingDirectory = workingDir; } LogInfo($"Using working directory: {workingDir ?? Environment.CurrentDirectory}", debugMessageImportance); if (envVars != null) { if (envVars.Count > 0) { Logger?.LogMessage(MessageImportance.Low, "Setting environment variables for execution:"); } foreach (KeyValuePair <string, string> envVar in envVars) { processStartInfo.EnvironmentVariables[envVar.Key] = envVar.Value; Logger?.LogMessage(MessageImportance.Low, $"\t{envVar.Key} = {envVar.Value}"); } } Process?process = Process.Start(processStartInfo); if (process == null) { throw new ArgumentException($"Process.Start({path} {args}) returned null process"); } process.ErrorDataReceived += (sender, e) => { lock (s_SyncObj) { if (!silent) { LogWarning(e.Data); outputBuilder.AppendLine(e.Data); } errorBuilder.AppendLine(e.Data); } }; process.OutputDataReceived += (sender, e) => { lock (s_SyncObj) { if (!silent) { LogInfo(e.Data, outputMessageImportance); outputBuilder.AppendLine(e.Data); } } }; process.BeginOutputReadLine(); process.BeginErrorReadLine(); process.WaitForExit(); if (process.ExitCode != 0) { Logger?.LogMessage(MessageImportance.Low, $"Exit code: {process.ExitCode}"); if (!ignoreErrors) { throw new Exception("Error: " + errorBuilder); } } return(outputBuilder.ToString().Trim('\r', '\n')); }
/// <summary> /// Logs a text comment /// </summary> /// <param name="buildEventContext">The context</param> /// <param name="importance">The importance</param> /// <param name="message">The message</param> public void LogCommentFromText(BuildEventContext buildEventContext, MessageImportance importance, string message) { _writer(message); }
protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) { var match = codeErrorRegEx.Match(singleLine); if (!match.Success) { match = noFileWarningOrErrorRegEx.Match(singleLine); } if (match.Success) { if (matched) { // we are already in a warning/error ... // dont loose it GenerateErrorOrWarning(); } matched = true; file = match.Groups ["file"].Value; if (!string.IsNullOrEmpty(file)) { file = Path.Combine(TargetDirectory, file); // Try to map back to the original resource file, so when the user // double clicks the error, it won't take them to the obj/Debug copy if (ResourceDirectories != null) { foreach (var dir in ResourceDirectories) { var resourceDirectory = Path.Combine(TargetDirectory, dir.ItemSpec); string newfile = MonoAndroidHelper.FixUpAndroidResourcePath(file, resourceDirectory, string.Empty, resource_name_case_map); if (!string.IsNullOrEmpty(newfile)) { file = newfile; break; } } } } line = 0; int.TryParse(match.Groups ["line"].Value, out line); text = match.Groups ["text"].Value.Trim(); type = match.Groups ["type"].Value; if (string.IsNullOrEmpty(type)) { type = text.Contains("Error") ? "Error" : "Warning"; } column = 0; } if (matched) { if (singleLine.Trim() == "^") { column = singleLine.IndexOf("^"); GenerateErrorOrWarning(); } if (singleLine.Trim().Contains("~")) { column = singleLine.IndexOf("~"); GenerateErrorOrWarning(); } } else { base.LogEventsFromTextOutput(singleLine, messageImportance); } }