Browse Source

Allow rules and children in any order

master
Dylan Baker 3 years ago
parent
commit
1e856cbbe7
2 changed files with 39 additions and 15 deletions
  1. 14
    15
      src/parser.ts
  2. 25
    0
      src/tests/parser.test.ts

+ 14
- 15
src/parser.ts View File

@@ -245,25 +245,24 @@ export default class Parser {
245 245
     }
246 246
 
247 247
     const rules: AST.Rule[] = [];
248
+    const children: AST.RuleSet[] = [];
248 249
 
249
-    while (this.currentToken().type === TokenTypes.PROPERTY) {
250
-      const propertyToken = this.eat(TokenTypes.PROPERTY);
251
-      if (propertyToken instanceof ParserError) return propertyToken;
252
-
253
-      const property = new AST.Property(propertyToken);
254
-
255
-      const value = this.value();
256
-      if (value instanceof ParserError) return value;
250
+    while ([TokenTypes.PROPERTY, TokenTypes.LPAREN].includes(this.currentToken().type)) {
251
+      if (this.currentToken().type === TokenTypes.PROPERTY) {
252
+        const propertyToken = this.eat(TokenTypes.PROPERTY);
253
+        if (propertyToken instanceof ParserError) return propertyToken;
257 254
 
258
-      rules.push(new AST.Rule(property, value));
259
-    }
255
+        const property = new AST.Property(propertyToken);
260 256
 
261
-    const children: AST.RuleSet[] = [];
257
+        const value = this.value();
258
+        if (value instanceof ParserError) return value;
262 259
 
263
-    while (this.currentToken().type === TokenTypes.LPAREN) {
264
-      const ruleSet = this.ruleSet(selectors);
265
-      if (ruleSet instanceof ParserError) return ruleSet;
266
-      children.push(ruleSet);
260
+        rules.push(new AST.Rule(property, value));
261
+      } else if (this.currentToken().type === TokenTypes.LPAREN) {
262
+        const ruleSet = this.ruleSet(selectors);
263
+        if (ruleSet instanceof ParserError) return ruleSet;
264
+        children.push(ruleSet);
265
+      }
267 266
     }
268 267
 
269 268
     const rParen = this.eat(TokenTypes.RPAREN);

+ 25
- 0
src/tests/parser.test.ts View File

@@ -287,3 +287,28 @@ test('parses mixin', (t) => {
287 287
     ]);
288 288
   }
289 289
 });
290
+
291
+test('allow rules and children in any order', (t) => {
292
+  t.plan(2);
293
+  const result = parse('(div (span :color blue) :color green)');
294
+  t.false(result instanceof ParserError);
295
+  if (!(result instanceof LexerError) && !(result instanceof ParserError)) {
296
+    t.deepEqual(
297
+      result.tree[0],
298
+      new AST.RuleSet(
299
+        [new AST.Selector(literalToken('div'))],
300
+        [new AST.Rule(property('color'), literalNode('green'))],
301
+        [
302
+          new AST.RuleSet(
303
+            [
304
+              new AST.Selector(literalToken('span'), [
305
+                new AST.Selector(literalToken('div')),
306
+              ]),
307
+            ],
308
+            [new AST.Rule(property('color'), literalNode('blue'))]
309
+          ),
310
+        ]
311
+      )
312
+    );
313
+  }
314
+});

Loading…
Cancel
Save