{"id":13694462,"url":"https://github.com/banterly91/Java-Builder-Guided-Completion-Intellij-Plugin","last_synced_at":"2025-05-03T03:31:42.233Z","repository":{"id":57736969,"uuid":"301209110","full_name":"banterly91/Java-Builder-Guided-Completion-Intellij-Plugin","owner":"banterly91","description":null,"archived":false,"fork":false,"pushed_at":"2021-01-22T20:43:51.000Z","size":446,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-11-12T21:38:40.407Z","etag":null,"topics":["builder","intellij-plugin","java"],"latest_commit_sha":null,"homepage":"https://www.banterly.net/2021/01/26/writing-my-first-intellij-plugin/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/banterly91.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-10-04T19:22:59.000Z","updated_at":"2023-06-17T19:14:32.000Z","dependencies_parsed_at":"2022-08-24T05:21:07.904Z","dependency_job_id":null,"html_url":"https://github.com/banterly91/Java-Builder-Guided-Completion-Intellij-Plugin","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":"JetBrains/intellij-platform-plugin-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banterly91%2FJava-Builder-Guided-Completion-Intellij-Plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banterly91%2FJava-Builder-Guided-Completion-Intellij-Plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banterly91%2FJava-Builder-Guided-Completion-Intellij-Plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banterly91%2FJava-Builder-Guided-Completion-Intellij-Plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/banterly91","download_url":"https://codeload.github.com/banterly91/Java-Builder-Guided-Completion-Intellij-Plugin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252137576,"owners_count":21700241,"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":["builder","intellij-plugin","java"],"created_at":"2024-08-02T17:01:32.850Z","updated_at":"2025-05-03T03:31:41.967Z","avatar_url":"https://github.com/banterly91.png","language":"Java","funding_links":[],"categories":["Java"],"sub_categories":[],"readme":"# Java Builder Pattern Guided Completion Intellij Plugin\n\n![Build](https://github.com/banterly91/Builder-Guided-Completion-Plugin/workflows/Build/badge.svg)\n[![Version](https://img.shields.io/jetbrains/plugin/v/15695.svg)](https://plugins.jetbrains.com/plugin/15695)\n[![Downloads](https://img.shields.io/jetbrains/plugin/d/15695.svg)](https://plugins.jetbrains.com/plugin/15695)\n\n\n\u003c!-- Plugin description --\u003e\nThis Intellij Plugin is designed to help you navigate the invocation of a [Builder](https://refactoring.guru/design-patterns/builder) class as part of the pattern with the same name.\n\nIt allows the creator of the Builder API to specify what methods are mandatory, what methods can be invoked more than once and more!\n\nThe user of the Builder API will have a guided experience through the auto-completion popup which will mark what methods are required, optional or invalid.\n\nThe home of the project together with its documentation is at https://github.com/banterly91/Java-Builder-Guided-Completion-Intellij-Plugin.\n\u003c!-- Plugin description end --\u003e\n![Completion example](docs/images/example1AutoCompletion.PNG)\n\n## Usage\nAfter setting up this plugin(see bellow), 3 annotations will be available for the Builder API author, and they should be used as follows:\n##### @BuilderClass\nUsed to mark the builder class\n```java\n@BuilderClass\npublic class Builder{}\n```\n##### @BuilderMethod\nUsed to mark the public methods of the Builder class which will be used to pass the data required to build the target object.\n\nThis annotation comes with 3 attributes:\n\n- ***type*** - it has 2 possible values\n  - ***BuilderMethod.Type.MANDATORY*** to mark the methods that must be called in order for the Builder to have enough data to construct a valid object.\n  - ***BuilderMethodType.OPTIONAL*** to mark methods as optional, the object can be constructed without them being invoked. This is the default value for the attribute.\n```java\n@BuilderClass\npublic class Builder {\n// other Builder class code\n\n@BuilderMethod(type = BuilderMethod.Type.MANDATORY)\npublic Builder withMandatoryValue(int mandatoryValue) {\n// mandatory method code\n}\n\n@BuilderMethod(type = BuilderMethod.Type.OPTIONAL)\npublic Builder withOptionalValue(int optionalValue) {\n// optional method code\n}\n}\n```\n\n\n- ***repeatable***\n  - Used to mark the methods that can be called multiple times(e.g. a method that adds items to a list field).\n  - This is a boolean attribute, so the user can give it either ***true*** or ***false*** as a valid value.\n  -  The default is ***false***.\n\n```java\n@BuilderClass\npublic class Builder {\n// other Builder class code\n\n@BuilderMethod(type = BuilderMethod.Type.MANDATORY, repeatable = true)\npublic Builder withMandatoryValue(int mandatoryValue) {\n// mandatory method code\n}\n\n@BuilderMethod(repeatable = true)\npublic Builder withOptionalValue(int optionalValue) {\n// optional method code\n}\n}\n```\n\n- ***incompatibleWith***\n  \n  We can have cases where two methods could both satisfy a mandatory requirement, so after one is called the other one should be considered invalid.\n  Consider the following case:\n  \n```java\n@BuilderClass\npublic class Builder { \n    List\u003cInteger\u003e values = new ArrayList\u003c\u003e();\n      \n    @BuilderMethod(ype = BuilderMethod.Type.MANDATORY, repeatable = true)\n    public Builder withValue(int value){\n        values.add(value);\n        return this;\n    }   \n  \n    @BuilderMethod(ype = BuilderMethod.Type.MANDATORY, repeatable = false)\n    public Builder withValues(List\u003cInteger\u003e values){\n        values.addAll(values);\n        return this;\n    }   \n}\n```\nIn the above case it makes sense that if `withValues()` is called, we should not be required to call `withValue()` and the other way around.\nFor this kind of cases we introduced this attribute. It takes a list of strings representing the name of the methods which, if invoked, will make the annotated method be rendered as invalid.\nTo handle the above case we can use the following:\n\n```java\n@BuilderClass\npublic class Builder { \n    List\u003cInteger\u003e values = new ArrayList\u003c\u003e();\n      \n    @BuilderMethod(ype = BuilderMethod.Type.MANDATORY, repeatable = true, incompatbileWith = {\"withValues\"})\n    public Builder withValue(int value){\n        values.add(value);\n        return this;\n    }   \n  \n    @BuilderMethod(ype = BuilderMethod.Type.MANDATORY, repeatable = false, incompatibleWith = {\"withValue\"})\n    public Builder withValues(List\u003cInteger\u003e values){\n        values.addAll(values);\n        return this;\n    }   \n}\n```\nNow whenever one of them will be invoked, the other one will be shown as invalid.\n\n##### @BuildMethod\nUsed to mark the build method of a builder.\n```java\n@BuilderClass\npublic class Builder {\n// other Builder class code\n\n@BuildMethod\npublic ClassWithBuilder build(){\n// build method code\n}\n}\n```\n\nAfter annotating the Builder class, the completion popup will categorize all annotated public methods in 3 groups:\n* required methods: will be at the top of the list and presented in bold and underlined \n* optional methods: will be after the required methods in the list and presented only in bold with no underline\n* invalid methods: will be at the bottom of the list and presented with a strikeout line\n\nThe completion order provided by Intellij might be a little different from what was described above I and will work in the future to make it consistent, but the Intellij API is not very friendly regarding this topic.\n\nIn general the grouping is done as you might expect, but for those curious the exact rules are these:\n* **required methods**\n    * methods marked with `@BuilderMethod(type = BuilderMethod.Type.MANDATORY)` that have not been invoked yet\n    * method marked with `@BuildMethod` when all required methods have been invoked\n* **optional methods**\n    * methods marked with `@BuilderMethod(type = BuilderMethod.Type.OPTIONAL)`\n    * methods marked with `@BuilderMethod(type = BuilderMethod.Type.MANDATORY, repeatable = true)` that have been invoked at least once\n    * methods marked with `@BuilderMethod(type = BuilderMethod.Type.OPTIONAL, repeatable = true)`, regardless of the number of invocations\n* **invalid methods**\n    * methods having the `incompatibleWith` attribute set, and the methods specified as arguments being already invoked. \n    * annotated methods not having the `repeatable` attribute set and have already been invoked\n    * method marked with `@BuildMethod` when not all methods marked with `@BuilderMethod(type = BuilderMethod.Type.MANDATORY)` have been invoked\n\n## Installation\n\n- Using IDE built-in plugin system:\n  \n  \u003ckbd\u003ePreferences\u003c/kbd\u003e \u003e \u003ckbd\u003ePlugins\u003c/kbd\u003e \u003e \u003ckbd\u003eMarketplace\u003c/kbd\u003e \u003e \u003ckbd\u003eSearch for \"mandatory-builder-fields-intellij-plugin\"\u003c/kbd\u003e \u003e\n  \u003ckbd\u003eInstall Plugin\u003c/kbd\u003e\n  \n- Manually:\n\n  Download the [latest release](https://github.com/banterly91/Builder-Guided-Completion-Plugin/releases/latest) and install it manually using\n  \u003ckbd\u003ePreferences\u003c/kbd\u003e \u003e \u003ckbd\u003ePlugins\u003c/kbd\u003e \u003e \u003ckbd\u003e⚙️\u003c/kbd\u003e \u003e \u003ckbd\u003eInstall plugin from disk...\u003c/kbd\u003e\n\n## Required Dependency\nYou need to add a dependency in order to have the annotations available in your project.\n\nIf you are using Maven, you can add this to your pom.xml:\n```xml\n\u003cdependencies\u003e\n\t\u003cdependency\u003e\n\t\t\u003cgroupId\u003enet.banterly\u003c/groupId\u003e\n\t\t\u003cartifactId\u003ebuilder-guided-completion-annotations\u003c/artifactId\u003e\n\t\t\u003cversion\u003e0.1.5\u003c/version\u003e\n\t\u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\nIf you are using Gradle you can add the following to your build.gradle.kts :\n```kotlin\ndependencies {\n    implementation(group = \"net.banterly\", name = \"builder-guided-completion-annotations\", version = \"0.1.5\")\n}\n```\n\n## Roadmap\nThis is just the first version of the plugin, so it comes with a couple of limitations which are planned to be fixed, especially if this plugin starts getting some usage.\nThe following will likely be included in a future release:\n\n##### Integrate with Project Lombok\nProject Lombok is widely used in the java community for automatically generating a lot of Java boilerplate code. This includes generating a lot of Builder classes. I would very much like to make this plugin work together with what Project Lombok provides. Actually part of the inspiration for this work came from one of their posts: https://github.com/rzwitserloot/lombok/wiki/FEATURE-IDEA:-%22Mandatory%22-fields-with-@Builder\n\n##### Advanced Builder Guidance\nWe could have cases where a builder could have multiple construction paths. For example if `methodA` is called then we can call only `methodB` on the builder, but if `methodC` is called then only `methodD` can be further called on the Builder. \n\n##### Show Warnings\nIf an invalid method is invoked, I would like that to show of as a warning level issue in the IDE.\n\n##### Fix Inconsistent Sorting\nAs mentioned above this issue can appear from time to time and work is planned to fix it.\n\n##### Other Issues requested by users\nIf there are any other issues that are requested by the users, they will get priority first. \n\nIf anyone wants to contribute via Pull Requests please do so.\n\n---\nPlugin based on the [IntelliJ Platform Plugin Template][template].\n\n[template]: https://github.com/JetBrains/intellij-platform-plugin-template\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbanterly91%2FJava-Builder-Guided-Completion-Intellij-Plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbanterly91%2FJava-Builder-Guided-Completion-Intellij-Plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbanterly91%2FJava-Builder-Guided-Completion-Intellij-Plugin/lists"}