• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2019 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 
18 package com.android.codegen
19 
20 import com.github.javaparser.ast.CompilationUnit
21 
22 /**
23  * Mixin for optionally shortening references based on existing imports
24  */
25 interface ImportsProvider {
26 
27     abstract val fileAst: CompilationUnit
28 
29     val NonNull: String get() { return classRef("android.annotation.NonNull") }
30     val NonEmpty: String get() { return classRef("android.annotation.NonEmpty") }
31     val Nullable: String get() { return classRef("android.annotation.Nullable") }
32     val TextUtils: String get() { return classRef("android.text.TextUtils") }
33     val LinkedHashMap: String get() { return classRef("java.util.LinkedHashMap") }
34     val Collections: String get() { return classRef("java.util.Collections") }
35     val Preconditions: String get() { return classRef("com.android.internal.util.Preconditions") }
36     val ArrayList: String get() { return classRef("java.util.ArrayList") }
37     val DataClass: String get() { return classRef("com.android.internal.util.DataClass") }
38     val DataClassEnum: String get() { return classRef("com.android.internal.util.DataClass.Enum") }
39     val ParcelWith: String get() { return classRef("com.android.internal.util.DataClass.ParcelWith") }
40     val PluralOf: String get() { return classRef("com.android.internal.util.DataClass.PluralOf") }
41     val Each: String get() { return classRef("com.android.internal.util.DataClass.Each") }
42     val MaySetToNull: String get() { return classRef("com.android.internal.util.DataClass.MaySetToNull") }
43     val DataClassGenerated: String get() { return classRef("com.android.internal.util.DataClass.Generated") }
44     val DataClassSuppressConstDefs: String get() { return classRef("com.android.internal.util.DataClass.SuppressConstDefsGeneration") }
45     val DataClassSuppress: String get() { return classRef("com.android.internal.util.DataClass.Suppress") }
46     val GeneratedMember: String get() { return classRef("com.android.internal.util.DataClass.Generated.Member") }
47     val Parcelling: String get() { return classRef("com.android.internal.util.Parcelling") }
48     val Parcelable: String get() { return classRef("android.os.Parcelable") }
49     val Parcel: String get() { return classRef("android.os.Parcel") }
50     val UnsupportedAppUsage: String get() { return classRef("android.compat.annotation.UnsupportedAppUsage") }
51 
52     /**
53      * Optionally shortens a class reference if there's a corresponding import present
54      */
55     fun classRef(fullName: String): String {
56         val pkg = fullName.substringBeforeLast(".")
57         val simpleName = fullName.substringAfterLast(".")
58         val imports = fileAst.imports
59 
60         // If an import of the same class name is available,
61         // use it instead of the internal Android package variants.
62         if (fullName.startsWith("com.android.internal.util.")
63             && imports.any {
64                 it.nameAsString.endsWith(fullName.removePrefix("com.android.internal.util."))
65             }
66         ) {
67             return fullName.removePrefix("com.android.internal.util.")
68         } else if (fullName.startsWith("android.annotation")
69             && imports.any { it.nameAsString.endsWith(simpleName) }
70         ) {
71             return simpleName
72         }
73 
74         if (imports.any { imprt ->
75                     imprt.nameAsString == fullName
76                             || (imprt.isAsterisk && imprt.nameAsString == pkg)
77                 }) {
78             return simpleName
79         } else {
80             val outerClass = pkg.substringAfterLast(".", "")
81             if (outerClass.firstOrNull()?.isUpperCase() == true) {
82                 return classRef(pkg) + "." + simpleName
83             }
84         }
85         return fullName
86     }
87 
88     /** @see classRef */
89     fun memberRef(fullName: String): String {
90         val className = fullName.substringBeforeLast(".")
91         val methodName = fullName.substringAfterLast(".")
92         return if (fileAst.imports.any {
93                     it.isStatic
94                             && (it.nameAsString == fullName
95                             || (it.isAsterisk && it.nameAsString == className))
96                 }) {
97             className.substringAfterLast(".") + "." + methodName
98         } else {
99             classRef(className) + "." + methodName
100         }
101     }
102 }
103 
104 /** @see classRef */
classRefnull105 inline fun <reified T : Any> ImportsProvider.classRef(): String {
106     return classRef(T::class.java.name)
107 }
108