Beispiel #1
0
        public override ExpressionNode Resolve(ScopeNode scope)
        {
            var a = A.Resolve(scope) as ValueNode;
            var b = B.Resolve(scope) as ValueNode;

            if (a == null || b == null)
                throw new InvalidOperationException("Can only combine values");

            switch (CombineOperator)
            {
                case '*':
                    return a*b;
                case '+':
                    return a + b;
                case '-':
                    return a - b;
                case '/':
                    return a/b;
                case '=':
                    return ValueNode.ValueEquals(a, b);
                case '<':
                    return a < b;
                case '>':
                    return a > b;
            }

            throw new Exception($"Invalid operator: {CombineOperator}");
        }
Beispiel #2
0
        public override ExpressionNode Resolve(ScopeNode scope)
        {
            var args = ValueList.From(_args.Resolve(scope));

            switch (Name)
            {
                case "nth":
                {
                    var vs = ValueList.From(args[0]);

                    var index = (int) args[1];

                    return vs[index - 1];
                }
                case "map-get":
                {
                    var vs = ValueList.From(args[0]);

                    var key = (string) args[1];

                    return vs[key];
                }
            }

            var function = scope.GetFunction(Name);

            var result = function.Execute(args);

            return result;
        }
Beispiel #3
0
        public ScopeNode GetActiveScope(ScopeNode currentScope)
        {
            if (Test(currentScope))
                return this;

            foreach (var elseNode in Elses)
            {
                if (elseNode.Test(currentScope))
                    return elseNode;
            }

            return null;
        }
Beispiel #4
0
        private void ReadFor(ScopeNode currentScope)
        {
            Expect('$');
            var varName = ReadName();

            Expect("from");
            SkipWhitespace();
            var from = ReadValueList('t');
            Expect("through");
            SkipWhitespace();
            var through = ReadValueList('{');
            Expect('{');

            var node = new ForNode(new VariableNode(varName), new Expression(from), new Expression(through));
            currentScope.Add(node);

            ReadScopeContent(node);
        }
Beispiel #5
0
 private void ReadReturn(ScopeNode currentScope)
 {
     ExpressionNode value = ReadValueList(';');
     Expect(';');
     var result = new ReturnNode(new Expression(value));
     currentScope.Add(result);
 }
Beispiel #6
0
        private void ReadScopeContent(ScopeNode currentScope)
        {
            var buffer = new StringBuilder();
            var interpolations = new List<ValueList>();

            //States
            var inCommentStart = false;
            var paranthesesLevel = 0;
            var inDoubleQuotes = false;

            while (!EndOfStream)
            {
                var c = (char) Read();

                if (inDoubleQuotes)
                {
                    buffer.Append(c);

                    if (c == '"')
                    {
                        inDoubleQuotes = false;
                    }
                }
                else
                {
                    switch (c)
                    {
                        case ' ':
                            //Ignore starting white space
                            if (buffer.Length == 0)
                                break;
                            goto default;
                        case '@':
                            if (buffer.Length != 0)
                                throw new Exception("Must be first character");

                            ReadAt(currentScope);

                            break;
                        case '$':
                            var name = ReadUntil(':');
                            var vn = new VariableNode(name);
                            vn.Expression = new Expression(ReadValueList(';'));
                            Expect(';');
                            currentScope.Add(vn);
                            break;
                        case '/':
                            if (inCommentStart)
                            {
                                ReadInlineComment();

                                inCommentStart = false;

                                //Remove the first slash from the buffer
                                buffer.Length--;
                            }
                            else
                            {
                                buffer.Append(c);
                                inCommentStart = true;
                            }
                            break;
                        case '*':
                            if (inCommentStart)
                            {
                                var node = ReadComment();
                                currentScope.Add(node);
                                inCommentStart = false;

                                //Remove the first slash from the buffer
                                buffer.Length--;
                                break;
                            }
                            goto default;
                        case ';':
                        {
                            throw new ScssReaderException("Unexpected ;", File.Path, _lineNumber);
                        }
                        case ':':
                            var pc = (char) Peek();
                            if (char.IsLetter(pc)) //hover etc.
                            {
                                buffer.Append(c);
                            }
                            else if (pc == ':')
                            {
                                buffer.Append(c);
                                buffer.Append(pc);
                                Read();
                            }
                            else
                            {
                                var pn = new PropertyNode();
                                pn.Name = new ScssString(buffer.ToString().Trim(), interpolations);
                                pn.Expression = new Expression(ReadValueList(';', '{'));
                                buffer.Clear();

                                var pc2 = (char) Read();
                                if (pc2 == ';')
                                {
                                    currentScope.Add(pn);
                                }
                                else if (pc2 == '{')
                                {
                                    var result = new NamespaceNode(pn);
                                    ReadScopeContent(result);
                                    currentScope.Add(result);
                                }
                                else
                                {
                                    throw new ScssReaderException("Expected { or ;", File.Path, _lineNumber);
                                }
                            }
                            break;
                        case '"':
                            inDoubleQuotes = true;
                            goto default;
                        case '(':
                            paranthesesLevel++;
                            goto default;
                        case ')':
                            paranthesesLevel--;
                            goto default;
                        case '{':
                        {
                            var node = new SelectorNode();
                            node.Selector = new ScssString(buffer.ToString().Trim(), interpolations);
                            ReadScopeContent(node);
                            currentScope.Add(node);
                            buffer.Clear();
                        }
                            break;
                        case '}':
                            return;
                        case '#':
                            if (Peek() == '{')
                            {
                                inCommentStart = false;
                                var value = ReadInterpolation();
                                buffer.Append("{" + interpolations.Count + "}");
                                interpolations.Add(value);
                                break;
                            }
                            else
                            {
                                goto default;
                            }
                        case '\n':
                            inCommentStart = false;
                            break;
                        default:
                            inCommentStart = false;
                            buffer.Append(c);
                            break;
                    }
                }
            }
        }
