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 */ classRefnull105inline fun <reified T : Any> ImportsProvider.classRef(): String { 106 return classRef(T::class.java.name) 107 } 108