diff --git a/src/parser/cssParser.ts b/src/parser/cssParser.ts index 13fdabd5..43eabba0 100644 --- a/src/parser/cssParser.ts +++ b/src/parser/cssParser.ts @@ -2012,6 +2012,12 @@ export class Parser { public _parseBinaryExpr(preparsedLeft?: nodes.BinaryExpression, preparsedOper?: nodes.Node): nodes.BinaryExpression | null { let node = this.create(nodes.BinaryExpression); + // fixes a overshoot later, where the operand token starts at current spot + // instead of backtracking to the beginning of the previous + if (preparsedLeft) { + node.offset = preparsedLeft.offset; + } + if (!node.setLeft((preparsedLeft || this._parseTerm()))) { return null; } diff --git a/src/test/css/parser.test.ts b/src/test/css/parser.test.ts index 0d6154e8..b17e28d9 100644 --- a/src/test/css/parser.test.ts +++ b/src/test/css/parser.test.ts @@ -44,6 +44,13 @@ export function assertError(text: string, parser: Parser, f: () => nodes.Node | } +export function assertType(text: string, parser: Parser, nodeType: nodes.NodeType, f: () => nodes.Node | null) { + const node = parser.internalParse(text, f)!; + assert.ok(node !== null, 'no node returned'); + const targetNode = node.findChildAtOffset(text.indexOf("--x") + 1, true)!; + assert.equal(nodes.NodeType[targetNode.type], nodes.NodeType[nodes.NodeType.Identifier]); +} + suite('CSS - Parser', () => { test('stylesheet', function () { @@ -701,4 +708,17 @@ suite('CSS - Parser', () => { assertError('url(http://msft.com\')', parser, parser._parseURILiteral.bind(parser), ParseError.RightParenthesisExpected); }); + test('nested identifier', function() { + const parser = new Parser(); + assertType("calc(100% - var(--x))", parser, nodes.NodeType.Identifier, parser._parseExpr.bind(parser));; + assertType("calc(100% - 2 * var(--x))", parser, nodes.NodeType.Identifier, parser._parseExpr.bind(parser));; + assertType("calc(1 + 2 + var(--x))", parser, nodes.NodeType.Identifier, parser._parseExpr.bind(parser));; + assertType("calc((100% - var(--x)) * 2)", parser, nodes.NodeType.Identifier, parser._parseExpr.bind(parser));; + // no longer fail + assertType("calc(2 * var(--x) + 1)", parser, nodes.NodeType.Identifier, parser._parseExpr.bind(parser));; + assertType("calc(var(--x) * 2 / 3)", parser, nodes.NodeType.Identifier, parser._parseExpr.bind(parser));; + assertType("calc(-1 * var(--x) + 1 * 2)", parser, nodes.NodeType.Identifier, parser._parseExpr.bind(parser));; + assertType("calc((100% - var(--x)) * 2 / 3)", parser, nodes.NodeType.Identifier, parser._parseExpr.bind(parser));; + }); + });