# 针对 Java 注解处理器开发者的参考文档 ## 程序元素 | Java | KSP 中的类似功能 | 注意事项 | | --- | --- | --- | | `AnnotationMirror` | `KSAnnotation` | | | `AnnotationValue` | `KSValueArguments` | | | `Element` | `KSDeclaration` / `KSDeclarationContainer` | | | `ExecutableElement` | `KSFunctionDeclaration` | | | `PackageElement` | `KSFile` | KSP 不将包建模为程序元素 | | `Parameterizable` | `KSDeclaration` | | | `QualifiedNameable` | `KSDeclaration` | | | `TypeElement` | `KSClassDeclaration` | | | `TypeParameterElement` | `KSTypeParameter` | | | `VariableElement` | `KSValueParameter` / `KSPropertyDeclaration` | | ## 类型 KSP 要求明确解析类型, 因此在解析之前, Java 中的有些功能只能通过 `KSType` 和对应的元素得到. | Java | KSP 中的类似功能 | 注意事项 | | --- | --- | --- | | `ArrayType` | `KSBuiltIns.arrayType` | | | `DeclaredType` | `KSType` / `KSClassifierReference` | | | `ErrorType` | `KSType.isError` | | | `ExecutableType` | `KSType` / `KSCallableReference` | | | `IntersectionType` | `KSType` / `KSTypeParameter` | | | `NoType` | `KSType.isError` | KSP 中没有这样的功能 | | `NullType` | | KSP 中没有这样的功能 | | `PrimitiveType` | `KSBuiltIns` | 与 Java 中的基本类型不完全相同 | | `ReferenceType` | `KSTypeReference` | | | `TypeMirror` | `KSType` | | | `TypeVariable` | `KSTypeParameter` | | | `UnionType` | 没有这样的功能 | Kotlin 的 每个 catch 代码段只有 1 个类型. 即使对 Java 注解处理器来说, `UnionType` 也是不可访问的 | | `WildcardType` | `KSType` / `KSTypeArgument` | | ## 杂项 | Java | KSP 中的类似功能 | 注意事项 | | --- | --- | --- | | `Name` | `KSName` | | | `ElementKind` | `ClassKind` / `FunctionKind` | | | `Modifier` | `Modifier` | | | `NestingKind` | `ClassKind` / `FunctionKind` | | | `AnnotationValueVisitor` | | | | `ElementVisitor` | `KSVisitor` | | | `AnnotatedConstruct` | `KSAnnotated` | | | `TypeVisitor` | | | | `TypeKind` | `KSBuiltIns` | 有些可以在 builtin 中得到, 其他通过 `KSClassDeclaration` 得到 `DeclaredType` | | `ElementFilter` | `Collection.filterIsInstance` | | | `ElementKindVisitor` | `KSVisitor` | | | `ElementScanner` | `KSTopDownVisitor` | | | `SimpleAnnotationValueVisitor` | | KSP 中不需要 | | `SimpleElementVisitor` | `KSVisitor` | | | `SimpleTypeVisitor` | | | | `TypeKindVisitor` | | | | `Types` | `Resolver` / `utils` | 有些 `utils` 也被集成在符号接口中 | | `Elements` | `Resolver` / `utils` | | ## 细节 这部分介绍 KSP 怎样提供 Java 注解处理 API 的功能. ### AnnotationMirror | Java | KSP 中的同等功能 | | --- | --- | | `getAnnotationType` | `ksAnnotation.annotationType` | | `getElementValues` | `ksAnnotation.arguments` | ### AnnotationValue | Java | KSP 中的同等功能 | | --- | --- | | `getValue` | `ksValueArgument.value` | ### Element | Java | KSP 中的同等功能 | | --- | --- | | `asType` | `ksClassDeclaration.asType(...)` 只对 `KSClassDeclaration` 有效. 需要提供类型参数. | | `getAnnotation` | 未实现 | | `getAnnotationMirrors` | `ksDeclaration.annotations` | | `getEnclosedElements` | `ksDeclarationContainer.declarations` | | `getEnclosingElements` | `ksDeclaration.parentDeclaration` | | `getKind` | 通过 `ClassKind` 或 `FunctionKind` 进行类型检查和转换 | | `getModifiers` | `ksDeclaration.modifiers` | | `getSimpleName` | `ksDeclaration.simpleName` | ### ExecutableElement | Java | KSP 中的同等功能 | | --- | --- | | `getDefaultValue` | 未实现 | | `getParameters` | `ksFunctionDeclaration.parameters` | | `getReceiverType` | `ksFunctionDeclaration.parentDeclaration` | | `getReturnType` | `ksFunctionDeclaration.returnType` | | `getSimpleName` | `ksFunctionDeclaration.simpleName` | | `getThrownTypes` | Kotlin 中不需要 | | `getTypeParameters` | `ksFunctionDeclaration.typeParameters` | | `isDefault` | 检查父类型是不是接口 | | `isVarArgs` | `ksFunctionDeclaration.parameters.any { it.isVarArg }` | ### Parameterizable | Java | KSP 中的同等功能 | | --- | --- | | `getTypeParameters` | `ksFunctionDeclaration.typeParameters` | ### QualifiedNameable | Java | KSP 中的同等功能 | | --- | --- | | `getQualifiedName` | `ksDeclaration.qualifiedName` | ### TypeElement | Java | KSP 中的同等功能 | | --- | --- | | `getEnclosedElements` | `ksClassDeclaration.declarations` | | `getEnclosingElement` | `ksClassDeclaration.parentDeclaration` | | `getInterfaces` | ```KOTLIN // 不需要类型解析也应该能够实现 ksClassDeclaration.superTypes .map { it.resolve() } .filter { (it?.declaration as? KSClassDeclaration)?.classKind == ClassKind.INTERFACE }
``` | | `getNestingKind` | Check `KSClassDeclaration.parentDeclaration` 和 `inner` 修饰符 | | `getQualifiedName` | `ksClassDeclaration.qualifiedName` | | `getSimpleName` | `ksClassDeclaration.simpleName` | | `getSuperclass` | ```KOTLIN // 不需要类型解析也应该能够实现 ksClassDeclaration.superTypes .map { it.resolve() } .filter { (it?.declaration as? KSClassDeclaration)?.classKind == ClassKind.CLASS } ``` | | `getTypeParameters` | `ksClassDeclaration.typeParameters` | ### TypeParameterElement | Java | KSP 中的同等功能 | | --- | --- | | `getBounds` | `ksTypeParameter.bounds` | | `getEnclosingElement` | `ksTypeParameter.parentDeclaration` | | `getGenericElement` | `ksTypeParameter.parentDeclaration` | ### VariableElement | Java | KSP 中的同等功能 | | --- | --- | | `getConstantValue` | 未实现 | | `getEnclosingElement` | `ksValueParameter.parentDeclaration` | | `getSimpleName` | `ksValueParameter.simpleName` | ### ArrayType | Java | KSP 中的同等功能 | | --- | --- | | `getComponentType` | `ksType.arguments.first()` | ### DeclaredType | Java | KSP 中的同等功能 | | --- | --- | | `asElement` | `ksType.declaration` | | `getEnclosingType` | `ksType.declaration.parentDeclaration` | | `getTypeArguments` | `ksType.arguments` | ### ExecutableType > **Note:** > 函数的 `KSType` 只是一个签名, 由 `FunctionN` 群表达. | Java | KSP 中的同等功能 | | --- | --- | | `getParameterTypes` | `ksType.declaration.typeParameters`, `ksFunctionDeclaration.parameters.map { it.type }` | | `getReceiverType` | `ksFunctionDeclaration.parentDeclaration.asType(...)` | | `getReturnType` | `ksType.declaration.typeParameters.last()` | | `getThrownTypes` | Kotlin 中不需要 | | `getTypeVariables` | `ksFunctionDeclaration.typeParameters` | ### IntersectionType | Java | KSP 中的同等功能 | | --- | --- | | `getBounds` | `ksTypeParameter.bounds` | ### TypeMirror | Java | KSP 中的同等功能 | | --- | --- | | `getKind` | 对于基本类型, `Unit`, 与 `KSBuiltIns` 中的类型比较, 其他情况使用 DeclaredType | ### TypeVariable | Java | KSP 中的同等功能 | | --- | --- | | `asElement` | `ksType.declaration` | | `getLowerBound` | 未决定. 只存在 capture, 并且需要明确的边界检查时, 才需要这个功能. | | `getUpperBound` | `ksTypeParameter.bounds` | ### WildcardType | Java | KSP 中的同等功能 | | --- | --- | | `getExtendsBound` | ```KOTLIN if (ksTypeArgument.variance == Variance.COVARIANT) ksTypeArgument.type else null ``` | | `getSuperBound` | ```KOTLIN if (ksTypeArgument.variance == Variance.CONTRAVARIANT) ksTypeArgument.type else null ``` | ### Elements | Java | KSP 中的同等功能 | | --- | --- | | `getAllAnnotationMirrors` | `KSDeclarations.annotations` | | `getAllMembers` | `getAllFunctions`, `getAllProperties` 未实现 | | `getBinaryName` | 未决定, 参见 [Java Specification](https://docs.oracle.com/javase/specs/jls/se13/html/jls-13.html#jls-13.1) | | `getConstantExpression` | 常数值, 而不是表达式 | | `getDocComment` | 未实现 | | `getElementValuesWithDefaults` | 未实现 | | `getName` | `resolver.getKSNameFromString` | | `getPackageElement` | 不支持包, 但可以取得包信息. KSP 中不能对包进行操作. | | `getPackageOf` | 不支持包 | | `getTypeElement` | `Resolver.getClassDeclarationByName` | | `hides` | 未实现 | | `isDeprecated` | ```KOTLIN KsDeclaration.annotations.any { it.annotationType.resolve()!!.declaration.qualifiedName!!.asString() == Deprecated::class.qualifiedName } ``` | | `overrides` | `KSFunctionDeclaration.overrides` / `KSPropertyDeclaration.overrides` (各个类的成员函数) | | `printElements` | KSP 对大多数类有基本的 `toString()` 实现 | ### Types | Java | KSP 中的同等功能 | | --- | --- | | `asElement` | `ksType.declaration` | | `asMemberOf` | `resolver.asMemberOf` | | `boxedClass` | 不需要 | | `capture` | 未决定 | | `contains` | `KSType.isAssignableFrom` | | `directSuperTypes` | `(ksType.declaration as KSClassDeclaration).superTypes` | | `erasure` | `ksType.starProjection()` | | `getArrayType` | `ksBuiltIns.arrayType.replace(...)` | | `getDeclaredType` | `ksClassDeclaration.asType` | | `getNoType` | `ksBuiltIns.nothingType` / `null` | | `getNullType` | 根据上下文确定, 可能可以使用 `KSType.markNullable` | | `getPrimitiveType` | 不需要, 检查 `KSBuiltins` | | `getWildcardType` | 在需要 `KSTypeArgument` 的地方使用 `Variance` | | `isAssignable` | `ksType.isAssignableFrom` | | `isSameType` | `ksType.equals` | | `isSubsignature` | `functionTypeA == functionTypeB` / `functionTypeA == functionTypeB.starProjection()` | | `isSubtype` | `ksType.isAssignableFrom` | | `unboxedType` | 不需要 |