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 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | 54x 54x 54x 54x 8092x 925x 7167x 629x 629x 629x 629x 544x 537x 200x 119x 119x 10x 2930x 2783x 1155x 32x 224x 182x 224x 175x 10337x 10337x 8603x 1372x 1372x 1372x 553x 553x 399x 399x 336x 336x 735x 210x 28x 28x 182x 10x 10x 182x 679x 679x 679x 448x 448x 448x 336x 336x 336x 322x 322x 322x 231x 231x 231x 3192x 629x 54x | const extractComments = require('solidity-comments-extractor'); // https://prettier.io/docs/en/plugins.html#parsers const parser = require('@solidity-parser/parser'); const semver = require('semver'); const tryHug = (node, operators) => { if (node.type === 'BinaryOperation' && operators.includes(node.operator)) return { type: 'TupleExpression', components: [node], isArray: false }; return node; }; function parse(text, _parsers, options) { const compiler = semver.coerce(options.compiler); const parsed = parser.parse(text, { loc: true, range: true }); parsed.comments = extractComments(text); parser.visit(parsed, { PragmaDirective(ctx) { // if the pragma is not for solidity we leave. if (ctx.name !== 'solidity') return; // if the compiler option has not been provided we leave. if (!compiler) return; // we make a check against each pragma directive in the document. if (!semver.satisfies(compiler, ctx.value)) { // @TODO: investigate the best way to warn that would apply to // different editors. // eslint-disable-next-line no-console console.warn( `[prettier-solidity] The compiler option is set to '${options.compiler}', which does not satisfy 'pragma solidity ${ctx.value}'.` ); } }, ModifierDefinition(ctx) { if (!ctx.parameters) { ctx.parameters = []; } }, FunctionDefinition(ctx) { if (!ctx.isConstructor) { ctx.modifiers.forEach((modifier) => { if (modifier.arguments && modifier.arguments.length === 0) { // eslint-disable-next-line no-param-reassign modifier.arguments = null; } }); } }, ForStatement(ctx) { if (ctx.initExpression) { ctx.initExpression.omitSemicolon = true; } ctx.loopExpression.omitSemicolon = true; }, HexLiteral(ctx) { ctx.value = options.singleQuote ? `hex'${ctx.value.slice(4, -1)}'` : `hex"${ctx.value.slice(4, -1)}"`; }, ElementaryTypeName(ctx) { // if the compiler is below 0.8.0 we will recognize the type 'byte' as an // alias of 'bytes1'. Otherwise we will ignore this and enforce always // 'bytes1'. const pre080 = compiler && semver.satisfies(compiler, '<0.8.0'); if (!pre080 && ctx.name === 'byte') ctx.name = 'bytes1'; }, BinaryOperation(ctx) { switch (ctx.operator) { case '+': case '-': ctx.left = tryHug(ctx.left, ['%']); ctx.right = tryHug(ctx.right, ['%']); break; case '*': ctx.left = tryHug(ctx.left, ['/', '%']); break; case '/': ctx.left = tryHug(ctx.left, ['*', '%']); break; case '%': ctx.left = tryHug(ctx.left, ['*', '/', '%']); break; case '**': // If the compiler has not been given as an option using we leave a**b**c. if (!compiler) break; if (semver.satisfies(compiler, '<0.8.0')) { // If the compiler is less than 0.8.0 then a**b**c is formatted as // (a**b)**c. ctx.left = tryHug(ctx.left, ['**']); break; } if ( ctx.left.type === 'BinaryOperation' && ctx.left.operator === '**' ) { // the parser still organizes the a**b**c as (a**b)**c so we need // to restructure it. ctx.right = { type: 'TupleExpression', components: [ { type: 'BinaryOperation', operator: '**', left: ctx.left.right, right: ctx.right } ], isArray: false }; ctx.left = ctx.left.left; } break; case '<<': case '>>': ctx.left = tryHug(ctx.left, ['+', '-', '*', '/', '**', '<<', '>>']); ctx.right = tryHug(ctx.right, ['+', '-', '*', '/', '**']); break; case '&': ctx.left = tryHug(ctx.left, ['+', '-', '*', '/', '**', '<<', '>>']); ctx.right = tryHug(ctx.right, ['+', '-', '*', '/', '**', '<<', '>>']); break; case '|': ctx.left = tryHug(ctx.left, [ '+', '-', '*', '/', '**', '<<', '>>', '&', '^' ]); ctx.right = tryHug(ctx.right, [ '+', '-', '*', '/', '**', '<<', '>>', '&', '^' ]); break; case '^': ctx.left = tryHug(ctx.left, [ '+', '-', '*', '/', '**', '<<', '>>', '&' ]); ctx.right = tryHug(ctx.right, [ '+', '-', '*', '/', '**', '<<', '>>', '&' ]); break; case '||': ctx.left = tryHug(ctx.left, ['&&']); ctx.right = tryHug(ctx.right, ['&&']); break; case '&&': default: break; } } }); return parsed; } module.exports = parse; |