FeatureFunction.cjs 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. 'use strict';
  2. const types = require('../../tokenizer/types.cjs');
  3. const name = 'FeatureFunction';
  4. const structure = {
  5. kind: String,
  6. feature: String,
  7. value: ['Declaration', 'Selector']
  8. };
  9. function getFeatureParser(kind, name) {
  10. const featuresOfKind = this.features[kind] || {};
  11. const parser = featuresOfKind[name];
  12. if (typeof parser !== 'function') {
  13. this.error(`Unknown feature ${name}()`);
  14. }
  15. return parser;
  16. }
  17. function parse(kind = 'unknown') {
  18. const start = this.tokenStart;
  19. const functionName = this.consumeFunctionName();
  20. const valueParser = getFeatureParser.call(this, kind, functionName.toLowerCase());
  21. this.skipSC();
  22. const value = this.parseWithFallback(
  23. () => {
  24. const startValueToken = this.tokenIndex;
  25. const value = valueParser.call(this);
  26. if (this.eof === false &&
  27. this.isBalanceEdge(startValueToken) === false) {
  28. this.error();
  29. }
  30. return value;
  31. },
  32. () => this.Raw(null, false)
  33. );
  34. if (!this.eof) {
  35. this.eat(types.RightParenthesis);
  36. }
  37. return {
  38. type: 'FeatureFunction',
  39. loc: this.getLocation(start, this.tokenStart),
  40. kind,
  41. feature: functionName,
  42. value
  43. };
  44. }
  45. function generate(node) {
  46. this.token(types.Function, node.feature + '(');
  47. this.node(node.value);
  48. this.token(types.RightParenthesis, ')');
  49. }
  50. exports.generate = generate;
  51. exports.name = name;
  52. exports.parse = parse;
  53. exports.structure = structure;