예제 #1
0
        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);
        }
예제 #3
0
        private void ParseCodeBlock(Stream stream)
        {
            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;
                    }
                    if (current == '\n' || current == char.MinValue)
                    {
                        break;
                    }
                }

                stream.Advance();

                var block = stream.PeekBlock(1, '{', '}');

                _semanticModel.ContextSpans.Add(null, null, ContextType.CodeBlock, stream.Position + 1, stream.Position + block.Length + 1);

                var codeStream = new Stream(block, stream.Position + 1);

                ParseUsings(codeStream);
                ParseCode(codeStream);

                stream.Advance(block.Length);
            }
        }
예제 #4
0
        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 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);
        }
예제 #6
0
        private void ParseBlock(Stream stream)
        {
            if (stream.Peek() == '[')
            {
                stream.Advance();

                var block = stream.PeekBlock(1, '[', ']');
                Parse(block, stream.Position + 1);
                stream.Advance(block.Length);
            }
        }
예제 #7
0
        //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);
                }
            }
        }
예제 #8
0
        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();
                }
            }
        }
예제 #9
0
        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);
        }