1 /*
<lambda>null2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.conscrypt.doclet
18
19 import com.sun.source.doctree.UnknownBlockTagTree
20 import javax.lang.model.element.Element
21 import javax.lang.model.element.ElementKind
22 import javax.lang.model.element.ExecutableElement
23 import javax.lang.model.element.Modifier
24 import javax.lang.model.element.TypeElement
25 import javax.lang.model.element.VariableElement
26 import javax.lang.model.type.TypeMirror
27
28 fun Element.isType() = isClass() || isInterface() || isEnum()
29 fun Element.isClass() = this is TypeElement && kind == ElementKind.CLASS
30 fun Element.isEnum() = this is TypeElement && kind == ElementKind.ENUM
31 fun Element.isInterface() = this is TypeElement && kind == ElementKind.INTERFACE
32 fun Element.isExecutable() = this is ExecutableElement
33 fun Element.isField() = this is VariableElement
34
35 fun Element.isVisibleType() = isType() && isVisible()
36 fun Element.isVisibleMethod() = isExecutable() && isVisible() && kind == ElementKind.METHOD
37 fun Element.isVisibleConstructor() = isExecutable() && isVisible() && kind == ElementKind.CONSTRUCTOR
38 fun Element.isVisibleField() = isField() && isVisible()
39 fun Element.isPublic() = modifiers.contains(Modifier.PUBLIC)
40 fun Element.isPrivate() = !isPublic() // Ignore protected for now :)
41 fun Element.isVisible() = !isHidden()
42 fun Element.isHidden() = isPrivate() || isFiltered() || parentIsHidden()
43 fun Element.children(filterFunction: (Element) -> Boolean) = enclosedElements
44 .filter(filterFunction)
45 .toList()
46
47 fun Element.parentIsHidden(): Boolean
48 = if (enclosingElement.isType()) enclosingElement.isHidden() else false
49
50 fun Element.hasAnnotation(annotationName: String): Boolean = annotationMirrors
51 .map { it.annotationType.toString() }
<lambda>null52 .any { it == annotationName }
53
Elementnull54 fun Element.hasJavadocTag(tagName: String): Boolean {
55 return docTree()?.blockTags?.any {
56 tag -> tag is UnknownBlockTagTree && tag.tagName == tagName
57 } ?: false
58 }
59
ExecutableElementnull60 fun ExecutableElement.isConstructor() = kind == ElementKind.CONSTRUCTOR
61 fun ExecutableElement.name() = if (isConstructor()) parentName() else simpleName.toString()
62 fun ExecutableElement.parentName() = enclosingElement.simpleName.toString()
63
64 fun ExecutableElement.methodSignature(): String {
65 val modifiers = modifiers.joinToString(" ")
66 val returnType = if (isConstructor()) "" else "${formatType(returnType)} "
67
68 val typeParams = typeParameters.takeIf { it.isNotEmpty() }
69 ?.joinToString(separator = ", ", prefix = "<", postfix = ">") {
70 it.asType().toString() } ?: ""
71
72 val parameters = parameters.joinToString(", ") { param ->
73 "${formatType(param.asType())} ${param.simpleName}"
74 }
75
76 val exceptions = thrownTypes
77 .joinToString(", ")
78 .prefixIfNotEmpty(" throws ")
79 return "$modifiers $typeParams$returnType${name()}($parameters)$exceptions"
80 }
81
formatTypenull82 fun formatType(typeMirror: TypeMirror): String {
83 return if (typeMirror.kind.isPrimitive) {
84 typeMirror.toString()
85 } else {
86 typeMirror.toString()
87 .split('.')
88 .last()
89 }
90 }
91
TypeElementnull92 fun TypeElement.baseFileName(): String =
93 if (enclosingElement.isType())
94 (enclosingElement as TypeElement).baseFileName() + "." + simpleName
95 else
96 qualifiedName.toString().replace('.', '/')
97
98 private fun String.prefixIfNotEmpty(prefix: String): String
99 = if (isNotEmpty()) prefix + this else this
100