コード例 #1
0
ファイル: ItemFactory.cs プロジェクト: obedurena/SassyStudio
        private ParseItem CreateBang(ComplexItem parent, ITextProvider text, ITokenStream stream)
        {
            var modifier = stream.Peek(1);

            if (BangModifier.IsValidModifier(text, modifier, "default"))
            {
                return(new DefaultModifier());
            }

            if (BangModifier.IsValidModifier(text, modifier, "important"))
            {
                return(new ImportanceModifier());
            }

            if (BangModifier.IsValidModifier(text, modifier, "optional"))
            {
                return(new OptionalModifier());
            }

            if (VariableName.IsVariable(text, stream))
            {
                return(CreateVariableDefinitionOrReference(parent, text, stream));
            }

            return(new TokenItem());
        }
コード例 #2
0
        protected virtual bool ParseCombinator(IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            SelectorCombinator combinator = null;
            switch (stream.Current.Type)
            {
                case TokenType.GreaterThan:
                    combinator = new ChildCombinator();
                    break;
                case TokenType.Plus:
                    combinator = new AdjacentSiblingCombinator();
                    break;
                case TokenType.Tilde:
                    combinator = new GeneralSiblingCombinator();
                    break;
            }

            if (combinator != null)
            {
                if (combinator.Parse(itemFactory, text, stream))
                {
                    Children.Add(combinator);
                    Combinator = combinator;
                }
            }
            else if (stream.Current.Type != TokenType.OpenCurlyBrace)
            {
                // whitespace only combinator means no adding to children or parsing
                // we just want to know that there was a combinator
                if (stream.Current.Start >= (stream.Peek(-1).End + 1))
                    Combinator = new DescendantCombinator();
            }

            return Combinator != null;
        }
コード例 #3
0
        static ParseItem CreateSimpleSelector(ComplexItem parent, IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            switch (stream.Current.Type)
            {
            case TokenType.Ampersand: return(new ParentReferenceSelector());

            case TokenType.Asterisk: return(new UniversalSelector());

            case TokenType.Period: return(new ClassSelector());

            case TokenType.Hash: return(new IdSelector());

            case TokenType.Identifier: return(new TypeSelector());

            case TokenType.OpenBrace: return(new AttributeSelector());

            case TokenType.DoubleColon: return(new PseudoElementSelector());

            case TokenType.PercentSign: return(new ExtendOnlySelector());
            }

            if (stream.Current.Type == TokenType.Colon)
            {
                var next = stream.Peek(1);
                switch (next.Type)
                {
                case TokenType.Identifier: return(new PseudoClassSelector());

                case TokenType.Function: return(new PseudoFunctionSelector());
                }
            }

            return(null);
        }
コード例 #4
0
ファイル: Parser.cs プロジェクト: edongashi/gamepad-mapper
        private static CommandBinding ParseCommandBinding(ITokenStream stream, ILogger logger)
        {
            var tokens = stream.Peek();

            if (tokens == null)
            {
                return(null);
            }

            if (tokens.Length > 3 && tokens[2].Value == "=")
            {
                var command = tokens[1].Value;
                var action  = ParseAction(tokens, 3, out var end);
                if (action != null)
                {
                    if (end != tokens.Length)
                    {
                        logger?.WriteLine(
                            $"Warning: Ignored unknown symbols at {stream.Path}:{stream.Line}.");
                    }

                    return(new CommandBinding(command, action));
                }

                action = new NoOpAction();
                logger?.WriteLine($"Error: Could not parse action at {stream.Path}:{stream.Line}.");

                return(new CommandBinding(command, action));
            }

            logger?.WriteLine($"Error: Malformed binding at {stream.Path}:{stream.Line}.");
            return(null);
        }
コード例 #5
0
ファイル: TokenStream.cs プロジェクト: edongashi/tss
        public static Token PeekOnly(this ITokenStream stream, Func <Token, bool> predicate, int index)
        {
            if (index < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(index));
            }

            var i = 0;

            while (true)
            {
                var current = stream.Peek(i++);
                if (current == null)
                {
                    return(null);
                }

                if (predicate(current))
                {
                    index--;
                    if (index < 0)
                    {
                        return(current);
                    }
                }
            }
        }
