gh-pages / com.nextfaze.devfun.category / DeveloperCategory

DeveloperCategory

@Target([AnnotationTarget.CLASS]) annotation class DeveloperCategory (source)

This annotation is optional, and is used to change the category’s name/order or the group of the functions defined in this class.

At compile time, a CategoryDefinition will be generated referencing the class with this annotation.

Inheritance

Categories can be specified at the class level and the function-level. Unset properties at the function level will use the class-level values.

However categories are “keyed” based on their name. Thus if a function declares a category with a different name, it will be considered a different category and will inherit values based on that one instead.

Note: Due to the way APT orders elements (in that it doesn’t) you may get non-deterministic inheritance if you redeclare values over multiple classes.

i.e. The order of “My Category” will be whatever APT provides first.

@DeveloperCategory("My Category", order = 10) class SomeClass
@DeveloperCategory("My Category", order = 20) class AnotherClass

Properties

All properties are optional.

Name

When value is undefined, the name is derived from the class name split by camel case. (e.g. “MyClass” → “My Class”).

Categories are merged at runtime by name (see below). They are case-sensitive (compared using standard equality checks). i.e. “MY CATEGORY” ≠ “My Category”

Since they are merged at runtime, declaring a category with the same name on multiple classes will create a single category with all the functions from those classes.

e.g. Change the name of a category to “Better Name”:

@DeveloperCategory("Better Name")
class MyClassWithAStupidName {
    @DeveloperFunction
    fun someFunction() = Unit // category="Better Name"
}

Merge classes to a single category:

@DeveloperCategory("My Category")
class SomeClass {
    @DeveloperFunction
    fun someFunction() = Unit // category="My Category"
}

@DeveloperCategory("My Category")
class AnotherClass {
    @DeveloperFunction
    fun anotherFunction() = Unit // category="My Category"
}

Group

Items in a category can be grouped (will be put under the same “group” heading) - this will happen automatically for the context aware “Context” category. e.g. “Context” = [“Current Activity” = , “My Fragment” = , “Another Fragment” = ]

A “Misc” group will be created for functions without a group if a category has one or more groups.

e.g. Grouping functions and overloading parent (class-defined) category definition:

@DeveloperCategory("My Category", group = "Some Group")
class SomeClass {
    @DeveloperFunction
    fun someFunction() = Unit // category="My Category", group="Some Group"

    @DeveloperFunction(category = DeveloperCategory(group = "Another Group"))
    fun anotherFunction() = Unit // category="My Category", group="Another Group"
}

@DeveloperCategory("My Category", group = "Another Group")
class AnotherClass {
    @DeveloperFunction
    fun anotherFunction() = Unit // category="My Category", group="Another Group"

    @DeveloperFunction(category = DeveloperCategory(group = "Special"))
    fun snowFlake() = Unit // category="My Category", group="Special"
}

Order

By default the category list is ordered by name. The order value can be used to adjust this. Categories with the same order are then ordered by name. i.e. ordering is by order (-∞ → +∞) then by name.

This is used by DevFun for the “Context” category (-10_1000) and the “Dev Fun” category (100_000).

If the order of a category is defined more than once, the first encountered non-null order value is used.

Contextual Vars

(experimental) At compile time that follow vars are available for use in value or group (also DeveloperFunction.value):

e.g.

@DeveloperCategory("Some Category", group = "Class: %CLASS_SN%")
annotation class MyCategory

@MyCategory
class MyClass {
    @DeveloperFunction
    fun someFun() = Unit // category="Some Category", group="Class: MyClass"
}

Custom Annotations

A “category” annotation is declared with @DeveloperAnnotation(developerCategory = true).

Simply declare the same fields with different defaults (they can also be omitted) to have a “grouping” category or what have you.

For an in-use example see demo annotation TestCat

Limitations

You cannot annotate interfaces at the moment due to the way Kotlin/KAPT handles annotations on functions in interfaces with default functions. This is intended to be handled in the future - feel free to post an issue or submit a PR.

Parameters

value - The name that to be shown for this category. If undefined the class name will be split by camel case. (e.g. “MyClass” → “My Class”)

group - Items in this class will be assigned this group.

order - Order of this category when listed. Ordering will be by order (-∞ → +∞) then by name (value)

See Also

DeveloperAnnotation

DeveloperFunction

DeveloperReference

Constructors

Name Summary
<init> DeveloperCategory(value: String = "", group: String = "", order: Int = 0)
This annotation is optional, and is used to change the category’s name/order or the group of the functions defined in this class.

Properties

Name Summary
group val group: String
Items in this class will be assigned this group.
order val order: Int
Order of this category when listed. Ordering will be by order (-∞ → +∞) then by name (value)
value val value: String
The name that to be shown for this category. If undefined the class name will be split by camel case. (e.g. “MyClass” → “My Class”)