Beispiel #7
0
        private void ReadMedia(ScopeNode currentScope)
        {
            var def = ReadUntil('{');

            MediaNode node = new MediaNode()
            {
                Definition = def.TrimEnd()
            };

            ReadScopeContent(node);
            currentScope.Add(node);
        }
Beispiel #8
0
        private void ReadMixin(ScopeNode currentScope)
        {
            var name = ReadName();

            VariableNode[] args = new VariableNode[0];

            SkipWhitespace();

            if (Peek() == '(')
                args = ReadArgumentDefinition().ToArray();

            var node = new MixinNode(name, args);
            Expect('{');
            ReadScopeContent(node);
            currentScope.Add(node);
        }
Beispiel #9
0
 public string Resolve(ScopeNode scope)
 {
     object[] args = _interpolations.Select(x => x.Resolve(scope)).ToArray();
     return string.Format(_value, args);
 }
Beispiel #10
0
        private void ReadInclude(ScopeNode currentScope)
        {
            var name = ReadName();
            ValueList args = new ValueList();

            SkipWhitespace();

            if (Peek() == '(')
                args = ReadArgumentCall();

            SkipWhitespace();

            var result = new IncludeNode(name, args);
            currentScope.Add(result);

            if (Peek() == '{')
            {
                Expect('{');
                ReadScopeContent(result);
            }
            else
                Optional(';');
        }
Beispiel #11
0
        private void ProcessImport(string path, ScssPackage fromPackage, ScopeNode scope, CssRoot root,
            CssSelector selector, int level, string nspace = "")
        {
            var file = fromPackage.File.SolveReference(path);
            var tree = TreeFromFile(file);

            ProcessScope(tree, tree, root, selector, level, nspace);
        }
Beispiel #12
0
 public ExpressionNode Resolve(ScopeNode scope)
 {
     return Root.Resolve(scope);
 }
Beispiel #13
0
 private void ReadExtend(ScopeNode currentScope)
 {
     string selector = ReadUntil(';');
     currentScope.Add(new ExtendNode(selector));
 }
Beispiel #14
0
 public abstract ExpressionNode Resolve(ScopeNode scope);