コード例 #6
0
ファイル: Parser.cs プロジェクト: edongashi/tss
        public static AndSelector ParseAndSelector(ITokenStream tokens)
        {
            var selectors = new List <ElementSelector>
            {
                ParseNotSelector(tokens)
            };

            while (true)
            {
                var zero = tokens.Peek();
                switch (zero)
                {
                case CaretToken _:
                    tokens.Consume();
                    selectors.Add(ParseNotSelector(tokens));
                    break;

                case NotToken _:
                case AsteriskToken _:
                case AmpersandToken _:
                case StringToken _:
                case IdentifierToken _:
                case ScriptToken _:
                    selectors.Add(ParseNotSelector(tokens));
                    break;

                default:
                    return(new AndSelector(selectors));
                }
            }
        }
コード例 #7
0
ファイル: ClassName.cs プロジェクト: profet23/SassyStudio
        public static bool IsValidName(ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.Period)
                return stream.Peek(1).Type == TokenType.Identifier;

            return false;
        }
コード例 #8
0
ファイル: ItemFactory.cs プロジェクト: obedurena/SassyStudio
        private ParseItem CreateVariableDefinitionOrReference(ComplexItem parent, ITextProvider text, ITokenStream stream)
        {
            var name = stream.Peek(1);

            if (name.Type == TokenType.Identifier && stream.Current.End == name.Start)
            {
                var assignment = stream.Peek(2);
                if (assignment.Type == TokenType.Colon || assignment.Type == TokenType.Equal)
                {
                    return(new VariableDefinition());
                }

                return(new VariableReference());
            }

            return(new TokenItem());
        }
コード例 #9
0
        static ParseItem CreateFunctionArgument(ComplexItem parent, IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            if (parent is MixinReference || parent is SystemFunctionReference || parent is UserFunctionReference)
                if (VariableName.IsVariable(text, stream) && stream.Peek(2).Type == TokenType.Colon)
                    return new NamedFunctionArgument();

            return null;
        }
コード例 #10
0
        public static bool IsValidName(ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.Period)
            {
                return(stream.Peek(1).Type == TokenType.Identifier);
            }

            return(false);
        }
コード例 #11
0
ファイル: ItemFactory.cs プロジェクト: obedurena/SassyStudio
        private ParseItem CreatePeriod(ComplexItem parent, ITextProvider text, ITokenStream stream)
        {
            if (stream.Peek(1).Type == TokenType.Identifier)
            {
                return(new ClassName());
            }

            return(new TokenItem());
        }
コード例 #12
0
ファイル: BangModifier.cs プロジェクト: profet23/SassyStudio
        public override bool Parse(IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.Bang && IsValidModifier(text, stream.Peek(1), FlagName))
            {
                Bang = Children.AddCurrentAndAdvance(stream);
                Flag = Children.AddCurrentAndAdvance(stream);
            }

            return Children.Count > 0;
        }
コード例 #13
0
        public override bool Parse(IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.At && IsValidTokenType(stream.Peek(1).Type))
            {
                At   = Children.AddCurrentAndAdvance(stream);
                Name = Children.AddCurrentAndAdvance(stream);
            }

            return(Children.Count > 0);
        }
コード例 #14
0
ファイル: AtRule.cs プロジェクト: profet23/SassyStudio
        public override bool Parse(IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.At && IsValidTokenType(stream.Peek(1).Type))
            {
                At = Children.AddCurrentAndAdvance(stream);
                Name = Children.AddCurrentAndAdvance(stream);
            }

            return Children.Count > 0;
        }
コード例 #15
0
        protected override bool ParseSelectorToken(IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.DoubleColon && stream.Peek(1).Type == TokenType.Identifier)
            {
                Prefix = Children.AddCurrentAndAdvance(stream, SassClassifierType.PseudoElement);
                Name = Children.AddCurrentAndAdvance(stream, SassClassifierType.PseudoElement);
            }

            return Children.Count > 0;
        }
