{"_id":"@alu0101056944/espree-logging-solution","name":"@alu0101056944/espree-logging-solution","dist-tags":{"latest":"1.5.2"},"versions":{"1.5.2":{"name":"@alu0101056944/espree-logging-solution","author":{"name":"Casiano Rodriguez Leon","email":"crguezl@ull.edu.es","url":"https://crguezl.github.io/"},"description":"Adds logs to javascript code","type":"module","bin":{"funlog":"bin/log.js"},"scripts":{"test1":"node bin/log.js test/data/test1.js -o ./output.js","test2":"node bin/log.js test/data/test2.js -o ./output.js","test3":"node bin/log.js test/data/test3.js -o ./output.js","test4":"node bin/log.js test/data/test4.js -o ./output.js","test":"mocha test/test.mjs","cov":"nyc npm test","cov2":"nyc --reporter=html --reporter=text --report-dir docs mocha","doc":"documentation readme ./src/** --section=API","doc2":"documentation build ./src/** -f html -o docs"},"dependencies":{"acorn":"^8.8.2","commander":"^10.0.0","escodegen":"^2.0.0","espree":"^9.4.1","estraverse":"^5.2.0","underscore":"^1.12.0"},"version":"1.5.2","devDependencies":{"mocha":"^10.2.0","nyc":"*","documentation":"*"},"main":"src/logging-espree.js","gitHead":"6e9e23fdc6214a196377c794fe5a211ed360e08b","_id":"@alu0101056944/espree-logging-solution@1.5.2","_nodeVersion":"19.6.0","_npmVersion":"9.4.0","dist":{"integrity":"sha512-i5beV/OypGNOVi4Rtqi7Ide0h+ji3P6yxvfV6B/pOIKK3GaxPbNWBLIZ4hIiAEhq5xXMpe1psYrD2e4XVm7NtQ==","shasum":"31afe6362be83da2424516ef17a2cb9d71f4aa8b","tarball":"https://registry.npmjs.org/@alu0101056944/espree-logging-solution/-/espree-logging-solution-1.5.2.tgz","fileCount":53,"unpackedSize":1624480,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC8RD0ZoQRcN8jm5yKPZEOyOYK1MnzVKzNFDaU0YQXyuwIgPgMTEjQU08ZTE3VgwEFmdA7FFs71gXngAquzzVCi1Hc="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj/9muACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoT6Q//WQ1Sls6fnFLRJoYTqntwwar0ciXLsOs87K4dzANa7ZtJTm2V\r\nU8Py+X0+UWcVuf4QCIBsC1PGDiOftQhdNIQGqrzZakujZkXG0dxzt2p5CewM\r\nzlwls7Nd069gbbTaSq9Esk/jJ8nt7iTaw1G7isIqjDPtrT1e3d5tvCNIKo2o\r\niiskgA0X6fjCXeepn6QsS5rJqR0ZkMADPu69BTNV3+mdKiSbnwuIcqQKgG32\r\nTSF3UNxRsZj0D0HQ6WnD+ifZPXWZYFXMRiDj4KfZNWAe3xOfiuT1IfHAGA2j\r\nSe4Y0KOp47YhUQeX+wnQBNbkYREj8VefnUetrLFl5b9J2YLThEWruFaR6MWo\r\nqKR170/ekjJsq4/taxoJ+CvOI1C9d8GpNDFAmhOKzn4PUOsfBR7r0+1gpHxa\r\ny0BbnrbMAgLonv6O9n5Ito34Whj3KPBu1DudE2ZToX5wof9ApDTcMp2PEoKR\r\nOc2D/8M/FWh8nW3rqDjMbEFzu8QM2l8Is9Ks820CLLLjuSuNBl30mW0Fzvt3\r\nWKkZEvsPu2WgTbes4Fcyx1/ouh8ZjEeQCMlTfz3jc9ZvQ1z3TaTvL7E0el4j\r\nR1JlxhhRvXIOEkNsAaeViwkEPB/2jhKFEoFtJy/vlo4vqBt9p5QD+U4v5nIk\r\nv1zFK7xC7UM7GiyG6lmhR6V+BaiJpgZvJms=\r\n=dVhA\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alu0101056944","email":"alu0101056944@ull.edu.es"},"directories":{},"maintainers":[{"name":"alu0101056944","email":"alu0101056944@ull.edu.es"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/espree-logging-solution_1.5.2_1677711790410_0.16887721408208045"},"_hasShrinkwrap":false}},"time":{"created":"2023-03-01T23:03:10.337Z","1.5.2":"2023-03-01T23:03:10.725Z","modified":"2023-03-01T23:03:10.886Z"},"maintainers":[{"name":"alu0101056944","email":"alu0101056944@ull.edu.es"}],"description":"Adds logs to javascript code","author":{"name":"Casiano Rodriguez Leon","email":"crguezl@ull.edu.es","url":"https://crguezl.github.io/"},"readme":"[![Open in Codespaces](https://classroom.github.com/assets/launch-codespace-f4981d0f882b2a3f0472912d15f9806d57e124e0fc890972558857b51b24a6f9.svg)](https://classroom.github.com/open-in-codespaces?assignment_repo_id=10326843)\n\n# Práctica Espree logging\n\n## API\n\n<!-- Generated by documentation.js. Update this documentation by updating the source code. -->\n\n#### Table of Contents\n\n*   [transpile](#transpile)\n    *   [Parameters](#parameters)\n*   [addLogging](#addlogging)\n    *   [Parameters](#parameters-1)\n*   [addBeforeCode](#addbeforecode)\n    *   [Parameters](#parameters-2)\n\n### transpile\n\n#### Parameters\n\n*   `inputFile` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** path to input file\n*   `outputFile` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** path to output file\n\n### addLogging\n\n#### Parameters\n\n*   `code` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** to log\n\nReturns **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** logged code\n\n### addBeforeCode\n\n#### Parameters\n\n*   `node` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** of the AST\n\n## Ejecutable\n\nEl ejecutable <code>bin/log.js</code> puede ser utilizado de la siguiente forma:\n\n```bash\nArguments:\n  filename                 file with the original code\n\nOptions:\n  -V, --version            output the version number\n  -o, --output <filename>  file in which to write the output\n  -h, --help               display help for command\n```\n\nEjemplo de ejecución:\n\n```bash\nnpx funlog test/data/test1.js -o output.txt\n```\n\n## Instalación\n\nPara instalar utilizar el siguiente comando:\n\n```bash\nnpm i\n```\n\n## Resumen de lo aprendido\n\n### Estructura de el arbol AST\n\nUn nodo <code>FunctionDeclaration</code> tiene un una propiedad *body*, una propiedad *params* y una propiedad *args* y el *body* suele ser un <code>BlockStatement</code> cuyo *body* es un array. Dentro de ese array podemos meter otros nodos que queramos, capacidad que aplicamos para incluir un nodo <code>CallStatement</code> equivalente a <code>console.log(...)</code>\n\n## Indicar los valores de los argumentos\n\nSe ha modificado el código de `logging-espree.js` para que el log también indique los valores de los argumentos que se pasaron a la función.\nEjemplo:\n\n```javascript\nfunction foo(a, b) {\n  var x = 'blah';\n  var y = (function (z) {\n    return z+3;\n  })(2);\n}\nfoo(1, 'wut', 3);\n```\n\n```javascript\nfunction foo(a, b) {\n    console.log(`Entering foo(${ a }, ${ b })`);\n    var x = 'blah';\n    var y = function (z) {\n        console.log(`Entering <anonymous function>(${ z })`);\n        return z + 3;\n    }(2);\n}\nfoo(1, 'wut', 3);\n```\n\nPara ello se modificó la función <code>addBeforeCode()</code> para que incluya un binding *params* en el string de salida del <code>console.log()</code>. Dicho binding es un array de elementos <code>String</code> construido a partir de la propiedad *params* del nodo <code>FunctionDeclaration</code>.\n\n## CLI con [Commander.js](https://www.npmjs.com/package/commander)\n\nSe importa <code>commander</code> y se obtiene el objeto <code>program</code> del mismo. Se invoca sobre ese objeto la configuración que queremos que tenga el ejecutable CLI. Luego invocamos su método <code>program.parse(process.argv)</code> para que procese la entrada de CLI y haga lo que lo hemos configurado para hacer.\n\n*   <code>.option()</code> para poder utilizar la opción *-o*\n*   <code>.argument()</code> para tener un argumento obligatorio.\n*   <code>.version()</code> recibe la versión del *package.json*\n*   <code>.action()</code> recibe un callback que tendrá tantos parámetros como argumento, salvo el último, que es un objeto options con los valores de cada opción.\n\n## Reto 1: Soportar funciones flecha\n\nLo que hacemos es utilizar <code>estraverse.traverse(ast, {enter:(node, parents) => {...}})</code> para recorrer el árbol de sintaxis abstracto (AST) nodo por nodo. Si se detecta que el corresponde a una declaración de función se le agrega una nueva sentencia a la misma. Es ahí donde entra <code>addBeforeCode()</code> para agregar dicho nodo.\n\n```js\n    (...)\n    estraverse.traverse(ast, {\n        enter: function(node, parent) {\n            if (/* si nodo declaración de función */) {\n                addBeforeCode(node);\n            }\n        }\n    });\n    (...)\n```\n\nEl problema está en que las funciones flecha son de tipo <code>ArrowFunctionDeclaration</code>, y ese nodo no está originalmente en la función, por lo que se le agrega.\n\n## Reto 2: Añadir el número de línea\n\nEspree permite obtener un objeto *loc* que contiene como propiedades *start* y *end*, los cuales tienen a su vez la propiedad *line* y *column*. Basta con utilizar *loc.start.line* en la función <code>addBeforeCode()</code>:\n\n```js\n(...)\nvar beforeCode = \"console.log(`Entering \" + name + `(${params})` +\n      ` at line ${node.loc.start.line}\\`);`;\n(...)\n```\n\nTras haber activado el objeto en la configuración de <code>espree.parse()</code>:\n\n```js\nconst ast = espree.parse(code, {ecmaVersion: 6, loc: true /* activamos el objeto loc */});\n```\n\n## Tests and Covering\n\n### Test results with mocha\n\n![sucessful test](docs/successful_test.PNG)\n\n### Code coverage using <code>nyc</code>\n\n![nyc result](docs/nyc.PNG)\n","readmeFilename":"README.md"}