コード例 #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);
                }
            }
        }
コード例 #2
0
        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 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);
        }
コード例 #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);
                }
            }
        }
コード例 #5
0
        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);
                }
            }
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
        }
コード例 #8
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
                        {
                            //ignored
                        }
                    }
                }
            }

            return(false);
        }
コード例 #9
0
        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);
        }
コード例 #10
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);
                }
            }
        }
コード例 #11
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);
            }
        }
コード例 #12
0
        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);
        }
コード例 #13
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);
        }
コード例 #14
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();
                }
            }
        }
コード例 #15
0
        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);
        }
コード例 #16
0
        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);
        }
コード例 #17
0
        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);
        }
コード例 #18
0
        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);
        }
コード例 #19
0
        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;
            }
        }