コード例 #16
0
        public override bool Parse(IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.PercentSign && stream.Peek(1).Type == TokenType.Identifier)
            {
                Prefix = Children.AddCurrentAndAdvance(stream);
                Name   = Children.AddCurrentAndAdvance(stream);
            }

            return(Children.Count > 0);
        }
コード例 #17
0
        public override bool Parse(IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.PercentSign && stream.Peek(1).Type == TokenType.Identifier)
            {
                Prefix = Children.AddCurrentAndAdvance(stream);
                Name = Children.AddCurrentAndAdvance(stream);
            }

            return Children.Count > 0;
        }
コード例 #18
0
        protected override bool ParseSelectorToken(IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.Colon && stream.Peek(1).Type == TokenType.Identifier)
            {
                Prefix    = Children.AddCurrentAndAdvance(stream, SassClassifierType.PseudoClass);
                ClassName = Children.AddCurrentAndAdvance(stream, SassClassifierType.PseudoClass);
            }

            return(Children.Count > 0);
        }
コード例 #19
0
ファイル: BangModifier.cs プロジェクト: obedurena/SassyStudio
        public override bool Parse(IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.Bang && IsValidModifier(text, stream.Peek(1), FlagName))
            {
                Bang = Children.AddCurrentAndAdvance(stream);
                Flag = Children.AddCurrentAndAdvance(stream);
            }

            return(Children.Count > 0);
        }
コード例 #20
0
ファイル: AtRule.cs プロジェクト: profet23/SassyStudio
        public static bool IsRule(ITextProvider text, ITokenStream stream, string name)
        {
            if (stream.Current.Type == TokenType.At)
            {
                var nameToken = stream.Peek(1);
                if (nameToken.Type == TokenType.Identifier)
                    return text.GetText(nameToken.Start, name.Length) == name;
            }

            return false;
        }
コード例 #21
0
ファイル: ItemFactory.cs プロジェクト: obedurena/SassyStudio
        private ParseItem CreateHash(ComplexItem parent, ITextProvider text, ITokenStream stream)
        {
            var value = stream.Peek(1);

            if (value.Type == TokenType.Identifier && (value.Length == 3 || value.Length == 6) && IsHex(text, value))
            {
                return(new HexColorValue());
            }

            return(new TokenItem());
        }
コード例 #22
0
        public static bool IsConditionalContinuationDirective(ITextProvider text, ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.At)
            {
                var name = stream.Peek(1);
                if (name.Type == TokenType.Identifier)
                    return text.StartsWithOrdinal(name.Start, "else");
            }

            return false;
        }
コード例 #23
0
        public static bool IsConditionalDirective(ITextProvider text, ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.At)
            {
                var name = stream.Peek(1);
                if (name.Type == TokenType.Identifier || name.Type == TokenType.Function)
                    return text.CompareOrdinal(name.Start, "if");
            }

            return false;
        }
コード例 #24
0
ファイル: PageDirective.cs プロジェクト: profet23/SassyStudio
 protected override void ParseDirective(IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
 {
     if (stream.Current.Type == TokenType.Semicolon && stream.Peek(1).Type == TokenType.Identifier)
     {
         var selector = itemFactory.CreateSpecific<PseudoClassSelector>(this, text, stream);
         if (selector.Parse(itemFactory, text, stream))
         {
             Selector = selector;
             Children.Add(selector);
         }
     }
 }
コード例 #25
0
 protected override void ParseDirective(IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
 {
     if (stream.Current.Type == TokenType.Semicolon && stream.Peek(1).Type == TokenType.Identifier)
     {
         var selector = itemFactory.CreateSpecific <PseudoClassSelector>(this, text, stream);
         if (selector.Parse(itemFactory, text, stream))
         {
             Selector = selector;
             Children.Add(selector);
         }
     }
 }
コード例 #26
0
        static ParseItem CreateFunctionArgument(ComplexItem parent, IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            if (parent is MixinReference || parent is SystemFunctionReference || parent is UserFunctionReference)
            {
                if (VariableName.IsVariable(text, stream) && stream.Peek(2).Type == TokenType.Colon)
                {
                    return(new NamedFunctionArgument());
                }
            }

            return(null);
        }
コード例 #27
0
        public static bool IsConditionalDirective(ITextProvider text, ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.At)
            {
                var name = stream.Peek(1);
                if (name.Type == TokenType.Identifier || name.Type == TokenType.Function)
                {
                    return(text.CompareOrdinal(name.Start, "if"));
                }
            }

            return(false);
        }
コード例 #28
0
        public static bool IsConditionalContinuationDirective(ITextProvider text, ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.At)
            {
                var name = stream.Peek(1);
                if (name.Type == TokenType.Identifier)
                {
                    return(text.StartsWithOrdinal(name.Start, "else"));
                }
            }

            return(false);
        }
