From 783c1840039e9a0f26bed493c88ccbf653ef719d Mon Sep 17 00:00:00 2001 From: Ian Wright Date: Mon, 8 Jul 2024 09:07:53 +0100 Subject: [PATCH 1/2] Converting to TS --- .babelrc | 2 +- .babelrc-test | 2 +- package-lock.json | 380 +++++++++--------- package.json | 10 +- src/instrumentation/AssignmentStatement.ts | 25 ++ src/instrumentation/FunctionCallStatement.ts | 43 ++ src/instrumentation/ProgramStatement.ts | 12 + src/instrumentation/ReturnValueStatement.ts | 52 +++ src/instrumentation/Statement.ts | 47 +++ src/plugin.ts | 16 + src/visitors/Functions.ts | 39 ++ src/visitors/types.ts | 3 + src/visitors/utils/getName.ts | 16 + src/visitors/utils/index.ts | 1 + .../AssignmentExpression.js | 0 src/{visitors => visitors_js}/Functions.js | 0 .../ReturnStatement.js | 0 .../UpdateExpression.js | 0 .../VariableDeclaration.js | 0 src/{visitors => visitors_js}/index.js | 0 .../utils/extractName.js | 0 .../utils/getDisplayValue.js | 0 .../utils/getLineNumber.js | 0 src/{visitors => visitors_js}/utils/index.js | 0 .../utils/isDebug.js | 0 src/{visitors => visitors_js}/utils/skip.js | 0 26 files changed, 455 insertions(+), 193 deletions(-) create mode 100644 src/instrumentation/AssignmentStatement.ts create mode 100644 src/instrumentation/FunctionCallStatement.ts create mode 100644 src/instrumentation/ProgramStatement.ts create mode 100644 src/instrumentation/ReturnValueStatement.ts create mode 100644 src/instrumentation/Statement.ts create mode 100644 src/plugin.ts create mode 100644 src/visitors/Functions.ts create mode 100644 src/visitors/types.ts create mode 100644 src/visitors/utils/getName.ts create mode 100644 src/visitors/utils/index.ts rename src/{visitors => visitors_js}/AssignmentExpression.js (100%) rename src/{visitors => visitors_js}/Functions.js (100%) rename src/{visitors => visitors_js}/ReturnStatement.js (100%) rename src/{visitors => visitors_js}/UpdateExpression.js (100%) rename src/{visitors => visitors_js}/VariableDeclaration.js (100%) rename src/{visitors => visitors_js}/index.js (100%) rename src/{visitors => visitors_js}/utils/extractName.js (100%) rename src/{visitors => visitors_js}/utils/getDisplayValue.js (100%) rename src/{visitors => visitors_js}/utils/getLineNumber.js (100%) rename src/{visitors => visitors_js}/utils/index.js (100%) rename src/{visitors => visitors_js}/utils/isDebug.js (100%) rename src/{visitors => visitors_js}/utils/skip.js (100%) diff --git a/.babelrc b/.babelrc index b0fe525..d905ad7 100644 --- a/.babelrc +++ b/.babelrc @@ -1,4 +1,4 @@ { - "presets": ["@babel/preset-env"], + "presets": ["@babel/preset-env", "@babel/preset-typescript"], "plugins": [] } diff --git a/.babelrc-test b/.babelrc-test index a427164..7a93718 100644 --- a/.babelrc-test +++ b/.babelrc-test @@ -1,4 +1,4 @@ { "presets": ["@babel/preset-env"], - "plugins": ["./src/babel-plugin-instrumentation"] + "plugins": ["./lib/plugin"] } diff --git a/package-lock.json b/package-lock.json index 8d699a9..617fbc0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "babelreverse-debugger", + "name": "babel-reverse-debugger", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "babelreverse-debugger", + "name": "babel-reverse-debugger", "version": "1.0.0", "license": "none", "dependencies": { @@ -14,10 +14,11 @@ "@babel/preset-env": "^7.24.5" }, "devDependencies": { - "@babel/helper-plugin-test-runner": "^7.24.1", - "@babel/types": "^7.24.5", + "@babel/preset-typescript": "^7.24.7", + "@babel/types": "^7.24.7", "@types/node": "^20.12.12", - "jest": "^29.7.0" + "jest": "^29.7.0", + "typescript": "^5.5.3" } }, "node_modules/@ampproject/remapping": { @@ -61,11 +62,11 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dependencies": { - "@babel/highlight": "^7.24.2", + "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" }, "engines": { @@ -110,11 +111,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.5.tgz", - "integrity": "sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", "dependencies": { - "@babel/types": "^7.24.5", + "@babel/types": "^7.24.7", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -124,11 +125,11 @@ } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -145,18 +146,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-check-duplicate-nodes": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-check-duplicate-nodes/-/helper-check-duplicate-nodes-7.22.5.tgz", - "integrity": "sha512-7QAOFIO853OUOVr7ILo9caP3+eb3dNsVzs9iNKr8xi4FIBMQOCN72mv2YENxjNEK/2q/DYlWNAZuTwFn+sJVbA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-compilation-targets": { "version": "7.23.6", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", @@ -173,18 +162,18 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.5.tgz", - "integrity": "sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-member-expression-to-functions": "^7.24.5", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.24.5", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", + "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", "semver": "^6.3.1" }, "engines": { @@ -226,80 +215,73 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-fixtures": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/helper-fixtures/-/helper-fixtures-7.24.4.tgz", - "integrity": "sha512-Mj/JSsgyZA98UEjalx0T5rhjib1KuFiirH6QuK7OdvF2Evdp63l3mJf/njhvifJL0afPXIJawAWbmNxLuKNq0Q==", - "dev": true, + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", "dependencies": { - "semver": "^6.3.1" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.5.tgz", - "integrity": "sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", + "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", "dependencies": { - "@babel/types": "^7.24.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", - "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dependencies": { - "@babel/types": "^7.24.0" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.5.tgz", - "integrity": "sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.24.3", - "@babel/helper-simple-access": "^7.24.5", - "@babel/helper-split-export-declaration": "^7.24.5", - "@babel/helper-validator-identifier": "^7.24.5" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -309,32 +291,20 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-test-runner": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-test-runner/-/helper-plugin-test-runner-7.24.1.tgz", - "integrity": "sha512-3tBZbUsWltC2TrNm7MyTSwsopBptReBJ3RHvk40EpmWU45252nxe/kvDu0BViy+VQuob2dTW2KUv8zroFnY5CA==", - "dev": true, + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", "dependencies": { - "@babel/helper-transform-fixture-test-runner": "^7.24.1" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.5.tgz", - "integrity": "sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", "engines": { "node": ">=6.9.0" } @@ -356,13 +326,13 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", - "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", + "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -372,78 +342,60 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.5.tgz", - "integrity": "sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dependencies": { - "@babel/types": "^7.24.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz", - "integrity": "sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", "dependencies": { - "@babel/types": "^7.24.5" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", - "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-transform-fixture-test-runner": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-transform-fixture-test-runner/-/helper-transform-fixture-test-runner-7.24.5.tgz", - "integrity": "sha512-BwcrwK+bnq37bqJnj/BrraUs4b2gxQ0GU6EgMckYNxeKNAeOkcXNxLrJaQE7PuJnDnHTyWSNW9Z6+U2UcI5hjA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.2", - "@babel/core": "^7.24.5", - "@babel/helper-check-duplicate-nodes": "^7.22.5", - "@babel/helper-fixtures": "^7.24.4", - "@jridgewell/trace-mapping": "^0.3.25", - "fs-readdir-recursive": "^1.1.0", - "jest-diff": "^29.6.4", - "lru-cache": "^5.1.1", - "make-dir": "^2.1.0" - }, + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz", - "integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", "engines": { "node": ">=6.9.0" } @@ -475,11 +427,11 @@ } }, "node_modules/@babel/highlight": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.5.tgz", - "integrity": "sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dependencies": { - "@babel/helper-validator-identifier": "^7.24.5", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -489,9 +441,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz", - "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", "bin": { "parser": "bin/babel-parser.js" }, @@ -691,12 +643,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz", - "integrity": "sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -800,12 +752,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.1.tgz", - "integrity": "sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", + "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1164,13 +1116,13 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz", - "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", + "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-simple-access": "^7.22.5" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1493,6 +1445,24 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.7.tgz", + "integrity": "sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-typescript": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-unicode-escapes": { "version": "7.24.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz", @@ -1659,6 +1629,25 @@ "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, + "node_modules/@babel/preset-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", + "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-typescript": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/regjsgen": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", @@ -1676,31 +1665,31 @@ } }, "node_modules/@babel/template": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", - "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.24.0", - "@babel/types": "^7.24.0" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.5.tgz", - "integrity": "sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==", - "dependencies": { - "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.24.5", - "@babel/parser": "^7.24.5", - "@babel/types": "^7.24.5", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1709,12 +1698,12 @@ } }, "node_modules/@babel/types": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.5.tgz", - "integrity": "sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", "dependencies": { - "@babel/helper-string-parser": "^7.24.1", - "@babel/helper-validator-identifier": "^7.24.5", + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -6287,6 +6276,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typescript": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", diff --git a/package.json b/package.json index d646565..035e028 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,10 @@ "description": "", "main": "index.js", "scripts": { + "build:lib": "babel src -d lib -x \".ts\"", + "build:types": "tsc --emitDeclarationOnly", + "check-types": "tsc --noEmit", + "run": "npx babel add.js --out-file out/add.js --quiet --config-file ./.babelrc-test", "build": "npx babel add.js --out-file out/add.js --quiet --config-file ./.babelrc-test", "debug": "export PLUGIN_DEBUG=1 && npx --node-options=--inspect-brk babel add.js --out-file out/add.js --quiet --config-file ./.babelrc-test", "start": "npm run build && node ./out/add.js --config-file ./.babelrc-test", @@ -17,9 +21,11 @@ "@babel/preset-env": "^7.24.5" }, "devDependencies": { - "@babel/types": "^7.24.5", + "@babel/preset-typescript": "^7.24.7", + "@babel/types": "^7.24.7", "@types/node": "^20.12.12", - "jest": "^29.7.0" + "jest": "^29.7.0", + "typescript": "^5.5.3" }, "jest": { "transformIgnorePatterns": [ diff --git a/src/instrumentation/AssignmentStatement.ts b/src/instrumentation/AssignmentStatement.ts new file mode 100644 index 0000000..91264f7 --- /dev/null +++ b/src/instrumentation/AssignmentStatement.ts @@ -0,0 +1,25 @@ +import type { VariableDeclaration, AssignmentExpression, UpdateExpression } from "@babel/types"; +import { Statement } from "./Statement"; + +type AssignmentNodeType = VariableDeclaration | AssignmentExpression | UpdateExpression; + +export class AssignmentStatement extends Statement { + public name: string; + public value: any; + public displayValue: any; + + constructor(nodeType: AssignmentNodeType["type"], name: string, lineNumber: number, displayValue: any, value: any) { + super(nodeType, lineNumber); + + this.name = name; + this.value = value; + this.displayValue = displayValue; + } + + log() { + console.debug("\x1b[33m%s\x1b[0m", this.lineNumber + ": Assignment " + name + " = " + JSON.stringify(this.displayValue)); + } +} + + + diff --git a/src/instrumentation/FunctionCallStatement.ts b/src/instrumentation/FunctionCallStatement.ts new file mode 100644 index 0000000..018f3e6 --- /dev/null +++ b/src/instrumentation/FunctionCallStatement.ts @@ -0,0 +1,43 @@ +import type { FunctionExpression, FunctionDeclaration, ArrowFunctionExpression, ObjectMethod, ClassMethod } from "@babel/types"; +import { Statement } from "./Statement"; + +type FunctionNodeType = FunctionExpression | FunctionDeclaration | ArrowFunctionExpression | ObjectMethod | ClassMethod; + +export class FunctionCallStatement extends Statement { + public branch: Statement; + public name: string; + public args: Record; + + /** + * Construct a new FunctionCall Statement + * @param nodeType The type of the AST Node + * @param name The name of the function called + * @param lineNumber The line number in the code that this statement corresponds to + * @param args The arguments passed to the function + */ + constructor(nodeType: FunctionNodeType["type"], name: string, lineNumber: number, args: Record) { + super(nodeType, lineNumber); + + this.name = name; + this.args = args; + } + + /** + * Add a new statement to the chain + * @param {Statement} statement The statement to add + * @return {Statement} The newly added statement + */ + add(statement: Statement): Statement { + this.branch = statement; + + // When a function is called we go deeper in the stack + statement.depth = this.depth + 1; + statement.prev = this; + + return statement; + } + + log() { + console.debug("\x1b[32m%s\x1b[0m", this.lineNumber + ": Function Call " + this.name + "(" + JSON.stringify(this.args) + ")"); + } +} diff --git a/src/instrumentation/ProgramStatement.ts b/src/instrumentation/ProgramStatement.ts new file mode 100644 index 0000000..d7509d3 --- /dev/null +++ b/src/instrumentation/ProgramStatement.ts @@ -0,0 +1,12 @@ +import { Statement } from "./Statement"; + +/** + * Represents the entry point into the program + */ +export class ProgramStatement extends Statement { + constructor() { + super("Program", 0); + } + + log() {} +} diff --git a/src/instrumentation/ReturnValueStatement.ts b/src/instrumentation/ReturnValueStatement.ts new file mode 100644 index 0000000..2dea69b --- /dev/null +++ b/src/instrumentation/ReturnValueStatement.ts @@ -0,0 +1,52 @@ +import type { ReturnStatement } from "@babel/types"; +import { Statement } from "./Statement"; + +export class ReturnValueStatement extends Statement { + public value: any; + + /** + * Construct a new FunctionCall Statement + * @param nodeType The type of the AST Node + * @param lineNumber The line number in the code that this statement corresponds to + * @param value The value being returned + */ + constructor(nodeType: ReturnStatement["type"], lineNumber: number, value: any) { + super(nodeType, lineNumber); + this.value = value; + } + + /** + * Add a new statement to the chain + * @param {Statement} statement The statement to add + * @return {Statement} The newly added statement + */ + add(statement: Statement): Statement { + this.next = statement; + + // When we return from a function we go back up the stack + statement.depth = this.depth - 1; + statement.branch_rewind = this; + + // Set the previous statement, to the last at the same depth + statement.prev = this.findPrevious(); + + return statement; + } + + /** + * Find the previous Node that was at a higher depth + */ + findPrevious() { + let searchItem = this.prev; + + while (searchItem?.depth !== this.depth - 1) { + searchItem = searchItem?.prev; + } + + return searchItem; + } + + log() { + console.log("\x1b[34m%s\x1b[0m", this.lineNumber + ": Returning " + this.value); + } +} diff --git a/src/instrumentation/Statement.ts b/src/instrumentation/Statement.ts new file mode 100644 index 0000000..cd91390 --- /dev/null +++ b/src/instrumentation/Statement.ts @@ -0,0 +1,47 @@ +import type { Node } from "@babel/types"; +import { stat } from "fs"; + +export abstract class Statement { + // Next statement in the chain + public next?: Statement; + + // Previous statement in the chain + public prev?: Statement; + + // The call stack depth of the current statement + public depth: number = 0; + + // This is used to allow stepping backwards into a function call from a return statement + public branch_rewind?: Statement; + + // The type of this AST Node + protected nodeType: Node["type"] | "Program"; + + protected lineNumber: number; + + /** + * Construct a new Node + * @param nodeType The type of the AST Node + * @param lineNumber The line number in the code that this statement corresponds to + */ + constructor(nodeType: Node["type"] | "Program", lineNumber: number) { + this.nodeType = nodeType; + } + + /** + * Add a new statement to the chain + * @param {Statement} statement The statement to add + * @return {Statement} The newly added statement + */ + add(statement: Statement): Statement { + this.next = statement; + + // Update the next node to point back to this one + statement.prev = this; + statement.depth = this.depth; + + return statement; + } + + abstract log(): void; +} diff --git a/src/plugin.ts b/src/plugin.ts new file mode 100644 index 0000000..8208707 --- /dev/null +++ b/src/plugin.ts @@ -0,0 +1,16 @@ +import { PluginObj } from '@babel/core'; +import { declare } from '@babel/helper-plugin-utils'; + +export default declare( + (api: any): PluginObj => { + api.assertVersion(7); + console.log(api.parse); + + return { + visitor: { + FunctionExpression(path) { + console.log(path.node.id?.name); + } + } + } + }); diff --git a/src/visitors/Functions.ts b/src/visitors/Functions.ts new file mode 100644 index 0000000..3685dc2 --- /dev/null +++ b/src/visitors/Functions.ts @@ -0,0 +1,39 @@ +import { NodePath } from "@babel/core"; +import type { FunctionExpression, FunctionDeclaration, ArrowFunctionExpression, ObjectMethod, ClassMethod } from "@babel/types"; + +import * as utils from "./utils"; + +type PathType = NodePath; + +function getName(path: PathType) { + const { node, parent } = path; + + const name = utils.getName(path); + if (name) { + return name; + } + + // Attempt to handle arrow functions inside a class + // class scientificCalculator { + // cos = (degrees) => Math.cos(degress * (Math.PI / 180)) + // } + if (["ArrowFunctionExpression", "FunctionExpression"].includes(node.type)) { + const isInDefineProperty = parent.type === "CallExpression" && parent.callee?.name === "_defineProperty"; + const isInCaptureAssignment = parent.type === "CallExpression" && parent.callee?.name === "___captureAssignment"; + + // Force this function to be skipped as we end up with duplicate instrumentation calls + // so we'll just use the ArrowFunctionExpression instead + if (node.type === "FunctionExpression" && (isInDefineProperty)) { + return "___"; + } + + if (node.type === "ArrowFunctionExpression" && (isInDefineProperty || isInCaptureAssignment)) { + return parent.arguments?.[1]?.value; + } + } +} + + +export function visit(t, path: PathType) { + const name = getName(path); +} diff --git a/src/visitors/types.ts b/src/visitors/types.ts new file mode 100644 index 0000000..5758264 --- /dev/null +++ b/src/visitors/types.ts @@ -0,0 +1,3 @@ +export interface IVisitor { + +} diff --git a/src/visitors/utils/getName.ts b/src/visitors/utils/getName.ts new file mode 100644 index 0000000..b56eeda --- /dev/null +++ b/src/visitors/utils/getName.ts @@ -0,0 +1,16 @@ +import { NodePath } from "@babel/core"; + +/** + * Attempt to extract the name of the current node + * @param {} path The path to the current node + * @return {string|undefined} The name of the node + */ +export function getName(path: NodePath): string | undefined { + const { node, parent } = path; + + return node.id?.name ?? + node.key?.name ?? + parent?.id?.name ?? + parent?.key?.name; +} + diff --git a/src/visitors/utils/index.ts b/src/visitors/utils/index.ts new file mode 100644 index 0000000..40eb593 --- /dev/null +++ b/src/visitors/utils/index.ts @@ -0,0 +1 @@ +export * from "./getName"; diff --git a/src/visitors/AssignmentExpression.js b/src/visitors_js/AssignmentExpression.js similarity index 100% rename from src/visitors/AssignmentExpression.js rename to src/visitors_js/AssignmentExpression.js diff --git a/src/visitors/Functions.js b/src/visitors_js/Functions.js similarity index 100% rename from src/visitors/Functions.js rename to src/visitors_js/Functions.js diff --git a/src/visitors/ReturnStatement.js b/src/visitors_js/ReturnStatement.js similarity index 100% rename from src/visitors/ReturnStatement.js rename to src/visitors_js/ReturnStatement.js diff --git a/src/visitors/UpdateExpression.js b/src/visitors_js/UpdateExpression.js similarity index 100% rename from src/visitors/UpdateExpression.js rename to src/visitors_js/UpdateExpression.js diff --git a/src/visitors/VariableDeclaration.js b/src/visitors_js/VariableDeclaration.js similarity index 100% rename from src/visitors/VariableDeclaration.js rename to src/visitors_js/VariableDeclaration.js diff --git a/src/visitors/index.js b/src/visitors_js/index.js similarity index 100% rename from src/visitors/index.js rename to src/visitors_js/index.js diff --git a/src/visitors/utils/extractName.js b/src/visitors_js/utils/extractName.js similarity index 100% rename from src/visitors/utils/extractName.js rename to src/visitors_js/utils/extractName.js diff --git a/src/visitors/utils/getDisplayValue.js b/src/visitors_js/utils/getDisplayValue.js similarity index 100% rename from src/visitors/utils/getDisplayValue.js rename to src/visitors_js/utils/getDisplayValue.js diff --git a/src/visitors/utils/getLineNumber.js b/src/visitors_js/utils/getLineNumber.js similarity index 100% rename from src/visitors/utils/getLineNumber.js rename to src/visitors_js/utils/getLineNumber.js diff --git a/src/visitors/utils/index.js b/src/visitors_js/utils/index.js similarity index 100% rename from src/visitors/utils/index.js rename to src/visitors_js/utils/index.js diff --git a/src/visitors/utils/isDebug.js b/src/visitors_js/utils/isDebug.js similarity index 100% rename from src/visitors/utils/isDebug.js rename to src/visitors_js/utils/isDebug.js diff --git a/src/visitors/utils/skip.js b/src/visitors_js/utils/skip.js similarity index 100% rename from src/visitors/utils/skip.js rename to src/visitors_js/utils/skip.js From 2500c4ad5e612867143401e17aedbaf8fcfeef24 Mon Sep 17 00:00:00 2001 From: Ian Wright Date: Wed, 17 Jul 2024 10:47:13 +0100 Subject: [PATCH 2/2] wip --- lib/plugin.js | 19 ++++++++++++ lib/visitors/Functions.js | 1 + lib/visitors/types.js | 5 +++ src/visitors/Functions.ts | 48 ++++++++++++++++++++++++++++- src/visitors/utils/getLineNumber.ts | 8 +++++ src/visitors/utils/getName.ts | 2 +- src/visitors/utils/index.ts | 16 +++++++++- src/visitors/utils/isDebug.ts | 1 + 8 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 lib/plugin.js create mode 100644 lib/visitors/Functions.js create mode 100644 lib/visitors/types.js create mode 100644 src/visitors/utils/getLineNumber.ts create mode 100644 src/visitors/utils/isDebug.ts diff --git a/lib/plugin.js b/lib/plugin.js new file mode 100644 index 0000000..7d979c6 --- /dev/null +++ b/lib/plugin.js @@ -0,0 +1,19 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; +var _helperPluginUtils = require("@babel/helper-plugin-utils"); +var _default = exports["default"] = (0, _helperPluginUtils.declare)(function (api) { + api.assertVersion(7); + console.log(api.parse); + return { + visitor: { + FunctionExpression: function FunctionExpression(path) { + var _path$node$id; + console.log((_path$node$id = path.node.id) === null || _path$node$id === void 0 ? void 0 : _path$node$id.name); + } + } + }; +}); \ No newline at end of file diff --git a/lib/visitors/Functions.js b/lib/visitors/Functions.js new file mode 100644 index 0000000..9a390c3 --- /dev/null +++ b/lib/visitors/Functions.js @@ -0,0 +1 @@ +"use strict"; \ No newline at end of file diff --git a/lib/visitors/types.js b/lib/visitors/types.js new file mode 100644 index 0000000..430afc1 --- /dev/null +++ b/lib/visitors/types.js @@ -0,0 +1,5 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); \ No newline at end of file diff --git a/src/visitors/Functions.ts b/src/visitors/Functions.ts index 3685dc2..ccef72c 100644 --- a/src/visitors/Functions.ts +++ b/src/visitors/Functions.ts @@ -5,6 +5,21 @@ import * as utils from "./utils"; type PathType = NodePath; +/** + * Should we skip this particular AST node? + */ +function skip(name, path) { + // Our internal functions + if (name && name.startsWith("___")) return true; + + // Code that we don't have any line numbers for + if (path.node.loc == undefined || path.node.loc.start === undefined || path.node.loc.start.line === undefined) { + return true; + } + + return false; +} + function getName(path: PathType) { const { node, parent } = path; @@ -18,7 +33,9 @@ function getName(path: PathType) { // cos = (degrees) => Math.cos(degress * (Math.PI / 180)) // } if (["ArrowFunctionExpression", "FunctionExpression"].includes(node.type)) { + // @ts-expect-error const isInDefineProperty = parent.type === "CallExpression" && parent.callee?.name === "_defineProperty"; + // @ts-expect-error const isInCaptureAssignment = parent.type === "CallExpression" && parent.callee?.name === "___captureAssignment"; // Force this function to be skipped as we end up with duplicate instrumentation calls @@ -28,12 +45,41 @@ function getName(path: PathType) { } if (node.type === "ArrowFunctionExpression" && (isInDefineProperty || isInCaptureAssignment)) { + // @ts-expect-error return parent.arguments?.[1]?.value; } } } -export function visit(t, path: PathType) { +export function visit(t, path: PathType, ASTType: string) { const name = getName(path); + if (skip(name, path)) { return; } + + utils.isDebug && console.debug("functions.inject"); + + const lineNumber = utils.getLineNumber(path); + const parameters = path.node.params.map(p => + t.objectProperty(t.identifier(p.name), t.identifier(p.name)) + ); + + const captureStart = t.expressionStatement( + t.callExpression(t.identifier("___instrumentFunction"), [ + t.stringLiteral(ASTType), + t.stringLiteral(name || "anonymous"), // Use extracted name or default to "anonymous" + t.numericLiteral(lineNumber), + t.objectExpression(parameters) + ]) + ); + + if (t.isBlockStatement(path.node.body)) { + path.get("body").unshiftContainer("body", captureStart); + } else { + const body = t.blockStatement([captureStart, t.returnStatement(path.node.body)]); + path.get('body').replaceWith(body); + } + + // @ts-expect-error: This is a field that we're adding in + // Mark this node as processed to avoid re-processing + path.node.__processed = true; } diff --git a/src/visitors/utils/getLineNumber.ts b/src/visitors/utils/getLineNumber.ts new file mode 100644 index 0000000..21dcce9 --- /dev/null +++ b/src/visitors/utils/getLineNumber.ts @@ -0,0 +1,8 @@ +/** + * Obtain the current line number for the node + * @param {} path The path to the current node + * @return {number} The line number + */ +export default function getLineNumber(path) { + return path.node.loc?.start?.line ?? path.parent.loc?.start?.line; +} diff --git a/src/visitors/utils/getName.ts b/src/visitors/utils/getName.ts index b56eeda..cf9b88a 100644 --- a/src/visitors/utils/getName.ts +++ b/src/visitors/utils/getName.ts @@ -5,7 +5,7 @@ import { NodePath } from "@babel/core"; * @param {} path The path to the current node * @return {string|undefined} The name of the node */ -export function getName(path: NodePath): string | undefined { +export default function getName(path: NodePath): string | undefined { const { node, parent } = path; return node.id?.name ?? diff --git a/src/visitors/utils/index.ts b/src/visitors/utils/index.ts index 40eb593..eec89e9 100644 --- a/src/visitors/utils/index.ts +++ b/src/visitors/utils/index.ts @@ -1 +1,15 @@ -export * from "./getName"; +import isDebug from "./isDebug"; +import getName from "./getName"; +// const skip = require("./skip"); +import getLineNumber from "./getLineNumber"; +// const extractName = require("./extractName"); +// const getDisplayValue = require("./getDisplayValue"); + +export { + isDebug, + getName, + // skip, + getLineNumber, + // extractName, + // getDisplayValue, +}; diff --git a/src/visitors/utils/isDebug.ts b/src/visitors/utils/isDebug.ts new file mode 100644 index 0000000..f6bf4db --- /dev/null +++ b/src/visitors/utils/isDebug.ts @@ -0,0 +1 @@ +export default const IS_DEBUG = process.env.PLUGIN_DEBUG === '1';