FeatureFunction.js 1.5 KB

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