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 2072x 2013x 115x           105x 105x       105x     55x 3341x 2556x       785x   135x         25x               135x       650x     55x 2072x       2072x   55x 2072x 90x 15x               55x 2072x       55x 2072x       55x 2072x                 2072x   2072x   55x 2072x                                               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;