Пример #1
0
        /// <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);
            }
        }
Пример #2
0
        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;
        }
Пример #3
0
        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;
        }
Пример #4
0
        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);
        }
Пример #5
0
 public static void PushIndentation(string indentation, TextFilePosition source, EntryFeatures features)
 {
     if (TemplateRenderer.renderer == null)
     {
         return;
     }
     TemplateRenderer.renderer.PushIndentation(indentation, source, features);
 }
Пример #6
0
 public static void WriteLine(TextFilePosition source)
 {
     if (TemplateRenderer.renderer == null)
     {
         return;
     }
     TemplateRenderer.renderer.WriteLine(source);
 }
Пример #7
0
        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);
        }
Пример #8
0
 public FileLine(string text, int beginIndex, int beginIndexNonSpace, int endIndex, TextFilePosition position)
 {
     Text = text;
     BeginIndex = beginIndex;
     BeginIndexNonSpace = beginIndexNonSpace;
     EndIndex = endIndex;
     Position = position;
 }
Пример #9
0
 public static void PushCaller(TextFilePosition source)
 {
     if (TemplateRenderer.renderer == null)
     {
         return;
     }
     TemplateRenderer.renderer.PushCaller(source);
 }
Пример #10
0
        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;
                }
            }
        }
Пример #11
0
        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);
        }
Пример #12
0
 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);
     }
 }
Пример #13
0
        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);
        }
Пример #14
0
        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
        }
Пример #15
0
            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;
            }
Пример #16
0
        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;
        }
Пример #17
0
        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);
        }
Пример #18
0
        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));
        }
Пример #19
0
        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;
        }