private static bool ParseCodeBlock(Stream stream, ShadowClass shadowClass) { if (stream.Current == '$' && stream.Peek() == '{') { for (var i = 0; ; i--) { var current = stream.Peek(i); if (current == '`' || (current == '/' && stream.Peek(i - 1) == '/')) { return(false); } if (current == '\n' || current == char.MinValue) { break; } } stream.Advance(); var block = stream.PeekBlock(1, '{', '}'); var codeStream = new Stream(block, stream.Position + 1); ParseUsings(codeStream, shadowClass); ParseCode(codeStream, shadowClass); stream.Advance(block.Length + 1); return(true); } return(false); }
private static bool ParseReference(Stream stream, ShadowClass shadowClass /*, ProjectItem templateProjectItem*/) { const string keyword = "reference"; if (stream.Current == '#' && stream.Peek() == keyword[0] && stream.PeekWord(1) == keyword) { var reference = stream.PeekLine(keyword.Length + 1); if (reference != null) { var len = reference.Length + keyword.Length + 1; reference = reference.Trim('"', ' ', '\n', '\r'); try { /*if (reference.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) * reference = PathResolver.ResolveRelative(reference, templateProjectItem);*/ shadowClass.AddReference(reference); return(true); } catch (Exception ex) { //Log.Error("Reference Error: " + ex); Console.WriteLine($"Reference Error: {ex}"); } finally { stream.Advance(len - 1); } } } return(false); }
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 { //ignored } } } } return(false); }
private static void ParseUsings(Stream stream, ShadowClass shadowClass) { stream.Advance(); while (true) { stream.SkipWhitespace(); if ((stream.Current == 'u' && stream.PeekWord() == "using") || (stream.Current == '/' && stream.Peek() == '/')) { var line = stream.PeekLine(); shadowClass.AddUsing(line, stream.Position); stream.Advance(line.Length); continue; } break; } }
private static void ParseCode(Stream stream, ShadowClass shadowClass) { var code = new StringBuilder(); do { if (stream.Current != char.MinValue) { code.Append(stream.Current); } }while (stream.Advance()); shadowClass.AddBlock(code.ToString(), 0); }
public static string Parse(/*ProjectItem templateProjectItem, */ string template, List <Type> extensions) { if (string.IsNullOrWhiteSpace(template)) { return(null); } var output = string.Empty; var stream = new Stream(template); var shadowClass = new ShadowClass(template); var contexts = new Contexts(shadowClass); shadowClass.Clear(); while (stream.Advance()) { if (ParseReference(stream, shadowClass)) { continue; } if (ParseCodeBlock(stream, shadowClass)) { continue; } if (ParseLambda(stream, shadowClass, contexts, ref output)) { continue; } output += stream.Current; } shadowClass.Parse(); extensions.Clear(); extensions.Add(Compiler.Compile(/*templateProjectItem, */ shadowClass)); extensions.AddRange(FindExtensionClasses(shadowClass)); return(output); }
private bool ParseComment(Stream stream, SemanticModel semanticModel, Stack <Context> context, int depth) { if (stream.Current == '/') { var type = stream.Peek(); var start = stream.Position; if (type == '/') { while (stream.Advance()) { var length = stream.Position - start; if (ParseDollar(stream, semanticModel, context, depth)) { if (length > 0) { semanticModel.Tokens.Add(Classifications.Comment, start, length); } //if (stream.Advance() == false || stream.Current == Constants.NewLine) return true; if (stream.Peek() == char.MinValue) { return(true); } start = stream.Position + 1; } if (stream.Current == Constants.NewLine) { break; } } semanticModel.Tokens.Add(Classifications.Comment, start, stream.Position - start); return(true); } if (type == '*') { while (stream.Advance()) { var length = stream.Position - start; if (ParseDollar(stream, semanticModel, context, depth)) { if (length > 0) { semanticModel.Tokens.Add(Classifications.Comment, start, length); } //if (stream.Advance() == false || stream.Current == Constants.NewLine) return true; if (stream.Peek() == char.MinValue) { return(true); } start = stream.Position + 1; } if (stream.Current == Constants.NewLine) { semanticModel.Tokens.Add(Classifications.Comment, start, length); if (stream.Advance(2) == false) { return(true); } start = stream.Position; } if (stream.Current == '*' && stream.Peek() == '/') { stream.Advance(); semanticModel.Tokens.Add(Classifications.Comment, start, stream.Position + 1 - start); return(true); } } semanticModel.Tokens.Add(Classifications.Comment, start, stream.Position - start); return(true); } } return(false); }
private bool ParseDollar(Stream stream, SemanticModel semanticModel, Stack <Context> context, int depth) { if (stream.Current == '$') { var identifier = GetIdentifier(stream, semanticModel, context); if (identifier != null) { var classification = GetPropertyClassification(depth); if (identifier.IsParent) { var parent = context.Skip(1).FirstOrDefault()?.Name.ToLowerInvariant(); semanticModel.Tokens.Add(classification, stream.Position, identifier.Name.Length + 1, identifier.QuickInfo.Replace("$parent", parent)); stream.Advance(identifier.Name.Length); var current = context.Pop(); //ParseDot(stream, semanticModel, context, depth); // identifier ParseBlock(stream, semanticModel, context, depth); // template context.Push(current); } else { semanticModel.Tokens.Add(classification, stream.Position, identifier.Name.Length + 1, identifier.QuickInfo); stream.Advance(identifier.Name.Length); if (identifier.IsCollection) { context.Push(_contexts.Find(identifier.Context)); ParseFilter(stream, semanticModel, depth); ParseBlock(stream, semanticModel, context, depth); // template context.Pop(); ParseBlock(stream, semanticModel, context, depth); // separator } else if (identifier.IsBoolean) { ParseBlock(stream, semanticModel, context, depth); // true ParseBlock(stream, semanticModel, context, depth); // false } else if (identifier.HasContext) { context.Push(_contexts.Find(identifier.Context)); //ParseDot(stream, semanticModel, context, depth); // identifier ParseBlock(stream, semanticModel, context, depth); // template context.Pop(); } } return(true); } } return(false); }