index.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. 'use strict';
  2. module.exports.parse = parse;
  3. module.exports.generate = generate;
  4. // TODO(jamestalmage): Allow full range of identifier characters instead of just ASCII
  5. //
  6. // This will likely require a build step
  7. //
  8. // SPEC: http://www.ecma-international.org/ecma-262/5.1/#sec-7.6
  9. //
  10. // TOOLING:
  11. // https://github.com/mathiasbynens/regenerate
  12. // https://www.npmjs.com/package/regjsgen
  13. var regex = /^\s*(?:([A-Za-z$_][A-Za-z0-9$_]*)\s*\.)?\s*([A-Za-z$_][A-Za-z0-9$_]*)\s*\(\s*((?:[A-Za-z$_][A-Za-z0-9$_]*)|(?:\[\s*[A-Za-z$_][A-Za-z0-9$_]*\s*]))?((?:\s*,\s*(?:(?:[A-Za-z$_][A-Za-z0-9$_]*)|(?:\[\s*[A-Za-z$_][A-Za-z0-9$_]*\s*])))+)?\s*\)\s*$/;
  14. function parse(str) {
  15. var match = regex.exec(str);
  16. if (!match) {
  17. return null;
  18. }
  19. var callee;
  20. if (match[1]) {
  21. callee = {
  22. type: 'MemberExpression',
  23. object: match[1],
  24. member: match[2]
  25. };
  26. } else {
  27. callee = {
  28. type: 'Identifier',
  29. name: match[2]
  30. };
  31. }
  32. var args = match[4] || '';
  33. args = args.split(',');
  34. if (match[3]) {
  35. args[0] = match[3];
  36. }
  37. var trimmed = [];
  38. args.forEach(function (str) {
  39. var optional = false;
  40. str = str.replace(/\s+/g, '');
  41. if (!str.length) {
  42. return;
  43. }
  44. if (str.charAt(0) === '[' && str.charAt(str.length - 1) === ']') {
  45. optional = true;
  46. str = str.substring(1, str.length - 1);
  47. }
  48. trimmed.push({
  49. name: str,
  50. optional: optional
  51. });
  52. });
  53. return {
  54. callee: callee,
  55. args: trimmed
  56. };
  57. }
  58. function generate(parsed) {
  59. var callee;
  60. if (parsed.callee.type === 'MemberExpression') {
  61. callee = [
  62. parsed.callee.object,
  63. '.',
  64. parsed.callee.member
  65. ];
  66. } else {
  67. callee = [parsed.callee.name];
  68. }
  69. return callee.concat([
  70. '(',
  71. parsed.args.map(function (arg) {
  72. return arg.optional ? '[' + arg.name + ']' : arg.name;
  73. }).join(', '),
  74. ')'
  75. ]).join('');
  76. }