feat: add final param in HikageView, HikageViewDeclaration

This commit is contained in:
2025-08-23 22:39:35 +08:00
parent 8e25430d68
commit 76df8fa06c
5 changed files with 50 additions and 33 deletions

View File

@@ -139,12 +139,13 @@ Hikage can automatically generate the `Hikageable` function corresponding to the
You can add the `HikageView` annotation on your custom `View` to mark it as a Hikage layout component.
| Parameter Name | Description |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `lparams` | LayoutParams `Class` object, if your custom `View` is a subclass of `ViewGroup`, you can declare or leave it blank to use the default value |
| `alias` | The alias of the layout component, that is, the function name to be generated, gets the name of the current Class by default |
| `requireInit` | Whether to fill in the initialization method block of the layout, the default is the omitted parameters |
| `requirePerformer` | Whether to fill in the `performer` method block of the layout, the default is an omitted parameter, which only takes effect when your custom `View` is a subclass of `ViewGroup` |
| Parameter Name | Description |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `lparams` | LayoutParams `Class` object, if your custom `View` is a subclass of `ViewGroup`, you can declare or leave it blank to use the default value |
| `alias` | The alias of the layout component, that is, the function name to be generated, gets the name of the current Class by default |
| `requireInit` | Whether to fill in the initialization method block of the layout, the default is the omitted parameters |
| `requirePerformer` | Whether to fill in the `performer` method block of the layout, the default is an omitted parameter, which only takes effect when your custom `View` is a subclass of `ViewGroup` |
| `final` | Whether to declare the layout as "final layout", the default is false, that is, whether this layout is `ViewGroup` or its subclasses will not generate the `performer` method block. After set to `true`, `lparams` and `requirePerformer` will no longer be valid. |
> The following example
@@ -177,13 +178,14 @@ Hikageable {
Hikage can also automatically generate layout component functions for the `View` component provided by third parties, and you can use the `HikageViewDeclaration` annotation to complete it.
| Parameter Name | Description |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `view` | Class object of layout component that needs to be declared |
| `lparams` | LayoutParams `Class` object, if your custom `View` is a subclass of `ViewGroup`, you can declare or leave it blank to use the default value |
| `alias` | The alias of the layout component, that is, the name of the function to be generated, obtains the name of the `view` Class by default |
| `requireInit` | Whether to fill in the initialization method block of the layout, the default is the omitted parameters |
| `requirePerformer` | Whether to fill in the `performer` method block of the layout, the default is an omitted parameter, which only takes effect when your custom `View` is a subclass of `ViewGroup` |
| Parameter Name | Description |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `view` | Class object of layout component that needs to be declared |
| `lparams` | LayoutParams `Class` object, if your custom `View` is a subclass of `ViewGroup`, you can declare or leave it blank to use the default value |
| `alias` | The alias of the layout component, that is, the name of the function to be generated, obtains the name of the `view` Class by default |
| `requireInit` | Whether to fill in the initialization method block of the layout, the default is the omitted parameters |
| `requirePerformer` | Whether to fill in the `performer` method block of the layout, the default is an omitted parameter, which only takes effect when your custom `View` is a subclass of `ViewGroup` |
| `final` | Whether to declare the layout as "final layout", the default is false, that is, whether this layout is `ViewGroup` or its subclasses will not generate the `performer` method block. After set to `true`, `lparams` and `requirePerformer` will no longer be valid. |
> The following example

View File

@@ -136,12 +136,13 @@ Hikage 可以在编译时为指定的布局组件自动生成布局组件对应
你可以在你的自定义 `View` 上加入 `HikageView` 注解,以标记它生成为 Hikage 布局组件。
| 参数名称 | 描述 |
| ------------------ | --------------------------------------------------------------------------------------------------------------------- |
| `lparams` | 布局参数 `ViewGroup.LayoutParams` Class 对象,如果你的自定义 `View``ViewGroup` 的子类,则可以声明或留空使用默认值 |
| `alias` | 布局组件的别名,即要生成的函数名称,默认获取当前 Class 的名称 |
| `requireInit` | 是否要求填写布局的初始化方法块,默认为可省略的参数 |
| `requirePerformer` | 是否要求填写布局的 `performer` 方法块,默认为可省略的参数,仅在你的自定义 `View``ViewGroup` 的子类时生效 |
| 参数名称 | 描述 |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `lparams` | 布局参数 `ViewGroup.LayoutParams` Class 对象,如果你的自定义 `View``ViewGroup` 的子类,则可以声明或留空使用默认值 |
| `alias` | 布局组件的别名,即要生成的函数名称,默认获取当前 Class 的名称 |
| `requireInit` | 是否要求填写布局的初始化方法块,默认为可省略的参数 |
| `requirePerformer` | 是否要求填写布局的 `performer` 方法块,默认为可省略的参数,仅在你的自定义 `View``ViewGroup` 的子类时生效 |
| `final` | 是否将布局声明为 “最终布局”,默认否,即此布局是否是 `ViewGroup` 还是从其继承都将不会生成 `performer` 方法块,设置为 `true` 之后,`lparams``requirePerformer` 将不再有效。 |
> 示例如下
@@ -174,13 +175,14 @@ Hikageable {
Hikage 同样可以为第三方提供的 `View` 组件自动生成布局组件函数,你可以使用 `HikageViewDeclaration` 注解来完成。
| 参数名称 | 描述 |
| ------------------ | --------------------------------------------------------------------------------------------------------------------- |
| `view` | 需要声明的布局组件的 Class 对象 |
| `lparams` | 布局参数 `ViewGroup.LayoutParams` Class 对象,如果你的自定义 `View``ViewGroup` 的子类,则可以声明或留空使用默认值 |
| `alias` | 布局组件的别名,即要生成的函数名称,默认获取 `view` Class 的名称 |
| `requireInit` | 是否要求填写布局的初始化方法块,默认为可省略的参数 |
| `requirePerformer` | 是否要求填写布局的 `performer` 方法块,默认为可省略的参数,仅在你的自定义 `View``ViewGroup` 的子类时生效 |
| 参数名称 | 描述 |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `view` | 需要声明的布局组件的 Class 对象 |
| `lparams` | 布局参数 `ViewGroup.LayoutParams` Class 对象,如果你的自定义 `View``ViewGroup` 的子类,则可以声明或留空使用默认值 |
| `alias` | 布局组件的别名,即要生成的函数名称,默认获取 `view` Class 的名称 |
| `requireInit` | 是否要求填写布局的初始化方法块,默认为可省略的参数 |
| `requirePerformer` | 是否要求填写布局的 `performer` 方法块,默认为可省略的参数,仅在你的自定义 `View``ViewGroup` 的子类时生效 |
| `final` | 是否将布局声明为 “最终布局”,默认否,即此布局是否是 `ViewGroup` 还是从其继承都将不会生成 `performer` 方法块,设置为 `true` 之后,`lparams``requirePerformer` 将不再有效。 |
> 示例如下

View File

@@ -211,7 +211,7 @@ class HikageViewGenerator(override val environment: SymbolProcessorEnvironment)
if (!performer.annotation.requireInit) defaultValue("{}")
}.build()
)
lparamsClass?.second?.let {
lparamsClass?.second?.takeIf { !performer.annotation.final }?.let {
addParameter(
ParameterSpec.builder(
name = "performer",
@@ -343,7 +343,8 @@ class HikageViewGenerator(override val environment: SymbolProcessorEnvironment)
override val lparams: KSClassDeclaration?,
override val alias: String?,
override val requireInit: Boolean,
override val requirePerformer: Boolean
override val requirePerformer: Boolean,
override val final: Boolean
) : HikageAnnotationSpec {
companion object {
@@ -360,12 +361,13 @@ class HikageViewGenerator(override val environment: SymbolProcessorEnvironment)
val alias = annotation.arguments.getOrNull<String>("alias")
val requireInit = annotation.arguments.getOrNull<Boolean>("requireInit") ?: false
val requirePerformer = annotation.arguments.getOrNull<Boolean>("requirePerformer") ?: false
val final = annotation.arguments.getOrNull<Boolean>("final") ?: false
// Solve the actual content of the annotation parameters.
val declaration = Processor.createViewDeclaration(NAME, alias, ksClass)
val resolvedLparams = Processor.resolvedLparamsDeclaration(NAME, resolver, declaration, lparams)
return HikageViewSpec(resolvedLparams, alias, requireInit, requirePerformer) to declaration
return HikageViewSpec(resolvedLparams, alias, requireInit, requirePerformer, final) to declaration
}
}
}
@@ -375,7 +377,8 @@ class HikageViewGenerator(override val environment: SymbolProcessorEnvironment)
override val lparams: KSClassDeclaration?,
override val alias: String?,
override val requireInit: Boolean,
override val requirePerformer: Boolean
override val requirePerformer: Boolean,
override val final: Boolean
) : HikageAnnotationSpec {
companion object {
@@ -393,6 +396,7 @@ class HikageViewGenerator(override val environment: SymbolProcessorEnvironment)
val alias = annotation.arguments.getOrNull<String>("alias")
val requireInit = annotation.arguments.getOrNull<Boolean>("requireInit") ?: false
val requirePerformer = annotation.arguments.getOrNull<Boolean>("requirePerformer") ?: false
val final = annotation.arguments.getOrNull<Boolean>("final") ?: false
// Solve the actual content of the annotation parameters.
val resolvedView = view?.declaration?.getClassDeclaration(resolver) ?: error("Internal error.")
@@ -407,7 +411,7 @@ class HikageViewGenerator(override val environment: SymbolProcessorEnvironment)
}
val resolvedLparams = Processor.resolvedLparamsDeclaration(NAME, resolver, declaration, lparams)
return HikageViewDeclarationSpec(resolvedView, resolvedLparams, alias, requireInit, requirePerformer) to declaration
return HikageViewDeclarationSpec(resolvedView, resolvedLparams, alias, requireInit, requirePerformer, final) to declaration
}
}
}
@@ -417,6 +421,7 @@ class HikageViewGenerator(override val environment: SymbolProcessorEnvironment)
val alias: String?
val requireInit: Boolean
val requirePerformer: Boolean
val final: Boolean
}
private data class Performer(

View File

@@ -45,6 +45,9 @@ import kotlin.reflect.KClass
* @param requireInit whether to force the `init` parameter to be called, default is false.
* @param requirePerformer whether to force the `performer` parameter to be called, default is false,
* this parameter will be ignored when no `performer` parameter is needed here.
* @param final whether to declare this layout as "final layout", default is false, that is,
* whether this layout inherits from or is [ViewGroup], the `performer` parameter will not be generated.
* After set to `true`, [lparams] and [requirePerformer] will no longer be valid.
*/
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.CLASS)
@@ -53,5 +56,6 @@ annotation class HikageView(
val lparams: KClass<*> = Any::class,
val alias: String = "",
val requireInit: Boolean = false,
val requirePerformer: Boolean = false
val requirePerformer: Boolean = false,
val final: Boolean = false
)

View File

@@ -48,6 +48,9 @@ import kotlin.reflect.KClass
* @param requireInit whether to force the `init` parameter to be called, default is false.
* @param requirePerformer whether to force the `performer` parameter to be called, default is false,
* this parameter will be ignored when no `performer` parameter is needed here.
* @param final whether to declare this layout as "final layout", default is false, that is,
* whether this layout inherits from or is [ViewGroup], the `performer` parameter will not be generated.
* After set to `true`, [lparams] and [requirePerformer] will no longer be valid.
*/
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.CLASS)
@@ -57,5 +60,6 @@ annotation class HikageViewDeclaration(
val lparams: KClass<*> = Any::class,
val alias: String = "",
val requireInit: Boolean = false,
val requirePerformer: Boolean = false
val requirePerformer: Boolean = false,
val final: Boolean = false
)