コード例 #29
0
        public static bool IsVariable(ITextProvider text, ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.Dollar || stream.Current.Type == TokenType.Bang)
            {
                var name = stream.Peek(1);
                if (name.Type == TokenType.Identifier)
                {
                    return(true);
                }
            }

            return(false);
        }
コード例 #30
0
        public static bool IsRule(ITextProvider text, ITokenStream stream, string name)
        {
            if (stream.Current.Type == TokenType.At)
            {
                var nameToken = stream.Peek(1);
                if (nameToken.Type == TokenType.Identifier)
                {
                    return(text.GetText(nameToken.Start, name.Length) == name);
                }
            }

            return(false);
        }
コード例 #31
0
ファイル: Parser.cs プロジェクト: edongashi/tss
        public static ElementSelector ParseNotSelector(ITokenStream tokens)
        {
            var zero    = tokens.Peek();
            var inverse = false;

            if (zero is NotToken)
            {
                inverse = true;
                tokens.Consume();
            }

            var atom = ParseAtomSelector(tokens);

            return(inverse ? new NotSelector(atom) : atom);
        }
コード例 #32
0
ファイル: ItemFactory.cs プロジェクト: obedurena/SassyStudio
        private ParseItem CreateImport(ComplexItem parent, ITextProvider text, ITokenStream stream)
        {
            var filename = stream.Peek(2);

            // if doing @import url() then we use standard css import
            if (UrlItem.IsUrl(text, filename))
            {
                return(new CssImportDirective());
            }

            if ((filename.Type == TokenType.String || filename.Type == TokenType.BadString))
            {
                // check to see if import starts with http(s)://
                var preamble = text.GetText(filename.Start, 9).Trim('"', '\'');
                if (preamble.StartsWith("//") || preamble.StartsWith("http://") || preamble.StartsWith("https://"))
                {
                    return(new CssImportDirective());
                }

                // check for media query
                var next = stream.Peek(3);
                if (next.Type == TokenType.Identifier)
                {
                    return(new CssImportDirective());
                }

                // check if we are importing actual css file
                if (text.GetText(filename.Start, filename.Length).Trim('"', '\'').EndsWith(".css"))
                {
                    return(new CssImportDirective());
                }
            }

            // since we didn't detect that it's a css import, use the sass import
            return(new SassImportDirective());
        }
コード例 #33
0
        protected override bool ParseSelectorToken(IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.Colon && stream.Peek(1).Type == TokenType.Function)
            {
                Prefix = Children.AddCurrentAndAdvance(stream);
                var function = itemFactory.CreateSpecific <PseduoFunction>(this, text, stream);
                if (function.Parse(itemFactory, text, stream))
                {
                    Function = function;
                    Children.Add(function);
                }
            }

            return(Children.Count > 0);
        }
コード例 #34
0
        protected override bool ParseSelectorToken(IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.Colon && stream.Peek(1).Type == TokenType.Function)
            {
                Prefix = Children.AddCurrentAndAdvance(stream);
                var function = itemFactory.CreateSpecific<PseduoFunction>(this, text, stream);
                if (function.Parse(itemFactory, text, stream))
                {
                    Function = function;
                    Children.Add(function);
                }
            }

            return Children.Count > 0;
        }