Beispiel #15
0
        private void ReadElse(ScopeNode currentScope)
        {
            ElseNode elseNode;

            if (Peek() == 'i') //Assume if
            {
                Read();
                Expect('f');
                SkipWhitespace();

                var val = ReadValueList('{');
                Expect('{');

                elseNode = new ElseNode(val);
            }
            else
            {
                elseNode = new ElseNode();
            }

            var parentIf = currentScope.Nodes.Last() as IfNode;

            if (parentIf == null)
                throw new Exception("Else without if");

            parentIf.Elses.Add(elseNode);

            ReadScopeContent(elseNode);
        }
Beispiel #16
0
        private void ReadEach(ScopeNode currentScope)
        {
            var varNames = ReadValueList('i');

            Expect("in");
            var val = ReadValueList('{');
            Expect('{');

            var node = new EachNode(varNames, val);
            currentScope.Add(node);

            ReadScopeContent(node);
        }
Beispiel #17
0
 private void ReadContent(ScopeNode currentScope)
 {
     currentScope.Add(new ContentNode());
     Optional(';');
 }
Beispiel #18
0
        private void ReadAt(ScopeNode currentScope)
        {
            string type = ReadName();

            SkipWhitespace();

            switch (type)
            {
                case "media":
                    ReadMedia(currentScope);
                    break;
                case "mixin":
                    ReadMixin(currentScope);
                    break;
                case "content":
                    ReadContent(currentScope);
                    break;
                case "include":
                    ReadInclude(currentScope);
                    break;
                case "import":
                    ReadImport(currentScope);
                    break;
                case "function":
                    ReadFunction(currentScope);
                    break;
                case "return":
                    ReadReturn(currentScope);
                    break;
                case "if":
                    ReadIf(currentScope);
                    break;
                case "else":
                    ReadElse(currentScope);
                    break;
                case "each":
                    ReadEach(currentScope);
                    break;
                case "for":
                    ReadFor(currentScope);
                    break;
                case "extend":
                    ReadExtend(currentScope);
                    break;
                default:
                    throw new ScssReaderException($"Could not recognize @{type}", File.Path, _lineNumber);
            }
        }
Beispiel #19
0
 public override ExpressionNode Resolve(ScopeNode scope)
 {
     return scope.GetVariable(VariableName).Expression.Resolve(scope);
 }
