예제 #1
0
 private Editor()
 {
     shadowClass = new ShadowClass();
     contexts = new Contexts(shadowClass);
     codeLexer = new CodeLexer(contexts);
     templateLexer = new TemplateLexer(contexts);
 }
예제 #2
0
        public static string Parse(string template, List<Type> extensions)
        {
            if (string.IsNullOrWhiteSpace(template)) return null;

            var output = string.Empty;
            var stream = new Stream(template);
            var shadowClass = new ShadowClass();
            var contexts = new Contexts(shadowClass);

            shadowClass.Clear();

            while (stream.Advance())
            {
                if (ParseCodeBlock(stream, shadowClass)) continue;
                if (ParseLambda(stream, shadowClass, contexts, ref output)) continue;
                output += stream.Current;
            }

            shadowClass.Parse();

            extensions.Clear();
            extensions.Add(Compiler.Compile(shadowClass));
            extensions.AddRange(FindExtensionClasses(shadowClass));

            return output;
        }
예제 #3
0
 public TemplateLexer(Contexts contexts)
 {
     _contexts = contexts;
     _fileContext = contexts.Find(nameof(File));
 }
예제 #4
0
        private static bool ParseLambda(Stream stream, ShadowClass shadowClass, Contexts contexts, ref string template)
        {
            if (stream.Current == '$')
            {
                var identifier = stream.PeekWord(1);
                if (identifier != null)
                {
                    var filter = stream.PeekBlock(identifier.Length + 2, '(', ')');
                    if (filter != null && stream.Peek(filter.Length + 2 + identifier.Length + 1) == '[')
                    {
                        try
                        {
                            var index = filter.IndexOf("=>", StringComparison.Ordinal);

                            if (index > 0)
                            {
                                var name = filter.Substring(0, index);

                                var contextName = identifier;
                                // Todo: Make the TemplateCodeParser context aware
                                if (contextName == "TypeArguments") contextName = "Types";
                                else if (contextName.StartsWith("Nested")) contextName = contextName.Remove(0, 6);

                                var type = contexts.Find(contextName)?.Type.FullName;

                                if (type == null) return false;

                                var methodIndex = counter++;

                                shadowClass.AddLambda(filter, type, name, methodIndex);

                                stream.Advance(filter.Length + 2 + identifier.Length);
                                template += $"${identifier}($__{methodIndex})";

                                return true;
                            }
                        }
                        catch
                        {
                        }
                    }
                }
            }

            return false;
        }
예제 #5
0
 public CodeLexer(Contexts contexts)
 {
     this.contexts = contexts;
     this.fileContext = contexts.Find(nameof(File));
 }