コード例 #35
0
ファイル: ItemFactory.cs プロジェクト: obedurena/SassyStudio
        private ParseItem CreateAtRule(ComplexItem parent, ITextProvider text, ITokenStream stream)
        {
            var nameToken = stream.Peek(1);

            if (nameToken.Type == TokenType.Identifier || nameToken.Type == TokenType.Function)
            {
                var ruleName = text.GetText(nameToken.Start, nameToken.Length);
                switch (ruleName)
                {
                case "mixin": return(new MixinDefinition());

                case "content": return(new ContentDirective());

                case "include": return(new MixinReference());

                case "function": return(new UserFunctionDefinition());

                case "import": return(CreateImport(parent, text, stream));

                case "extend": return(new ExtendDirective());

                case "for": return(new ForLoopDirective());

                case "while": return(new WhileLoopDirective());

                case "each": return(new EachLoopDirective());

                case "if":
                case "else":
                case "else if": return(new ConditionalControlDirective());

                case "media": return(new MediaQueryDirective());

                case "font-face": return(new FontFaceDirective());

                case "page": return(new PageDirective());

                case "charset": return(new CharsetDirective());

                case "keyframes": return(new KeyframesDirective());

                default: return(new AtRule());
                }
            }

            return(new TokenItem());
        }
コード例 #36
0
ファイル: Parser.cs プロジェクト: edongashi/tss
        public static ContainmentSelector ParseContainmentSelector(ITokenStream tokens, bool isNested)
        {
            var selectors = new List <AndSelector>
            {
                ParseAndSelector(tokens)
            };

            while (true)
            {
                var zero = tokens.Peek();
                if (!(zero is WhitespaceToken))
                {
                    break;
                }

                var one = tokens.DrainPeek();
                switch (one)
                {
                case CommaToken _:
                case LCurlyToken _:
                    goto exit;

                default:
                    selectors.Add(ParseAndSelector(tokens));
                    continue;
                }
            }

exit:

            for (var i = 1; i < selectors.Count; i++)
            {
                if (selectors[i].HasContextSelector)
                {
                    throw new FormatException("Unexpected context selector in rule.");
                }
            }

            if (isNested && !selectors[0].HasContextSelector)
            {
                selectors.Insert(0, new AndSelector(new[] { new ContextSelector() }));
            }

            return(new ContainmentSelector(selectors));
        }
コード例 #37
0
        public static Token[] PeekNonEmpty(this ITokenStream stream)
        {
            while (true)
            {
                var tokens = stream.Peek();
                if (tokens == null)
                {
                    return(null);
                }

                if (tokens.Length > 0)
                {
                    return(tokens);
                }

                stream.Move();
            }
        }
コード例 #38
0
        static ParseItem CreateDocumentationTag(ComplexItem parent, IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            if (!(parent is XmlDocumentationComment))
                return null;

            if (stream.Current.Type == TokenType.LessThan)
            {
                var next = stream.Peek(1);
                if (next.Type != TokenType.Identifier)
                    return null;

                switch (text.GetText(next.Start, next.Length))
                {
                    case "reference": return new FileReferenceTag();
                }
            }

            return null;
        }
コード例 #39
0
ファイル: Parser.cs プロジェクト: edongashi/tss
        internal static Token DrainPeek(this ITokenStream tokens)
        {
            Token current;

            while (true)
            {
                current = tokens.Peek();
                if (current is WhitespaceToken)
                {
                    tokens.Consume();
                }
                else
                {
                    break;
                }
            }

            return(current);
        }
