/// <summary> /// Pushes an indentation level. /// </summary> /// <param name="indentation">The indentation text.</param> public void PushIndentation(string indentation, TextFilePosition original, EntryFeatures features = EntryFeatures.None) { if (indentation == null) { throw new ArgumentNullException(nameof(indentation)); } if (original == null) { throw new ArgumentNullException(nameof(original)); } if (this.IsLineBlank) { var callerIndex = (this.CallerIndexStack.Count == 0) ? -1 : this.CallerIndexStack.Peek(); this.IndentationStack.Push(new IndentationItem(indentation, original, callerIndex, features)); this.PopIndendationStack.Push(true); } else { // Compensation for InterpolationRule Indentation in case current line isn't blank anymore. // Uses helper stack to track if the current indentation must be really popped. this.Write(indentation, original, EntryFeatures.ColumnInterpolation); this.PopIndendationStack.Push(false); } }
public OriginalTextSpan(string text, int begin, int end, TextFilePosition position) { if (text == null) { throw new ArgumentNullException(nameof(text)); } if (begin > end) { throw new ArgumentOutOfRangeException(nameof(begin), "Must be less equal than end."); } if (end > text.Length) { throw new ArgumentOutOfRangeException(nameof(end), "end must be less equal string length."); } this.Begin = begin; this.End = end; this.OriginalText = text; this.Text = OriginalText.Substring(Begin, End - Begin); if (position == null) { throw new ArgumentNullException(nameof(position)); } this.Position = position; }
public FileLine(string text, int begin, int beginNonSpace, int end, TextFilePosition position) { if (text == null) { throw new ArgumentNullException(nameof(text)); } if (begin > beginNonSpace) { throw new ArgumentOutOfRangeException(nameof(begin), $"Must be less equal than {nameof(beginNonSpace)}."); } if (beginNonSpace > end) { throw new ArgumentOutOfRangeException(nameof(beginNonSpace), $"Must be less equal than {nameof(end)}."); } if (end > text.Length) { throw new ArgumentOutOfRangeException(nameof(end), $"Must be less equal {nameof(text)} length."); } this.Text = text; this.Begin = begin; this.BeginNonSpace = beginNonSpace; this.End = end; this.Position = position; }
private void PrintException(Exception ex, List <GeneratedCode> generatedCodes) { var frames = new List <Interface.StackFrame>(); var stackTrace = new StackTrace(ex, true); for (int i = 0; i < stackTrace.FrameCount; ++i) { System.Diagnostics.StackFrame diagnosticFrame = stackTrace.GetFrame(i); // Extract method name MethodBase method = diagnosticFrame.GetMethod(); // Note(Maik): Skip internal render methods in case of a stack trace. if (Attribute.IsDefined(method, typeof(HideStackTraceAttribute))) { continue; } Type declaringType = method.DeclaringType; var methodSb = new StringBuilder(); if (declaringType != null) { methodSb.Append(declaringType.FullName).Append("."); } methodSb.Append(method.Name); // Extract original filename, line and column int?line = null; if (diagnosticFrame.GetFileLineNumber() != 0) { line = diagnosticFrame.GetFileLineNumber(); } int?column = null; if (diagnosticFrame.GetFileColumnNumber() != 0) { column = diagnosticFrame.GetFileColumnNumber(); } string filename = diagnosticFrame.GetFileName(); GeneratedCode generatedCode = generatedCodes.FirstOrDefault(gcode => string.Compare(gcode.TemplatePath, filename, StringComparison.OrdinalIgnoreCase) == 0); if ((generatedCode != null) && (line != null)) { var position = new TextPosition(line.Value, column ?? 1); TextFilePosition original = generatedCode.SourceMap.FindSourceByGenerated(position); if (original.IsValid) { filename = original.Name; line = original.Line; column = original.Column; } } var msgFrame = new Interface.StackFrame(methodSb.ToString(), filename, line, column); frames.Add(msgFrame); } // for this.MessageHandler.Message(TraceLevel.Error, $"{ex.GetType().FullName}: {ex.Message}", string.Empty, new TextPosition()); this.MessageHandler.StackTrace(frames); }
public static void PushIndentation(string indentation, TextFilePosition source, EntryFeatures features) { if (TemplateRenderer.renderer == null) { return; } TemplateRenderer.renderer.PushIndentation(indentation, source, features); }
public static void WriteLine(TextFilePosition source) { if (TemplateRenderer.renderer == null) { return; } TemplateRenderer.renderer.WriteLine(source); }
public void PushCaller(TextFilePosition original) { var parentIndex = (this.CallerIndexStack.Count == 0) ? -1 : this.CallerIndexStack.Peek(); int callerIndex = this.Mapping.AddCaller(original, parentIndex); this.CallerIndexStack.Push(callerIndex); }
public FileLine(string text, int beginIndex, int beginIndexNonSpace, int endIndex, TextFilePosition position) { Text = text; BeginIndex = beginIndex; BeginIndexNonSpace = beginIndexNonSpace; EndIndex = endIndex; Position = position; }
public static void PushCaller(TextFilePosition source) { if (TemplateRenderer.renderer == null) { return; } TemplateRenderer.renderer.PushCaller(source); }
public void Write(string text, TextFilePosition original, EntryFeatures features = EntryFeatures.None) { // Skip empty spans if (string.IsNullOrEmpty(text)) { return; } var index = 0; while (index < text.Length) { if (this.IsLineBlank) { foreach (var indentationItem in this.IndentationStack.Reverse()) { if (indentationItem.Indentation.Length > 0) { var entry = new MappingEntry(this.Position(), indentationItem.Original, indentationItem.CallerIndex, indentationItem.Features); this.Mapping.Add(entry); this.TextWriter.Write(indentationItem.Indentation); this.Column += indentationItem.Indentation.Length; } } this.IsLineBlank = false; } var callerIndex = (this.CallerIndexStack.Count == 0) ? -1 : this.CallerIndexStack.Peek(); var lineBreakIndex = text.IndexOf('\n', index); if (lineBreakIndex == -1) { // No line break found var len = (text.Length - index); if (original.IsValid && (len > 0)) { var entry = new MappingEntry(this.Position(), original, callerIndex, features); this.Mapping.Add(entry); } this.TextWriter.Write(text.Substring(index, text.Length - index)); Column += len; index += len; } else { // Line break found ++lineBreakIndex; var len = (lineBreakIndex - index); if (original.IsValid && (len > 0)) { var entry = new MappingEntry(this.Position(), original, callerIndex, features); this.Mapping.Add(entry); } this.TextWriter.Write(text.Substring(index, text.Length - lineBreakIndex)); index += len; ++Line; this.IsLineBlank = true; this.Column = 1; } } }
private Assembly CompileCode(List <GeneratedCode> generatedCodes) { // Prepare compiler var parameters = new CompilerParameters(); parameters.GenerateInMemory = true; parameters.TreatWarningsAsErrors = true; parameters.IncludeDebugInformation = true; parameters.CompilerOptions = string.Join(" ", Constants.CompilerOptions); parameters.ReferencedAssemblies.AddRange(Constants.CompilerAssemblies); parameters.ReferencedAssemblies.AddRange(this.ReferencedAssemblies.ToArray()); parameters.ReferencedAssemblies.Add(typeof(TemplateCompiler).Assembly.Location); // Compile CompilerResults compilerResults; using (var codeProvider = new CSharpCodeProvider()) { var codes = generatedCodes.Select(generatedCode => generatedCode.Code).ToArray(); compilerResults = codeProvider.CompileAssemblyFromSource(parameters, codes); } // Report errors foreach (CompilerError compilerError in compilerResults.Errors) { string filename = compilerError.FileName; var textPosition = new TextPosition(); if (compilerError.Line != 0 && compilerError.Column != 0) { GeneratedCode generatedCode = generatedCodes.FirstOrDefault(gcode => string.Compare(gcode.TemplatePath, compilerError.FileName, StringComparison.OrdinalIgnoreCase) == 0); if (generatedCode != null) { var errorPosition = new TextPosition(compilerError.Line, compilerError.Column); TextFilePosition original = generatedCode.SourceMap.FindSourceByGenerated(errorPosition); if (original.IsValid) { textPosition = new TextPosition(original.Line, original.Column); } } else { textPosition = new TextPosition(compilerError.Line, compilerError.Column); } } TraceLevel traceLevel = compilerError.IsWarning ? TraceLevel.Warning : TraceLevel.Error; this.MessageHandler.Message(traceLevel, $"{compilerError.ErrorNumber}: {compilerError.ErrorText}", filename, textPosition); } if (compilerResults.Errors.Count > 0) { return(null); } return(compilerResults.CompiledAssembly); }
public void WriteLine(TextFilePosition original) { this.TextWriter.WriteLine(); this.IsLineBlank = true; ++Line; this.Column = 1; if (original.IsValid) { var callerIndex = (this.CallerIndexStack.Count == 0) ? -1 : this.CallerIndexStack.Peek(); var entry = new MappingEntry(this.Position(), original, callerIndex, EntryFeatures.None); this.Mapping.Add(entry); } }
public static void Write(Func <string> func, TextFilePosition source, EntryFeatures features) { if (TemplateRenderer.renderer == null) { return; } TemplateRenderer.renderer.PushCaller(source); string text = func(); TemplateRenderer.renderer.PopCaller(); TemplateRenderer.renderer.Write(text, source, features); }
public static void Write(Action action, TextFilePosition source, EntryFeatures features) { if (TemplateRenderer.renderer == null) { return; } TemplateRenderer.renderer.PushCaller(source); action(); TemplateRenderer.renderer.PopCaller(); #pragma warning disable CS1717 // Assignment made to same variable features = features; #pragma warning restore CS1717 // Assignment made to same variable }
public IndentationItem(string indentation, TextFilePosition original, int callerIndex, EntryFeatures features) { if (indentation == null) { throw new ArgumentNullException(nameof(indentation)); } this.Indentation = indentation; if (original == null) { throw new ArgumentNullException(nameof(original)); } this.Original = original; this.CallerIndex = callerIndex; this.Features = features; }
public OriginalTextSpan(string text, TextFilePosition position) { if (text == null) { throw new ArgumentNullException(nameof(text)); } this.Begin = 0; this.End = text.Length; this.OriginalText = text; this.Text = text; if (position == null) { throw new ArgumentNullException(nameof(position)); } this.Position = position; }
public List <AsbtractRenderCommand> Parse(string originalName, string text) { var commands = new List <AsbtractRenderCommand>(); int index = 0; int nonSpaceIndex = 0; int end = 0; int line = 1; while (index < text.Length) { nonSpaceIndex = text.IndexOfNot(index, text.Length, CharExtensions.IsSpace); end = text.IndexOf(nonSpaceIndex, text.Length, CharExtensions.IsNewline); IParserRule parserRule; List <AsbtractRenderCommand> ruleCommands; var textFilePostion = new TextFilePosition(originalName, new TextPosition(line, 1)); var fileLine = new FileLine(text, index, nonSpaceIndex, end, textFilePostion); if (this.ParseRules.TryGetValue(text[nonSpaceIndex], out parserRule)) { ruleCommands = parserRule.Parse(fileLine, this.MessageHandler); } else { ruleCommands = this.FallbackRule.Parse(fileLine, this.MessageHandler); } commands.AddRange(ruleCommands); if (end == text.Length) { break; } char complementaryNewLineChar = ((text[end] == '\n') ? '\r' : '\n'); index = text.IndexOfNot(end + 1, text.Length, c => c == complementaryNewLineChar); ++line; } return(commands); }
public OriginalTextSpan CreateOriginalTextSpan(int begin, int end) { if (begin > end) { throw new ArgumentOutOfRangeException(nameof(begin), $"Must be less equal than {nameof(end)}."); } if (begin < this.Begin) { throw new ArgumentOutOfRangeException($"{nameof(begin)} is smaller than {nameof(FileLine)} {nameof(this.Begin)}!"); } if (end > this.End) { throw new ArgumentOutOfRangeException($"{nameof(end)} is greater than {nameof(FileLine)} {nameof(this.End)}!"); } var position = new TextPosition(this.Position.Line, begin - this.Begin + 1); var filePosition = new TextFilePosition(this.Position.Name, position); return(new OriginalTextSpan(this.Text, begin, end, filePosition)); }
private string SourceExpression(TextFilePosition position) { var escapedSourceName = position.Name.Escape(); return($"new _Source(\"{escapedSourceName}\", {position.Line}, {position.Column})"); }
Assembly CompileCode(List<string> sources) { // Prepare compiler var parameters = new CompilerParameters(); parameters.GenerateInMemory = true; parameters.MainClass = "Twofold.Entry"; parameters.ReferencedAssemblies.Add("System.dll"); parameters.ReferencedAssemblies.Add("System.Core.dll"); foreach (string referencedAssembly in referencedAssemblies) { parameters.ReferencedAssemblies.Add(referencedAssembly); } // Compile var codeProvider = new CSharpCodeProvider(); CompilerResults compilerResults = codeProvider.CompileAssemblyFromSource(parameters, sources.ToArray()); if (compilerResults.Errors.Count > 0) { foreach (CompilerError compilerError in compilerResults.Errors) { TraceLevel traceLevel = compilerError.IsWarning ? TraceLevel.Warning : TraceLevel.Error; var errorPosition = new TextFilePosition(compilerError.FileName, new TextPosition(compilerError.Line, compilerError.Column)); messageHandler.CSharpMessage(traceLevel, errorPosition, compilerError.ToString()); } } return compilerResults.CompiledAssembly; }