/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
import * as lessScanner from './lessScanner';
import { TokenType } from './cssScanner';
import * as cssParser from './cssParser';
import * as nodes from './cssNodes';
import { ParseError } from './cssErrors';
/// <summary>
/// A parser for LESS
/// http://lesscss.org/
/// </summary>
var LESSParser = /** @class */ (function (_super) {
    __extends(LESSParser, _super);
    function LESSParser() {
        return _super.call(this, new lessScanner.LESSScanner()) || this;
    }
    LESSParser.prototype._parseStylesheetStatement = function (isNested) {
        if (isNested === void 0) { isNested = false; }
        if (this.peek(TokenType.AtKeyword)) {
            return this._parseVariableDeclaration()
                || this._parsePlugin()
                || _super.prototype._parseStylesheetAtStatement.call(this, isNested);
        }
        return this._tryParseMixinDeclaration()
            || this._tryParseMixinReference()
            || this._parseFunction()
            || this._parseRuleset(true);
    };
    LESSParser.prototype._parseImport = function () {
        if (!this.peekKeyword('@import') && !this.peekKeyword('@import-once') /* deprecated in less 1.4.1 */) {
            return null;
        }
        var node = this.create(nodes.Import);
        this.consumeToken();
        // less 1.4.1: @import (css) "lib"
        if (this.accept(TokenType.ParenthesisL)) {
            if (!this.accept(TokenType.Ident)) {
                return this.finish(node, ParseError.IdentifierExpected, [TokenType.SemiColon]);
            }
            do {
                if (!this.accept(TokenType.Comma)) {
                    break;
                }
            } while (this.accept(TokenType.Ident));
            if (!this.accept(TokenType.ParenthesisR)) {
                return this.finish(node, ParseError.RightParenthesisExpected, [TokenType.SemiColon]);
            }
        }
        if (!node.addChild(this._parseURILiteral()) && !node.addChild(this._parseStringLiteral())) {
            return this.finish(node, ParseError.URIOrStringExpected, [TokenType.SemiColon]);
        }
        if (!this.peek(TokenType.SemiColon) && !this.peek(TokenType.EOF)) {
            node.setMedialist(this._parseMediaQueryList());
        }
        return this.finish(node);
    };
    LESSParser.prototype._parsePlugin = function () {
        if (!this.peekKeyword('@plugin')) {
            return null;
        }
        var node = this.createNode(nodes.NodeType.Plugin);
        this.consumeToken(); // @import
        if (!node.addChild(this._parseStringLiteral())) {
            return this.finish(node, ParseError.StringLiteralExpected);
        }
        if (!this.accept(TokenType.SemiColon)) {
            return this.finish(node, ParseError.SemiColonExpected);
        }
        return this.finish(node);
    };
    LESSParser.prototype._parseMediaQuery = function (resyncStopToken) {
        var node = _super.prototype._parseMediaQuery.call(this, resyncStopToken);
        if (!node) {
            var node_1 = this.create(nodes.MediaQuery);
            if (node_1.addChild(this._parseVariable())) {
                return this.finish(node_1);
            }
            return null;
        }
        return node;
    };
    LESSParser.prototype._parseMediaDeclaration = function (isNested) {
        if (isNested === void 0) { isNested = false; }
        return this._tryParseRuleset(isNested)
            || this._tryToParseDeclaration()
            || this._tryParseMixinDeclaration()
            || this._tryParseMixinReference()
            || this._parseDetachedRuleSetMixin()
            || this._parseStylesheetStatement(isNested);
    };
    LESSParser.prototype._parseMediaFeatureName = function () {
        return this._parseIdent() || this._parseVariable();
    };
    LESSParser.prototype._parseVariableDeclaration = function (panic) {
        if (panic === void 0) { panic = []; }
        var node = this.create(nodes.VariableDeclaration);
        var mark = this.mark();
        if (!node.setVariable(this._parseVariable(true))) {
            return null;
        }
        if (this.accept(TokenType.Colon)) {
            if (this.prevToken) {
                node.colonPosition = this.prevToken.offset;
            }
            if (node.setValue(this._parseDetachedRuleSet())) {
                node.needsSemicolon = false;
            }
            else if (!node.setValue(this._parseExpr())) {
                return this.finish(node, ParseError.VariableValueExpected, [], panic);
            }
            node.addChild(this._parsePrio());
        }
        else {
            this.restoreAtMark(mark);
            return null; // at keyword, but no ':', not a variable declaration but some at keyword
        }
        if (this.peek(TokenType.SemiColon)) {
            node.semicolonPosition = this.token.offset; // not part of the declaration, but useful information for code assist
        }
        return this.finish(node);
    };
    LESSParser.prototype._parseDetachedRuleSet = function () {
        var mark = this.mark();
        // "Anonymous mixin" used in each() and possibly a generic type in the future
        if (this.peekDelim('#') || this.peekDelim('.')) {
            this.consumeToken();
            if (!this.hasWhitespace() && this.accept(TokenType.ParenthesisL)) {
                var node = this.create(nodes.MixinDeclaration);
                if (node.getParameters().addChild(this._parseMixinParameter())) {
                    while (this.accept(TokenType.Comma) || this.accept(TokenType.SemiColon)) {
                        if (this.peek(TokenType.ParenthesisR)) {
                            break;
                        }
                        if (!node.getParameters().addChild(this._parseMixinParameter())) {
                            this.markError(node, ParseError.IdentifierExpected, [], [TokenType.ParenthesisR]);
                        }
                    }
                }
                if (!this.accept(TokenType.ParenthesisR)) {
                    this.restoreAtMark(mark);
                    return null;
                }
            }
            else {
                this.restoreAtMark(mark);
                return null;
            }
        }
        if (!this.peek(TokenType.CurlyL)) {
            return null;
        }
        var content = this.create(nodes.BodyDeclaration);
        this._parseBody(content, this._parseDetachedRuleSetBody.bind(this));
        return this.finish(content);
    };
    LESSParser.prototype._parseDetachedRuleSetBody = function () {
        return this._tryParseKeyframeSelector() || this._parseRuleSetDeclaration();
    };
    LESSParser.prototype._addLookupChildren = function (node) {
        if (!node.addChild(this._parseLookupValue())) {
            return false;
        }
        var expectsValue = false;
        while (true) {
            if (this.peek(TokenType.BracketL)) {
                expectsValue = true;
            }
            if (!node.addChild(this._parseLookupValue())) {
                break;
            }
            expectsValue = false;
        }
        return !expectsValue;
    };
    LESSParser.prototype._parseLookupValue = function () {
        var node = this.create(nodes.Node);
        var mark = this.mark();
        if (!this.accept(TokenType.BracketL)) {
            this.restoreAtMark(mark);
            return null;
        }
        if (((node.addChild(this._parseVariable(false, true)) ||
            node.addChild(this._parsePropertyIdentifier())) &&
            this.accept(TokenType.BracketR)) || this.accept(TokenType.BracketR)) {
            return node;
        }
        this.restoreAtMark(mark);
        return null;
    };
    LESSParser.prototype._parseVariable = function (declaration, insideLookup) {
        if (declaration === void 0) { declaration = false; }
        if (insideLookup === void 0) { insideLookup = false; }
        var isPropertyReference = !declaration && this.peekDelim('$');
        if (!this.peekDelim('@') && !isPropertyReference && !this.peek(TokenType.AtKeyword)) {
            return null;
        }
        var node = this.create(nodes.Variable);
        var mark = this.mark();
        while (this.acceptDelim('@') || (!declaration && this.acceptDelim('$'))) {
            if (this.hasWhitespace()) {
                this.restoreAtMark(mark);
                return null;
            }
        }
        if (!this.accept(TokenType.AtKeyword) && !this.accept(TokenType.Ident)) {
            this.restoreAtMark(mark);
            return null;
        }
        if (!insideLookup && this.peek(TokenType.BracketL)) {
            if (!this._addLookupChildren(node)) {
                this.restoreAtMark(mark);
                return null;
            }
        }
        return node;
    };
    LESSParser.prototype._parseTermExpression = function () {
        return this._parseVariable() ||
            this._parseEscaped() ||
            _super.prototype._parseTermExpression.call(this) || // preference for colors before mixin references
            this._tryParseMixinReference(false);
    };
    LESSParser.prototype._parseEscaped = function () {
        if (this.peek(TokenType.EscapedJavaScript) ||
            this.peek(TokenType.BadEscapedJavaScript)) {
            var node = this.createNode(nodes.NodeType.EscapedValue);
            this.consumeToken();
            return this.finish(node);
        }
        if (this.peekDelim('~')) {
            var node = this.createNode(nodes.NodeType.EscapedValue);
            this.consumeToken();
            if (this.accept(TokenType.String) || this.accept(TokenType.EscapedJavaScript)) {
                return this.finish(node);
            }
            else {
                return this.finish(node, ParseError.TermExpected);
            }
        }
        return null;
    };
    LESSParser.prototype._parseOperator = function () {
        var node = this._parseGuardOperator();
        if (node) {
            return node;
        }
        else {
            return _super.prototype._parseOperator.call(this);
        }
    };
    LESSParser.prototype._parseGuardOperator = function () {
        if (this.peekDelim('>')) {
            var node = this.createNode(nodes.NodeType.Operator);
            this.consumeToken();
            this.acceptDelim('=');
            return node;
        }
        else if (this.peekDelim('=')) {
            var node = this.createNode(nodes.NodeType.Operator);
            this.consumeToken();
            this.acceptDelim('<');
            return node;
        }
        else if (this.peekDelim('<')) {
            var node = this.createNode(nodes.NodeType.Operator);
            this.consumeToken();
            this.acceptDelim('=');
            return node;
        }
        return null;
    };
    LESSParser.prototype._parseRuleSetDeclaration = function () {
        if (this.peek(TokenType.AtKeyword)) {
            return this._parseKeyframe()
                || this._parseMedia(true)
                || this._parseImport()
                || this._parseSupports(true) // @supports
                || this._parseDetachedRuleSetMixin() // less detached ruleset mixin
                || this._parseVariableDeclaration() // Variable declarations
                || _super.prototype._parseRuleSetDeclarationAtStatement.call(this);
        }
        return this._tryParseMixinDeclaration()
            || this._tryParseRuleset(true) // nested ruleset
            || this._tryParseMixinReference() // less mixin reference
            || this._parseFunction()
            || this._parseExtend() // less extend declaration
            || _super.prototype._parseRuleSetDeclaration.call(this); // try css ruleset declaration as the last option
    };
    LESSParser.prototype._parseKeyframeIdent = function () {
        return this._parseIdent([nodes.ReferenceType.Keyframe]) || this._parseVariable();
    };
    LESSParser.prototype._parseKeyframeSelector = function () {
        return this._parseDetachedRuleSetMixin() // less detached ruleset mixin
            || _super.prototype._parseKeyframeSelector.call(this);
    };
    LESSParser.prototype._parseSimpleSelectorBody = function () {
        return this._parseSelectorCombinator() || _super.prototype._parseSimpleSelectorBody.call(this);
    };
    LESSParser.prototype._parseSelector = function (isNested) {
        // CSS Guards
        var node = this.create(nodes.Selector);
        var hasContent = false;
        if (isNested) {
            // nested selectors can start with a combinator
            hasContent = node.addChild(this._parseCombinator());
        }
        while (node.addChild(this._parseSimpleSelector())) {
            hasContent = true;
            var mark = this.mark();
            if (node.addChild(this._parseGuard()) && this.peek(TokenType.CurlyL)) {
                break;
            }
            this.restoreAtMark(mark);
            node.addChild(this._parseCombinator()); // optional
        }
        return hasContent ? this.finish(node) : null;
    };
    LESSParser.prototype._parseSelectorCombinator = function () {
        if (this.peekDelim('&')) {
            var node = this.createNode(nodes.NodeType.SelectorCombinator);
            this.consumeToken();
            while (!this.hasWhitespace() && (this.acceptDelim('-') || this.accept(TokenType.Num) || this.accept(TokenType.Dimension) || node.addChild(this._parseIdent()) || this.acceptDelim('&'))) {
                //  support &-foo
            }
            return this.finish(node);
        }
        return null;
    };
    LESSParser.prototype._parseSelectorIdent = function () {
        if (!this.peekInterpolatedIdent()) {
            return null;
        }
        var node = this.createNode(nodes.NodeType.SelectorInterpolation);
        var hasContent = this._acceptInterpolatedIdent(node);
        return hasContent ? this.finish(node) : null;
    };
    LESSParser.prototype._parsePropertyIdentifier = function (inLookup) {
        if (inLookup === void 0) { inLookup = false; }
        var propertyRegex = /^[\w-]+/;
        if (!this.peekInterpolatedIdent() && !this.peekRegExp(this.token.type, propertyRegex)) {
            return null;
        }
        var mark = this.mark();
        var node = this.create(nodes.Identifier);
        node.isCustomProperty = this.acceptDelim('-') && this.acceptDelim('-');
        var childAdded = false;
        if (!inLookup) {
            if (node.isCustomProperty) {
                childAdded = this._acceptInterpolatedIdent(node);
            }
            else {
                childAdded = this._acceptInterpolatedIdent(node, propertyRegex);
            }
        }
        else {
            if (node.isCustomProperty) {
                childAdded = node.addChild(this._parseIdent());
            }
            else {
                childAdded = node.addChild(this._parseRegexp(propertyRegex));
            }
        }
        if (!childAdded) {
            this.restoreAtMark(mark);
            return null;
        }
        if (!inLookup && !this.hasWhitespace()) {
            this.acceptDelim('+');
            if (!this.hasWhitespace()) {
                this.acceptIdent('_');
            }
        }
        return this.finish(node);
    };
    LESSParser.prototype.peekInterpolatedIdent = function () {
        return this.peek(TokenType.Ident) ||
            this.peekDelim('@') ||
            this.peekDelim('$') ||
            this.peekDelim('-');
    };
    LESSParser.prototype._acceptInterpolatedIdent = function (node, identRegex) {
        var _this = this;
        var hasContent = false;
        var indentInterpolation = function () {
            var pos = _this.mark();
            if (_this.acceptDelim('-')) {
                if (!_this.hasWhitespace()) {
                    _this.acceptDelim('-');
                }
                if (_this.hasWhitespace()) {
                    _this.restoreAtMark(pos);
                    return null;
                }
            }
            return _this._parseInterpolation();
        };
        var accept = identRegex ?
            function () { return _this.acceptRegexp(identRegex); } :
            function () { return _this.accept(TokenType.Ident); };
        while (accept() ||
            node.addChild(this._parseInterpolation() ||
                this.try(indentInterpolation))) {
            hasContent = true;
            if (this.hasWhitespace()) {
                break;
            }
        }
        return hasContent;
    };
    LESSParser.prototype._parseInterpolation = function () {
        // @{name} Variable or
        // ${name} Property
        var mark = this.mark();
        if (this.peekDelim('@') || this.peekDelim('$')) {
            var node = this.createNode(nodes.NodeType.Interpolation);
            this.consumeToken();
            if (this.hasWhitespace() || !this.accept(TokenType.CurlyL)) {
                this.restoreAtMark(mark);
                return null;
            }
            if (!node.addChild(this._parseIdent())) {
                return this.finish(node, ParseError.IdentifierExpected);
            }
            if (!this.accept(TokenType.CurlyR)) {
                return this.finish(node, ParseError.RightCurlyExpected);
            }
            return this.finish(node);
        }
        return null;
    };
    LESSParser.prototype._tryParseMixinDeclaration = function () {
        var mark = this.mark();
        var node = this.create(nodes.MixinDeclaration);
        if (!node.setIdentifier(this._parseMixinDeclarationIdentifier()) || !this.accept(TokenType.ParenthesisL)) {
            this.restoreAtMark(mark);
            return null;
        }
        if (node.getParameters().addChild(this._parseMixinParameter())) {
            while (this.accept(TokenType.Comma) || this.accept(TokenType.SemiColon)) {
                if (this.peek(TokenType.ParenthesisR)) {
                    break;
                }
                if (!node.getParameters().addChild(this._parseMixinParameter())) {
                    this.markError(node, ParseError.IdentifierExpected, [], [TokenType.ParenthesisR]);
                }
            }
        }
        if (!this.accept(TokenType.ParenthesisR)) {
            this.restoreAtMark(mark);
            return null;
        }
        node.setGuard(this._parseGuard());
        if (!this.peek(TokenType.CurlyL)) {
            this.restoreAtMark(mark);
            return null;
        }
        return this._parseBody(node, this._parseMixInBodyDeclaration.bind(this));
    };
    LESSParser.prototype._parseMixInBodyDeclaration = function () {
        return this._parseFontFace() || this._parseRuleSetDeclaration();
    };
    LESSParser.prototype._parseMixinDeclarationIdentifier = function () {
        var identifier;
        if (this.peekDelim('#') || this.peekDelim('.')) {
            identifier = this.create(nodes.Identifier);
            this.consumeToken(); // # or .
            if (this.hasWhitespace() || !identifier.addChild(this._parseIdent())) {
                return null;
            }
        }
        else if (this.peek(TokenType.Hash)) {
            identifier = this.create(nodes.Identifier);
            this.consumeToken(); // TokenType.Hash
        }
        else {
            return null;
        }
        identifier.referenceTypes = [nodes.ReferenceType.Mixin];
        return this.finish(identifier);
    };
    LESSParser.prototype._parsePseudo = function () {
        if (!this.peek(TokenType.Colon)) {
            return null;
        }
        var mark = this.mark();
        var node = this.create(nodes.ExtendsReference);
        this.consumeToken(); // :
        if (this.acceptIdent('extend')) {
            return this._completeExtends(node);
        }
        this.restoreAtMark(mark);
        return _super.prototype._parsePseudo.call(this);
    };
    LESSParser.prototype._parseExtend = function () {
        if (!this.peekDelim('&')) {
            return null;
        }
        var mark = this.mark();
        var node = this.create(nodes.ExtendsReference);
        this.consumeToken(); // &
        if (this.hasWhitespace() || !this.accept(TokenType.Colon) || !this.acceptIdent('extend')) {
            this.restoreAtMark(mark);
            return null;
        }
        return this._completeExtends(node);
    };
    LESSParser.prototype._completeExtends = function (node) {
        if (!this.accept(TokenType.ParenthesisL)) {
            return this.finish(node, ParseError.LeftParenthesisExpected);
        }
        var selectors = node.getSelectors();
        if (!selectors.addChild(this._parseSelector(true))) {
            return this.finish(node, ParseError.SelectorExpected);
        }
        while (this.accept(TokenType.Comma)) {
            if (!selectors.addChild(this._parseSelector(true))) {
                return this.finish(node, ParseError.SelectorExpected);
            }
        }
        if (!this.accept(TokenType.ParenthesisR)) {
            return this.finish(node, ParseError.RightParenthesisExpected);
        }
        return this.finish(node);
    };
    LESSParser.prototype._parseDetachedRuleSetMixin = function () {
        if (!this.peek(TokenType.AtKeyword)) {
            return null;
        }
        var mark = this.mark();
        var node = this.create(nodes.MixinReference);
        if (node.addChild(this._parseVariable(true)) && (this.hasWhitespace() || !this.accept(TokenType.ParenthesisL))) {
            this.restoreAtMark(mark);
            return null;
        }
        if (!this.accept(TokenType.ParenthesisR)) {
            return this.finish(node, ParseError.RightParenthesisExpected);
        }
        return this.finish(node);
    };
    LESSParser.prototype._tryParseMixinReference = function (atRoot) {
        if (atRoot === void 0) { atRoot = true; }
        var mark = this.mark();
        var node = this.create(nodes.MixinReference);
        var identifier = this._parseMixinDeclarationIdentifier();
        while (identifier) {
            this.acceptDelim('>');
            var nextId = this._parseMixinDeclarationIdentifier();
            if (nextId) {
                node.getNamespaces().addChild(identifier);
                identifier = nextId;
            }
            else {
                break;
            }
        }
        if (!node.setIdentifier(identifier)) {
            this.restoreAtMark(mark);
            return null;
        }
        var hasArguments = false;
        if (this.accept(TokenType.ParenthesisL)) {
            hasArguments = true;
            if (node.getArguments().addChild(this._parseMixinArgument())) {
                while (this.accept(TokenType.Comma) || this.accept(TokenType.SemiColon)) {
                    if (this.peek(TokenType.ParenthesisR)) {
                        break;
                    }
                    if (!node.getArguments().addChild(this._parseMixinArgument())) {
                        return this.finish(node, ParseError.ExpressionExpected);
                    }
                }
            }
            if (!this.accept(TokenType.ParenthesisR)) {
                return this.finish(node, ParseError.RightParenthesisExpected);
            }
            identifier.referenceTypes = [nodes.ReferenceType.Mixin];
        }
        else {
            identifier.referenceTypes = [nodes.ReferenceType.Mixin, nodes.ReferenceType.Rule];
        }
        if (this.peek(TokenType.BracketL)) {
            if (!atRoot) {
                this._addLookupChildren(node);
            }
        }
        else {
            node.addChild(this._parsePrio());
        }
        if (!hasArguments && !this.peek(TokenType.SemiColon) && !this.peek(TokenType.CurlyR) && !this.peek(TokenType.EOF)) {
            this.restoreAtMark(mark);
            return null;
        }
        return this.finish(node);
    };
    LESSParser.prototype._parseMixinArgument = function () {
        // [variableName ':'] expression | variableName '...'
        var node = this.create(nodes.FunctionArgument);
        var pos = this.mark();
        var argument = this._parseVariable();
        if (argument) {
            if (!this.accept(TokenType.Colon)) {
                this.restoreAtMark(pos);
            }
            else {
                node.setIdentifier(argument);
            }
        }
        if (node.setValue(this._parseDetachedRuleSet() || this._parseExpr(true))) {
            return this.finish(node);
        }
        this.restoreAtMark(pos);
        return null;
    };
    LESSParser.prototype._parseMixinParameter = function () {
        var node = this.create(nodes.FunctionParameter);
        // special rest variable: @rest...
        if (this.peekKeyword('@rest')) {
            var restNode = this.create(nodes.Node);
            this.consumeToken();
            if (!this.accept(lessScanner.Ellipsis)) {
                return this.finish(node, ParseError.DotExpected, [], [TokenType.Comma, TokenType.ParenthesisR]);
            }
            node.setIdentifier(this.finish(restNode));
            return this.finish(node);
        }
        // special const args: ...
        if (this.peek(lessScanner.Ellipsis)) {
            var varargsNode = this.create(nodes.Node);
            this.consumeToken();
            node.setIdentifier(this.finish(varargsNode));
            return this.finish(node);
        }
        var hasContent = false;
        // default variable declaration: @param: 12 or @name
        if (node.setIdentifier(this._parseVariable())) {
            this.accept(TokenType.Colon);
            hasContent = true;
        }
        if (!node.setDefaultValue(this._parseDetachedRuleSet() || this._parseExpr(true)) && !hasContent) {
            return null;
        }
        return this.finish(node);
    };
    LESSParser.prototype._parseGuard = function () {
        if (!this.peekIdent('when')) {
            return null;
        }
        var node = this.create(nodes.LessGuard);
        this.consumeToken(); // when
        node.isNegated = this.acceptIdent('not');
        if (!node.getConditions().addChild(this._parseGuardCondition())) {
            return this.finish(node, ParseError.ConditionExpected);
        }
        while (this.acceptIdent('and') || this.accept(TokenType.Comma)) {
            if (!node.getConditions().addChild(this._parseGuardCondition())) {
                return this.finish(node, ParseError.ConditionExpected);
            }
        }
        return this.finish(node);
    };
    LESSParser.prototype._parseGuardCondition = function () {
        if (!this.peek(TokenType.ParenthesisL)) {
            return null;
        }
        var node = this.create(nodes.GuardCondition);
        this.consumeToken(); // ParenthesisL
        if (!node.addChild(this._parseExpr())) {
            // empty (?)
        }
        if (!this.accept(TokenType.ParenthesisR)) {
            return this.finish(node, ParseError.RightParenthesisExpected);
        }
        return this.finish(node);
    };
    LESSParser.prototype._parseFunction = function () {
        var pos = this.mark();
        var node = this.create(nodes.Function);
        if (!node.setIdentifier(this._parseFunctionIdentifier())) {
            return null;
        }
        if (this.hasWhitespace() || !this.accept(TokenType.ParenthesisL)) {
            this.restoreAtMark(pos);
            return null;
        }
        if (node.getArguments().addChild(this._parseMixinArgument())) {
            while (this.accept(TokenType.Comma) || this.accept(TokenType.SemiColon)) {
                if (this.peek(TokenType.ParenthesisR)) {
                    break;
                }
                if (!node.getArguments().addChild(this._parseMixinArgument())) {
                    return this.finish(node, ParseError.ExpressionExpected);
                }
            }
        }
        if (!this.accept(TokenType.ParenthesisR)) {
            return this.finish(node, ParseError.RightParenthesisExpected);
        }
        return this.finish(node);
    };
    LESSParser.prototype._parseFunctionIdentifier = function () {
        if (this.peekDelim('%')) {
            var node = this.create(nodes.Identifier);
            node.referenceTypes = [nodes.ReferenceType.Function];
            this.consumeToken();
            return this.finish(node);
        }
        return _super.prototype._parseFunctionIdentifier.call(this);
    };
    LESSParser.prototype._parseURLArgument = function () {
        var pos = this.mark();
        var node = _super.prototype._parseURLArgument.call(this);
        if (!node || !this.peek(TokenType.ParenthesisR)) {
            this.restoreAtMark(pos);
            var node_2 = this.create(nodes.Node);
            node_2.addChild(this._parseBinaryExpr());
            return this.finish(node_2);
        }
        return node;
    };
    return LESSParser;
}(cssParser.Parser));
export { LESSParser };