コード例 #40
0
ファイル: ItemFactory.cs プロジェクト: obedurena/SassyStudio
        private ParseItem CreateSelectorComponent(ComplexItem parent, ITextProvider text, ITokenStream stream)
        {
            switch (stream.Current.Type)
            {
            case TokenType.Asterisk: return(new UniversalSelector());

            case TokenType.Period: return(new ClassSelector());

            case TokenType.Hash: return(new IdSelector());

            case TokenType.Identifier: return(new TypeSelector());

            case TokenType.OpenBrace: return(new AttributeSelector());

            case TokenType.DoubleColon: return(new PseudoElementSelector());

            case TokenType.GreaterThan: return(new ChildCombinator());

            case TokenType.Plus: return(new AdjacentSiblingCombinator());

            case TokenType.Tilde: return(new GeneralSiblingCombinator());

            case TokenType.Ampersand: return(new ParentReferenceSelector());

            case TokenType.OpenInterpolation: return(new StringInterpolationSelector());

            case TokenType.PercentSign: return(new ExtendOnlySelector());
            }

            if (stream.Current.Type == TokenType.Colon)
            {
                var next = stream.Peek(1);
                switch (next.Type)
                {
                case TokenType.Identifier: return(new PseudoClassSelector());

                case TokenType.Function: return(new PseudoFunctionSelector());
                }
            }

            return(null);
        }
コード例 #41
0
        public static bool IsDeclaration(ITextProvider text, ITokenStream stream)
        {
            int position = stream.Position;

            bool validPropertyName = false;

            while (true)
            {
                var last = stream.Current;
                var next = stream.Advance();

                if (next.Start > last.End || IsDeclarationTerminator(last.Type))
                {
                    break;
                }

                if (next.Type == TokenType.Colon)
                {
                    var value = stream.Peek(1);
                    switch (value.Type)
                    {
                    case TokenType.Ampersand:
                        validPropertyName = false;
                        break;

                    case TokenType.Identifier:
                    case TokenType.Function:
                        validPropertyName = value.Start > next.End || !IsPseudoSelector(text, value);
                        break;

                    default:
                        validPropertyName = true;
                        break;
                    }
                    break;
                }
            }

            stream.SeekTo(position);
            return(validPropertyName);
        }
コード例 #42
0
        public override bool Parse(IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.Identifier && IsValidNamedRange(text.GetText(stream.Current.Start, stream.Current.Length)))
            {
                AnimationBegin = Children.AddCurrentAndAdvance(stream, SassClassifierType.Keyword);
            }
            else if (stream.Current.Type == TokenType.Number && stream.Peek(1).Type == TokenType.PercentSign)
            {
                ParseItem begin = itemFactory.Create <PercentageUnit>(this, text, stream);
                if (begin.Parse(itemFactory, text, stream))
                {
                    AnimationBegin = begin;
                    Children.Add(begin);

                    if (stream.Current.Type == TokenType.Comma)
                    {
                        Comma = Children.AddCurrentAndAdvance(stream, SassClassifierType.Punctuation);
                    }

                    ParseItem end = itemFactory.Create <PercentageUnit>(this, text, stream);
                    if (end.Parse(itemFactory, text, stream))
                    {
                        AnimationEnd = end;
                        Children.Add(end);
                    }
                }
            }

            if (AnimationBegin != null)
            {
                var block = itemFactory.CreateSpecific <RuleBlock>(this, text, stream);
                if (block.Parse(itemFactory, text, stream))
                {
                    Body = block;
                    Children.Add(block);
                }
            }

            return(Children.Count > 0);
        }
コード例 #43
0
        protected virtual bool ParseCombinator(IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            SelectorCombinator combinator = null;

            switch (stream.Current.Type)
            {
            case TokenType.GreaterThan:
                combinator = new ChildCombinator();
                break;

            case TokenType.Plus:
                combinator = new AdjacentSiblingCombinator();
                break;

            case TokenType.Tilde:
                combinator = new GeneralSiblingCombinator();
                break;
            }

            if (combinator != null)
            {
                if (combinator.Parse(itemFactory, text, stream))
                {
                    Children.Add(combinator);
                    Combinator = combinator;
                }
            }
            else if (stream.Current.Type != TokenType.OpenCurlyBrace)
            {
                // whitespace only combinator means no adding to children or parsing
                // we just want to know that there was a combinator
                if (stream.Current.Start >= (stream.Peek(-1).End + 1))
                {
                    Combinator = new DescendantCombinator();
                }
            }

            return(Combinator != null);
        }
