private void TerminateSymbol(Stream stream) { if (stream.Current == ' ' || stream.Current == '{' || stream.Current == ';' || stream.Current == '(' || stream.Current == ')' || stream.Current == ',') { _isSymbol = false; } // Find object literals if (stream.Current == '{') { var i = 0; while (true) { if (stream.Peek(--i) != ' ') { break; } } var peek = stream.Peek(i); if (peek == '=' || peek == '(' || peek == ',') { var block = stream.PeekBlock(1, '{', '}'); _objectLiteralEnds = Math.Max(_objectLiteralEnds, stream.Position + block.Length); } } }
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 bool ParseKeywords(Stream stream, SemanticModel semanticModel) { var peek = stream.Peek(-1); if (char.IsLetterOrDigit(peek) == false && peek != '.') { var name = stream.PeekWord(); if (name != null && Keywords.Contains(name)) { semanticModel.Tokens.Add(Classifications.Keyword, stream.Position, name.Length); stream.Advance(name.Length - 1); if (SymbolKeywords.Contains(name)) { while (stream.Peek() == ' ') { stream.Advance(); } _isSymbol = true; } return(true); } } return(false); }
private void ParseFilter(Stream stream, SemanticModel semanticModel, int depth) { if (stream.Peek() == '(') { stream.Advance(); var classification = GetPropertyClassification(depth); semanticModel.Tokens.AddBrace(stream, classification); var block = stream.PeekBlock(1, '(', ')'); if (block.Contains("=>") == false) { semanticModel.Tokens.Add(Classifications.String, stream.Position + 1, block.Length); } stream.Advance(block.Length); if (stream.Peek() == ')') { stream.Advance(); semanticModel.Tokens.AddBrace(stream, classification); } } }
private void ParseReference(Stream stream) { 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, this.templateProjectItem);*/ _semanticModel.ShadowClass.AddReference(reference); } catch { //Log.Debug("Reference Error: " + ex.Message); } stream.Advance(len - 1); } } }
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 void ParseCode(Stream stream) { var code = new StringBuilder(); var position = stream.Position; var isString = false; var open = char.MinValue; do { if (stream.Current != char.MinValue) { code.Append(stream.Current); } if (isString && stream.Current == open && stream.Peek(-1) != '\\') { isString = false; } else if (stream.Current == '"' || stream.Current == '\'') { open = stream.Current; isString = true; } if (isString == false) { _semanticModel.Tokens.AddBrace(stream); } }while (stream.Advance()); _semanticModel.ShadowClass.AddBlock(code.ToString(), position); }
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 bool ParseNumber(Stream stream, SemanticModel semanticModel) { if (char.IsDigit(stream.Current) || (stream.Current == '.' && char.IsDigit(stream.Peek()))) { var start = stream.Position; do { if (char.IsDigit(stream.Peek()) == false && (stream.Peek() == '.' && char.IsDigit(stream.Peek(2))) == false) { break; } }while (stream.Advance()); semanticModel.Tokens.Add(Classifications.Number, start, stream.Position + 1 - start); return(true); } return(false); }
//private void ParseDot(Stream stream, SemanticModel semanticModel, Stack<Context> context, int depth) //{ // if (stream.Peek() == '.') // { // stream.Advance(); // var identifier = GetIdentifier(stream, semanticModel, context); // if (identifier != null) // { // var classification = GetPropertyClassification(depth); // var parent = context.Skip(1).FirstOrDefault(); // semanticModel.Tokens.Add(classification, stream.Position); // semanticModel.ContextSpans.Add(context.Peek(), parent, ContextType.Template, stream.Position, stream.Position + 1); // if (identifier.IsParent) // { // semanticModel.Tokens.Add(classification, stream.Position + 1, identifier.Name.Length, identifier.QuickInfo.Replace("$parent", parent?.Name.ToLowerInvariant())); // 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 + 1, identifier.Name.Length, identifier.QuickInfo); // stream.Advance(identifier.Name.Length); // if (identifier.IsCollection) // { // context.Push(_contexts.Find(identifier.Context)); // ParseFilter(stream, semanticModel, context, 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(); // } // } // } // } //} private void ParseBlock(Stream stream, SemanticModel semanticModel, Stack <Context> context, int depth) { if (stream.Peek() == '[') { stream.Advance(); var classification = GetPropertyClassification(depth); semanticModel.Tokens.AddBrace(stream, classification); var block = stream.PeekBlock(1, '[', ']'); Parse(block, semanticModel, context, stream.Position + 1, depth + 1); stream.Advance(block.Length); if (stream.Peek() == ']') { stream.Advance(); semanticModel.Tokens.AddBrace(stream, classification); } } }
private void ParseBlock(Stream stream) { if (stream.Peek() == '[') { stream.Advance(); var block = stream.PeekBlock(1, '[', ']'); Parse(block, stream.Position + 1); stream.Advance(block.Length); } }
private bool ParseReference(Stream stream, SemanticModel semanticModel) { const string keyword = "reference"; if (stream.Current == '#' && stream.Peek() == keyword[0] && stream.PeekWord(1) == keyword) { semanticModel.Tokens.Add(Classifications.Directive, stream.Position, keyword.Length + 1); stream.Advance(keyword.Length); return(true); } return(false); }
private bool ParseCodeBlock(Stream stream, SemanticModel semanticModel, Stack <Context> context) { if (stream.Current == '$' && stream.Peek() == '{' && context.Peek() == _fileContext) { 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; } } semanticModel.Tokens.Add(Classifications.Property, stream.Position); stream.Advance(); semanticModel.Tokens.AddBrace(stream, Classifications.Property); var block = stream.PeekBlock(1, '{', '}'); stream.Advance(block.Length); if (stream.Peek() == '}') { stream.Advance(); semanticModel.Tokens.AddBrace(stream, Classifications.Property); } return(true); } return(false); }
private void ParseFilter(Stream stream) { if (stream.Peek() == '(') { stream.Advance(); var block = stream.PeekBlock(1, '(', ')'); var index = block.IndexOf("=>", StringComparison.Ordinal); if (index > 0) { var name = block.Substring(0, index); _semanticModel.ContextSpans.Add(null, null, ContextType.Lambda, stream.Position + 1, stream.Position + block.Length + 1); _semanticModel.ShadowClass.AddLambda(block, _context.Peek().Name, name, stream.Position + 1); } stream.Advance(block.Length); if (stream.Peek() == ')') { stream.Advance(); } } }
private bool ParseString(Stream stream, SemanticModel semanticModel, Stack <Context> context, int depth) { if (stream.Current == '\'' || stream.Current == '"' || stream.Current == '`') { var start = stream.Position; var open = stream.Current; while (stream.Advance()) { var length = stream.Position - start; if (ParseDollar(stream, semanticModel, context, depth)) { semanticModel.Tokens.Add(Classifications.String, start, length); if (stream.Advance() == false || stream.Current == Constants.NewLine) { return(true); } start = stream.Position; } if (stream.Current == open) { if (stream.Peek(-1) != '\\' || stream.Peek(-2) == '\\') { semanticModel.Tokens.Add(Classifications.String, start, stream.Position + 1 - start); return(true); } } } semanticModel.Tokens.Add(Classifications.String, start, stream.Position - start); return(true); } return(false); }
private bool ParseOperators(Stream stream, SemanticModel semanticModel) { if (Operators.Contains(stream.Current)) { semanticModel.Tokens.Add(Classifications.Operator, stream.Position); if (stream.Current == ':') { while (stream.Peek() == ' ') { stream.Advance(); } _isSymbol = true; } return(true); } return(false); }
private Identifier GetIdentifier(Stream stream) { var word = stream.PeekWord(1); if (word == null) { return(null); } var c = _context.Peek(); var identifier = _semanticModel.GetIdentifier(c, word); if (identifier == null) { return(null); } if (identifier.IsBoolean == false && identifier.IsCollection == false) { return(identifier); } var next = stream.Peek(identifier.Name.Length + 1); if (identifier.IsBoolean && next == '[') { return(identifier); } if (identifier.IsCollection && (identifier.RequireTemplate == false || next == '[' || (identifier.IsCustom == false && next == '('))) { return(identifier); } return(null); }
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 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; } }