Beispiel #20
0
        private void ProcessScope(ScssPackage package, ScopeNode scope, CssRoot root, CssSelector selector, int level,
            string nspace = "")
        {
            if (scope is SelectorNode)
            {
                var snode = (SelectorNode) scope;
                var s = snode.Selector.Resolve(scope);
                if (selector != null)
                {
                    s = ExpandSelector(selector.Selector, s);
                }

                selector = new CssSelector(s, level);
                root.Add(selector);
            }

            foreach (var node in scope.Nodes)
            {
                var useNode = node;

                if (node is PropertyNode)
                {
                    var n = (PropertyNode) node;

                    var value = n.Expression.Resolve(scope).Value;

                    selector.Add(new CssProperty(nspace + n.Name.Resolve(scope), value, level + 1));
                }
                else if (node is MediaNode)
                {
                    var n = (MediaNode) node;
                    var s = new CssMedia(level + 1)
                    {
                        Definition = n.Definition
                    };

                    root.Add(s);

                    int nextLevel = level + 1;

                    if (selector != null)
                    {
                        selector = new CssSelector(selector.Selector, level + 2);
                        s.Add(selector);

                        nextLevel++;
                    }

                    ProcessScope(package, (ScopeNode) n, s, selector, nextLevel, nspace);
                }
                else if (node is CommentNode)
                {
                    var n = (CommentNode) node;
                    CssNode p = root;

                    if (selector != null)
                        p = selector;

                    p.Add(new CssComment(n.Comment, level + 1));
                }
                else if (node is ImportNode)
                {
                    var n = (ImportNode) node;

                    if (n.Path.Contains(".css")
                        || n.Path.Contains("http://")
                        || n.Path.Contains("url(")
                        || n.Path.Contains(" "))
                    {
                        root.Add(new CssImport(n.Path, level + 1));
                    }
                    else
                    {
                        var path = n.Path.Trim('\"');
                        ProcessImport(path, package, scope, root, selector, level, nspace);
                    }
                }
                else if (node is VariableNode)
                {
                    var n = (VariableNode) node;

                    scope.SetVariable(n);
                }
                else if (node is MixinNode)
                {
                    var n = (MixinNode) node;

                    scope.SetMixin(n);
                }
                else if (node is ContentNode)
                {
                    var sn = scope.GetContent();
                    ProcessScope(package, sn, root, selector, level - 1, nspace);
                }
                else if (node is IfNode)
                {
                    var n = (IfNode) node;
                    var sn = n.GetActiveScope(scope);

                    if (sn != null)
                        ProcessScope(package, sn, root, selector, level, nspace);
                }
                else if (node is EachNode)
                {
                    var n = (EachNode) node;
                    var var = n.Variables;

                    foreach (var value in n.List)
                    {
                        if (var.Count == 1)
                        {
                            var[0].Expression = new Expression(value);
                            n.SetVariable(var[0]);
                        }
                        else
                        {
                            if (!(value is ValueList))
                                throw new Exception("This must be a list");

                            var subList = (ValueList) value;

                            // There is a bug in the reader causing unecessary levels of value lists
                            // TODO UNDONE
                            if (subList.Count == 1)
                                subList = (ValueList) subList[0];

                            for (int i = 0; i < var.Count; i++)
                            {
                                var[i].Expression = new Expression(subList[i]);
                                n.SetVariable(var[i]);
                            }
                        }

                        ProcessScope(package, n, root, selector, level, nspace);
                    }
                }
                else if (node is ForNode)
                {
                    var n = (ForNode) node;
                    var var = n.Variable;
                    int from = int.Parse(n.From.Resolve(scope).Value);

                    int to = 0;
                    string toStr = n.Through.Resolve(scope).Value;

                    if (!int.TryParse(toStr, out to))
                        throw new Exception("Failed to parse to value");

                    for (int i = from; i <= to; i++)
                    {
                        var value = new ValueNode(i.ToString());

                        var.Expression = new Expression(value);
                        n.SetVariable(var);
                        ProcessScope(package, n, root, selector, level, nspace);
                    }
                }
                else if (node is ExtendNode)
                {
                    var n = (ExtendNode) node;

                    package.AddExtension(new ScssExtension()
                    {
                        Selector = selector.Selector,
                        Super = ((ExtendNode) node).Selector
                    });
                }
                else if (node is FunctionNode)
                {
                    var n = (FunctionNode) node;

                    scope.SetFunction(n);
                }
                else if (node is NamespaceNode)
                {
                    var subLevel = level;

                    var n = (NamespaceNode) node;
                    string header = n.Header.Name.Resolve(scope);
                    if (!n.Header.Expression.Empty)
                    {
                        var value = n.Header.Expression.Resolve(scope).Value;
                        selector.Add(new CssProperty(header, value, level + 1));

                        subLevel++;
                    }

                    ProcessScope(package, (ScopeNode) node, root, selector, subLevel, header + "-");
                }
                else if (node is IncludeNode)
                {
                    var n = (IncludeNode) node;

                    var mn = scope.GetMixin(n.MixinName);

                    mn.Initialize(n);

                    ProcessScope(package, mn, root, selector, level);
                }
                else if (useNode is SelectorNode)
                {
                    ProcessScope(package, (ScopeNode) node, root, selector, level + 1);
                }
            }
        }
Beispiel #21
0
        private void ReadFunction(ScopeNode currentScope)
        {
            var name = ReadName();

            var args = ReadArgumentDefinition();

            var node = new FunctionNode(name, args.ToArray());
            Expect('{');
            ReadScopeContent(node);
            currentScope.Add(node);
        }
Beispiel #22
0
        private void ReadIf(ScopeNode currentScope)
        {
            var val = ReadValueList('{');
            Expect('{');

            var ifNode = new IfNode(val);
            currentScope.Add(ifNode);

            ReadScopeContent(ifNode);
        }
Beispiel #23
0
        private void ReadImport(ScopeNode currentScope)
        {
            var path = ReadUntil(';');

            currentScope.Add(new ImportNode(path));
        }
Beispiel #24
0
        public bool Test(ScopeNode currentScope)
        {
            var result = _condition.Resolve(currentScope);

            return result.Value == "1";
        }
Beispiel #25
0
 public virtual void SetContent(ScopeNode content)
 {
     _content = content;
 }