예제 #1
0
 public virtual LessNode VisitSelectorElement(LessParser.SelectorElementContext context)
 {
     throw new System.NotImplementedException();
 }
        public override LessNode VisitSelectorElement(LessParser.SelectorElementContext context)
        {
            IEnumerable <IdentifierPart> GetIdentifierParts()
            {
                string prefix = context.HASH()?.GetText()
                                ?? context.DOT()?.GetText();

                foreach (var identifierPart in this.GetIdentifierParts(prefix, context.identifier()))
                {
                    yield return(identifierPart);
                }
            }

            Identifier GetPseudoclassIdentifier()
            {
                var pseudo = context.pseudoClass();

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

                string prefix = pseudo.COLON()?.GetText()
                                ?? pseudo.COLONCOLON()?.GetText()
                                ?? "";

                return(new Identifier(new PseudoclassIdentifierPart(prefix, pseudo.pseudoclassIdentifier().GetText(),
                                                                    (Expression)pseudo.expression()?.Accept(this))));
            }

            Identifier GetIdentifier()
            {
                return(new Identifier(GetIdentifierParts()));
            }

            SelectorElement GetElement(bool hasTrailingWhitespace)
            {
                var parentSelector = context.parentSelectorReference();

                if (parentSelector != null)
                {
                    return(new ParentReferenceSelectorElement(hasTrailingWhitespace));
                }

                if (context.pseudoClass() != null)
                {
                    return(new IdentifierSelectorElement(GetPseudoclassIdentifier(), hasTrailingWhitespace));
                }

                if (context.identifier() != null)
                {
                    return(new IdentifierSelectorElement(GetIdentifier(), hasTrailingWhitespace));
                }

                var attrib = context.attrib();

                if (attrib != null)
                {
                    var identifier = (Identifier)attrib.identifier().Accept(this);

                    var op = attrib.attribRelate();
                    if (op != null)
                    {
                        return(new AttributeSelectorElement(identifier, op.GetText(), (Expression)attrib.attribValue().Accept(this),
                                                            hasTrailingWhitespace));
                    }

                    return(new AttributeSelectorElement(identifier, hasTrailingWhitespace));
                }

                // The lexer rules might match an ID selector as a color, so we account for that here
                if (context.HexColor() != null)
                {
                    return(new IdentifierSelectorElement(new Identifier(new ConstantIdentifierPart(context.HexColor().GetText())),
                                                         hasTrailingWhitespace));
                }

                return(new CombinatorSelectorElement(context.combinator().GetText(), hasTrailingWhitespace));
            }

            bool HasTrailingWhitespace()
            {
                int index = context.Stop.TokenIndex + 1;

                while (index < tokenStream.Size)
                {
                    var tokenType = tokenStream.Get(index).Type;
                    if (tokenType == LessLexer.WS)
                    {
                        return(true);
                    }

                    if (tokenType != LessLexer.COMMENT)
                    {
                        return(false);
                    }

                    index++;
                }

                return(false);
            }

            return(GetElement(HasTrailingWhitespace()));
        }