{"id":17030082,"url":"https://github.com/rob-blackbourn/jetblack-operator-overloading","last_synced_at":"2025-04-12T12:11:42.119Z","repository":{"id":42766399,"uuid":"269272228","full_name":"rob-blackbourn/jetblack-operator-overloading","owner":"rob-blackbourn","description":"A babel plugin for operator overloading in JavaScript","archived":false,"fork":false,"pushed_at":"2023-03-05T04:02:25.000Z","size":443,"stargazers_count":27,"open_issues_count":3,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-26T06:51:11.642Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rob-blackbourn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-04T05:51:34.000Z","updated_at":"2025-03-14T23:40:06.000Z","dependencies_parsed_at":"2023-02-08T05:31:38.567Z","dependency_job_id":null,"html_url":"https://github.com/rob-blackbourn/jetblack-operator-overloading","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rob-blackbourn%2Fjetblack-operator-overloading","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rob-blackbourn%2Fjetblack-operator-overloading/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rob-blackbourn%2Fjetblack-operator-overloading/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rob-blackbourn%2Fjetblack-operator-overloading/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rob-blackbourn","download_url":"https://codeload.github.com/rob-blackbourn/jetblack-operator-overloading/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248565074,"owners_count":21125417,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-14T08:04:04.223Z","updated_at":"2025-04-12T12:11:42.097Z","avatar_url":"https://github.com/rob-blackbourn.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @jetblack/operator-overloading\n\nA Babel plugin for operator overloading.\n\nThere is a trivial template project [here](https://github.com/rob-blackbourn/example-operator-overloading).\n\nThis was based on an [idea](https://github.com/foxbenjaminfox/babel-plugin-overload)\nby [Benjamin Fox](https://github.com/foxbenjaminfox)\n\nThere are a number of great implementations of operator overloading including a\ncurrent [proposal](https://github.com/tc39/proposal-operator-overloading). This\nproposal is far more sophisticated than this implementation, but I had issues\nwith my use case. This is a very simple version that worked for me and might\nbe a good work-around for you while we wait for the proposal to be accepted.\n\n## Example\n\nThe following code adds two integers and then two points.\n\nThe directive at the start is required to enable the transformation.\n\n```javascript\n'operator-overloading enabled'\n\nclass Point {\n\n    constructor(x, y) {\n        this.x = x\n        this.y = y\n    }\n    \n    [Symbol.for('+')](other) {\n        const x = this.x + other.x\n        const y = this.y + other.y\n        return new Point(x, y)\n    }\n}\n\n// Built in operators still work.\nconst x1 = 2\nconst x2 = 3\nconst x3 = x1 + x2\nconsole.log(x3)\n\n// Overridden operators work!\nconst p1 = new Point(5, 5)\nconst p2 = new Point(2, 3)\nconst p3 = p1 + p2\nconsole.log(p3)\n```\nproduces the following output:\n```bash\n5\nPoint { x: 7, y: 8 }\n```\n\n## Status\n\nThis is the first babel plugin I have written, so your mileage may vary.\n\nI would appreciate any help!\n\n## Usage\n\n1. Make a new folder and create a package.json file.\n\n```bash\n~$ mkdir my-app\n~$ cd my-app\n~/my-app$ npm init -y\n```\n\n2. Install babel and the basic preset (also `@babel/cli` for easier testing).\n\n```bash\n~/my-app$ npm install --save-dev @babel/core @babel/preset-env @babel/cli\n```\n3. Install the operator overload plugin. Note that `\"node\": \"current\"` is specified in targets. The targets specified **must** support arrow functions.\n\n```bash\n~/my-app$ npm install --save-dev @jetblack/operator-overloading\n```\n4. Create a `.babelrc` file:\n```json\n{\n    \"presets\": [\n        [\n            \"@babel/preset-env\",\n            {\n                \"targets\" : {\n                    \"node\": \"current\"\n                }\n            }\n        ]\n    ],\n    \"plugins\": [\"module:@jetblack/operator-overloading\"]\n}\n```\n\n5. Write some code:\n\n```javascript\n'operator-overloading enabled'\n\nclass Point {\n\n    constructor(x, y) {\n        this.x = x\n        this.y = y\n    }\n    \n    [Symbol.for('+')](other) {\n        const x = this.x + other.x\n        const y = this.y + other.y\n        return new Point(x, y)\n    }\n}\n\nconst p1 = new Point(5, 5)\nconst p2 = new Point(2, 3)\nconst p3 = p1 + p2\nconsole.log(p3)\n```\n\n6. Run it with `babel-node`:\n\n```bash\n~/my-app$ ./node_modules/.bin/babel-node.cmd index.js\nPoint { x: 7, y: 8 }\n```\n\n## Description\n\nThe plugin wraps expressions in arrow functions. The following is produced for `x + y`.\n\n```javascript\n(() =\u003e {\n  'operator-overloading disabled';\n\n  return x !== undefined \u0026\u0026 x !== null \u0026\u0026 x[Symbol.for(\"+\")]\n    ? x[Symbol.for(\"+\")](y)\n    : x + y;\n})()\n```\n\nFor example the following code:\n```javascript\nlet x = 1, y = 2\nlet z = x + y\n```\ngets re-written as:\n```javascript\nlet x = 1, y = 2\nlet z = (() =\u003e {\n  return x !== undefined \u0026\u0026 x !== null \u0026\u0026 x[Symbol.for(\"+\")]\n    ? x[Symbol.for(\"+\")](y)\n    : x + y;\n})();\n```\n\nThis allows the creation of custom overrides such as:\n```javascript\nclass Point {\n\n    constructor(x, y) {\n        this.x = x\n        this.y = y\n    }\n    \n    [Symbol.For('+')](other) {\n        const x = this.x + other.x\n        const y = this.y + other.y\n        return new Point(x, y)\n    }\n}\n```\n\n## Options\n\nAs the plugin requires arrow functions the `@babel/preset-env` preset `targets` must support them.\n\nOperator overloading is disabled for all files by default.\n\nThis can be enabled globally in the `.babelrc`:\n```json\n{\n    \"presets\": [\n        [\n            \"@babel/preset-env\",\n            {\n                \"targets\" : {\n                    \"node\": \"current\"\n                }\n            }\n        ]\n    ],\n    \"plugins\": [\n        [\n            \"@jetblack/operator-overloading\",\n            {\n                \"enabled\": true\n            }\n        ]\n    ]\n}\n```\n\nIt can be enabled or disabled locally by including the `'operator-overloading'` directive at the start of a file or within a block.\n\n```javascript\n'operator-overloading disabled'\nlet a = 1\nlet b = 2\nlet c = a + b\n\n'operator-overloading enabled'\nlet x = Point(2, 4)\nlet y = Point(3, 5)\nlet z = x + y\n```\n\nUsing operator overloading transpilation will increase compilation and run time when enabled.\n\n## Unsupported operations\n\nNo transpilation will be applied to he following operators.\n\n- `typeof`\n- `===`\n- `!==`\n- `\u0026\u0026`\n- `||`\n- `instanceof`\n\n## Supported operations\n\n### Arithmetic\n\n- `+` addition `[Symbol.for('+')](other)`\n- `-` subtraction `[Symbol.for('-')](other)`\n- `*` multiplication `[Symbol.for('*')](other)`\n- `/` division `[Symbol.for('/')](other)`\n- `%` remainder `[Symbol.for('%')](other)`\n\n### Arithmetic Unary\n\n- `+`: plus `[Symbol.for('plus')]()`\n- `-`: minus `[Symbol.for('minus')]()`\n\n### Increment an Decrement\n- `++` increment `[Symbol.for('prefix-increment')]()` and `[Symbol.for('postfix-increment')]()`\n- `--` decrement `[Symbol.for('prefix-decrement')]()` and `[Symbol.for('postfix-decrement')]()`\n\n### Arithmetic Assignment\n\nArithmetic assignment reuses the overrides for arithmetic.\n\n- `+=` addition assignment `[Symbol.for('+')](other)`\n- `-=` subtraction assignment `[Symbol.for('-')](other)`\n- `*=` multiplication assignment `[Symbol.for('*')](other)`\n- `/=` division assignment `[Symbol.for('/')](other)`\n- `%=` remainder assignment `[Symbol.for('%')](other)`\n\n### Bitwise\n\n- `\u0026` bitwise and `[Symbol.for('\u0026')](other)`\n- `|` bitwise or `[Symbol.for('|')](other)`\n- `~` bitwise not `[Symbol.for('~')]()`\n- `^` bitwise xor `[Symbol.for('^')](other)`\n- `\u003c\u003c` bitwise shift left `[Symbol.for('\u003c\u003c')](other)`\n- `\u003e\u003e` bitwise sign propagating shift right `[Symbol.for('\u003e\u003e')](other)`\n- `\u003e\u003e\u003e` bitwise zero padding shift right `[Symbol.for('\u003e\u003e\u003e')](other)`\n\n### Bitwise Assignment\n\nBitwise assignment reuses the overrides for bitwise.\n\n- `\u0026=` bitwise and `[Symbol.for('\u0026')](other)`\n- `|=` bitwise or `[Symbol.for('|')](other)`\n- `~=` bitwise not `[Symbol.for('~')]()`\n- `^=` bitwise xor `[Symbol.for('^')](other)`\n- `\u003c\u003c=` bitwise shift left `[Symbol.for('\u003c\u003c')](other)`\n- `\u003e\u003e=` bitwise sign propagating shift right `[Symbol.for('\u003e\u003e')](other)`\n- `\u003e\u003e\u003e=` bitwise zero padding shift right `[Symbol.for('\u003e\u003e\u003e')](other)`\n\n### Others\n\n- `delete` delete property `[Symbol.for('delete')](key)`\n- `in` has property `[Symbol.for('in')](key)`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frob-blackbourn%2Fjetblack-operator-overloading","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frob-blackbourn%2Fjetblack-operator-overloading","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frob-blackbourn%2Fjetblack-operator-overloading/lists"}