All files / src/nodes FunctionDefinition.js

100% Statements 45/45
100% Branches 40/40
100% Functions 12/12
100% Lines 37/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125          55x   55x 55x 55x   55x 2089x 2029x 115x           105x 105x       105x     55x 3359x 2559x       800x   135x         25x               135x       665x     55x 2089x       2089x   55x 2089x 90x 15x               55x 2089x       55x 2089x       55x 2089x                 2089x   2089x   55x 2089x                                               55x  
const {
  doc: {
    builders: { dedent, group, indent, join, line }
  },
  util: { getNextNonSpaceNonCommentCharacterIndex }
} = require('prettier');
 
const printSeparatedList = require('./print-separated-list');
const printSeparatedItem = require('./print-separated-item');
const printComments = require('./print-comments');
 
const functionName = (node, options) => {
  if (node.isConstructor && !node.name) return 'constructor';
  if (node.name) return `function ${node.name}`;
  if (node.isReceiveEther) return 'receive';
  // The parser doesn't give us any information about the keyword used for the
  // fallback.
  // Using the originalText is the next best option.
  // A neat idea would be to rely on the pragma and enforce it but for the
  // moment this will do.
  const names = { fallback: 'fallback', function: 'function' };
  const name = options.originalText.slice(
    options.locStart(node),
    options.locStart(node) + 8
  );
  return names[name];
};
 
const parameters = (parametersType, node, path, print, options) => {
  if (node[parametersType] && node[parametersType].length > 0) {
    return printSeparatedList(path.map(print, parametersType), {
      grouped: false
    });
  }
  if (node.comments && node.comments.length > 0) {
    // we add a check to see if the comment is inside the parentheses
    const parameterComments = printComments(
      node,
      path,
      options,
      (comment) =>
        options.originalText.charAt(
          getNextNonSpaceNonCommentCharacterIndex(
            options.originalText,
            comment,
            options.locEnd
          )
        ) === ')'
    );
    return parameterComments.parts.length > 0
      ? printSeparatedItem(parameterComments)
      : '';
  }
  return '';
};
 
const visibility = (node) =>
  node.visibility && node.visibility !== 'default'
    ? [line, node.visibility]
    : '';
 
const virtual = (node) => (node.isVirtual ? [line, 'virtual'] : '');
 
const override = (node, path, print) => {
  if (!node.override) return '';
  if (node.override.length === 0) return [line, 'override'];
  return [
    line,
    'override(',
    printSeparatedList(path.map(print, 'override')),
    ')'
  ];
};
 
const stateMutability = (node) =>
  node.stateMutability && node.stateMutability !== 'default'
    ? [line, node.stateMutability]
    : '';
 
const modifiers = (node, path, print) =>
  node.modifiers.length > 0
    ? [line, join(line, path.map(print, 'modifiers'))]
    : '';
 
const returnParameters = (node, path, print, options) =>
  node.returnParameters
    ? [
        line,
        'returns (',
        group(parameters('returnParameters', node, path, print, options)),
        ')'
      ]
    : '';
 
const signatureEnd = (node) => (node.body ? dedent(line) : ';');
 
const body = (node, path, print) => (node.body ? path.call(print, 'body') : '');
 
const FunctionDefinition = {
  print: ({ node, path, print, options }) => [
    group([
      functionName(node, options),
      '(',
      parameters('parameters', node, path, print, options),
      ')',
      indent(
        group([
          // TODO: sort comments for modifiers and return parameters
          printComments(node, path, options),
          visibility(node),
          stateMutability(node),
          virtual(node),
          override(node, path, print),
          modifiers(node, path, print),
          returnParameters(node, path, print, options),
          signatureEnd(node)
        ])
      )
    ]),
    body(node, path, print)
  ]
};
 
module.exports = FunctionDefinition;