コード例 #44
0
        public override bool Parse(IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            if (stream.Current.Type == TokenType.Identifier && IsValidNamedRange(text.GetText(stream.Current.Start, stream.Current.Length)))
            {
                AnimationBegin = Children.AddCurrentAndAdvance(stream, SassClassifierType.Keyword);
            }
            else if (stream.Current.Type == TokenType.Number && stream.Peek(1).Type == TokenType.PercentSign)
            {
                ParseItem begin = itemFactory.Create<PercentageUnit>(this, text, stream);
                if (begin.Parse(itemFactory, text, stream))
                {
                    AnimationBegin = begin;
                    Children.Add(begin);

                    if (stream.Current.Type == TokenType.Comma)
                        Comma = Children.AddCurrentAndAdvance(stream, SassClassifierType.Punctuation);

                    ParseItem end = itemFactory.Create<PercentageUnit>(this, text, stream);
                    if (end.Parse(itemFactory, text, stream))
                    {
                        AnimationEnd = end;
                        Children.Add(end);
                    }
                }
            }

            if (AnimationBegin != null)
            {
                var block = itemFactory.CreateSpecific<RuleBlock>(this, text, stream);
                if (block.Parse(itemFactory, text, stream))
                {
                    Body = block;
                    Children.Add(block);
                }
            }

            return Children.Count > 0;
        }
コード例 #45
0
        public static bool IsDeclaration(ITextProvider text, ITokenStream stream)
        {
            int position = stream.Position;

            bool validPropertyName = false;
            while (true)
            {
                var last = stream.Current;
                var next = stream.Advance();

                if (next.Start > last.End || IsDeclarationTerminator(last.Type))
                    break;

                if (next.Type == TokenType.Colon)
                {
                    var value = stream.Peek(1);
                    switch (value.Type)
                    {
                        case TokenType.Ampersand:
                            validPropertyName = false;
                            break;
                        case TokenType.Identifier:
                        case TokenType.Function:
                            validPropertyName = value.Start > next.End || !IsPseudoSelector(text, value);
                            break;
                        default:
                            validPropertyName = true;
                            break;
                    }
                    break;
                }
            }

            stream.SeekTo(position);
            return validPropertyName;
        }
コード例 #46
0
        static ParseItem CreateSimpleSelector(ComplexItem parent, IItemFactory itemFactory, ITextProvider text, ITokenStream stream)
        {
            switch (stream.Current.Type)
            {
                case TokenType.Ampersand: return new ParentReferenceSelector();
                case TokenType.Asterisk: return new UniversalSelector();
                case TokenType.Period: return new ClassSelector();
                case TokenType.Hash: return new IdSelector();
                case TokenType.Identifier: return new TypeSelector();
                case TokenType.OpenBrace: return new AttributeSelector();
                case TokenType.DoubleColon: return new PseudoElementSelector();
                case TokenType.PercentSign: return new ExtendOnlySelector();
            }

            if (stream.Current.Type == TokenType.Colon)
            {
                var next = stream.Peek(1);
                switch (next.Type)
                {
                    case TokenType.Identifier: return new PseudoClassSelector();
                    case TokenType.Function: return new PseudoFunctionSelector();
                }
            }

            return null;
        }
コード例 #47
0
ファイル: Function.cs プロジェクト: profet23/SassyStudio
 static bool IsFunctionCall(ITokenStream stream)
 {
     return stream.Current.Type == TokenType.Function || (stream.Current.Type == TokenType.Identifier && stream.Peek(1).Type == TokenType.OpenFunctionBrace);
 }
コード例 #48
0
 public static bool IsNamedArgument(ITextProvider text, ITokenStream stream)
 {
     return VariableName.IsVariable(text, stream) && stream.Peek(2).Type == TokenType.Colon;
 }