{"id":20950580,"url":"https://github.com/dsx-tech/student-project-subtyping","last_synced_at":"2026-04-20T20:03:16.912Z","repository":{"id":82716703,"uuid":"241899387","full_name":"dsx-tech/student-project-subtyping","owner":"dsx-tech","description":"The subtypes check system based on Java annotation processing","archived":false,"fork":false,"pushed_at":"2020-06-05T07:50:45.000Z","size":154,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-13T05:19:42.057Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","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/dsx-tech.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-02-20T14:04:41.000Z","updated_at":"2020-06-05T07:49:25.000Z","dependencies_parsed_at":null,"dependency_job_id":"d5149819-f93a-4f34-9784-573e7e5d8f2b","html_url":"https://github.com/dsx-tech/student-project-subtyping","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dsx-tech/student-project-subtyping","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsx-tech%2Fstudent-project-subtyping","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsx-tech%2Fstudent-project-subtyping/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsx-tech%2Fstudent-project-subtyping/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsx-tech%2Fstudent-project-subtyping/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dsx-tech","download_url":"https://codeload.github.com/dsx-tech/student-project-subtyping/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsx-tech%2Fstudent-project-subtyping/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28038027,"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","status":"online","status_checked_at":"2025-12-25T02:00:05.988Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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-11-19T00:49:12.687Z","updated_at":"2025-12-25T21:01:24.227Z","avatar_url":"https://github.com/dsx-tech.png","language":"Java","readme":"# Java Subtyping\nA plugin for a javac which helps Java developers to avoid errors with usage of primitive types. The plugin introduces a pluggable type system based on Java annotation processing.    \n\nThe main features are listed below.\n- Declare custom types that are used to mark up local variables, fields, method parameters, and return values of methods.\n- Declare subtyping relation on custom types.\n- Prohibit the usage of custom types in unary and binary operations.\n- Check whether custom types are used correctly.    \n## How to enable the plugin\nTo enable the plugin download the [jar]() and follow current steps to enable annotation processing for [IntelliJ IDEA](https://www.jetbrains.com/help/idea/annotation-processors-support.html) or [Gradle](https://docs.gradle.org/current/userguide/java_plugin.html) project.   \n## How to use the plugin to prevent errors\nDeclaring custom types:\n```java\n@MetaType\nclass UserId {}\n\nclass AdultUserId extends UserId {}\n```\nAll custom types should be marked by the `@MetaType` annotation. Notice that if a supertype is declared with a `@MetaType` annotation, the subtype also has the annotation implicitly.   \n\nIf you want to declare variable or parameter with a custom type, use an annotation `@Type` with corresponding `.class` argument as in example below.\n```java\nclass IdSender {\n    void sendPersonId(@Type(AdultUserId.class) String id) {\n        // do something\n    }\n\n    void doSomething() {\n        //...\n        @Type(UserId.class)\n        String personId = \"personId\";\n\n        sendPersonId(personId); // error; incompatible types: \n                                // 'UserId' cannot be converted to 'AdultUserId'\n        //...\n    }\n}\n```\nBy default, the usage of annotated value is prohibited in binary and unary operation such as `+`, `-`, etc. To permit the type in operations use appropriate annotations such as `@Plus`, `@Minus`, etc. Notice that if a supertype is declared with the corresponding annotation, the subtype also has the annotation implicitly.    \n|`@Annotation`|Corresponding operations|\n|:------------|:-----------------------|\n|`@Plus`|`+`|\n|`@Minus`|`+`|\n|`@Divide`|`+`|\n|`@Multiply`|`+`|\n|`@Remainder`|`%`|\n|`@UnaryPlus`|`+`|\n|`@UnaryMinus`|`-`|\n|`@Increment`|`++`|\n|`@Decrement`|`--`|\n|`@BitwiseComplement`|`~`|\n|`@LeftShift`|`\u003c\u003c`|\n|`@RightShift`| `\u003e\u003e` |\n|`@UnsignedRightShift`|`\u003e\u003e\u003e`|\n|`@Equal`|`!=`, `==`, `\u003e`, `\u003c`, `\u003c=`, `\u003e=`|\n|`@And` | `\u0026` |\n|`@Or`|`|`|\n|`@Xor`|`^`|\n|`@ConditionalAnd`|`\u0026\u0026`|\n|`@ConditionalOr`|`||`|\n|`@LogicalComplement`|`!`|\n\n## Type inference and rules for correct use of the types    \nThe plugin enforces subtyping rules and permission in operations. \nA particular type can be safely used wherever its supertype is expected.\nThe type can be safety used in particular operation if the operation is permitted for the type.\nIn order to reduce the number of `@Type` annotations in the source code, the plugin can infer the type of the local variable, using type information obtained from the variable's initializer. \nMoreover, you can use _raw type_ variables (without custom type such as common variable) and literals to initialize variables of custom type, as well as arguments methods with custom type parameters. Example below demonstrate this.\n```java\nclass IdSender {\n    void sendPersonId(@Type(AdultUserId.class) String id) {\n        // do something\n    }\n\n    void doSomething() {\n        //...\n        @Type(UserId.class)\n        String personId = \"personId\";\n\n        sendPersonId(\"otherPersonId\"); // correct\n        //...\n    }\n}\n```\nIn arithmetic operations, the type of one of the operands must be a subtype of the other. \nAfter the plugin has checked this, the operand type is moved to the corresponding supertype of the other operand. \nThis behavior is the same as calculating the type of arithmetic expressions in Java.\n```java\nclass BankAccount { \n    @Type(Dollar.class)\n    private int val1 = 100;\n\n    @Type(Currency.class)\n    private int val2 = 100;\n\n    void evaluateSum() {\n        //... \n        int sum = val1 + val2; // variable sum has type Currency\n        //...\n    }\n}\n```\nWhen one of the operands in an arithmetic expression has a _raw type_, the entire expression loses its type and gets the _unknown type_. \nThis expression can be used as a common variable or argument, but it cannot be used as initializer for a custom type variable. \nThe example below demonstrate it.\n```java\nclass BankAccount { \n    @Type(Dollar.class)\n    private int val1 = 100;\n    \n    private int val2 = 100;\n\n    void evaluateSum() {\n        //... \n        int sum = val1 + val2; // variable sum has unknown type\n\n        @Type(Euro.class)\n        int val3 = sum; // error: cannot use an unknown type expression to initialize a custom type variable\n        //...\n    }\n}\n```\nSometimes you may want to initialize a variable or field with an incompatible type. \nFor example, when converting a currency. In this case, you can use an `@UnsafeCast` annotation. If you want to avoid a warning, you should use a corresponding argument. The example below demonstrate how you can do it.\n```java\nclass BankAccount { \n    @Type(Dollar.class)\n    private int val1 = 100;\n\n    @UnsafeCast(printWarning = false)\n    @Type(Euro.class)\n    private int val2 = val1 * 0.92;\n\n    void evaluateSum() {\n        //... \n    }\n}\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsx-tech%2Fstudent-project-subtyping","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdsx-tech%2Fstudent-project-subtyping","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsx-tech%2Fstudent-project-subtyping/lists"}