Vsevolod Tolstopyatov | 74bcc92 | 2018-05-03 20:07:54 +0300 | [diff] [blame] | 1 | package kotlinx.coroutines.experimental.tools |
| 2 | |
| 3 | import com.google.gson.internal.* |
| 4 | import com.google.gson.stream.* |
| 5 | import java.io.* |
| 6 | |
| 7 | data class ClassVisibility(val name: String, val visibility: String?, val members: Map<MemberSignature, MemberVisibility>) |
| 8 | data class MemberVisibility(val member: MemberSignature, val declaration: String?, val visibility: String?) |
| 9 | data class MemberSignature(val name: String, val desc: String) |
| 10 | |
| 11 | private fun isPublic(visibility: String?, isPublishedApi: Boolean) = visibility == null || visibility == "public" || visibility == "protected" || (isPublishedApi && visibility == "internal") |
| 12 | fun ClassVisibility.isPublic(isPublishedApi: Boolean) = isPublic(visibility, isPublishedApi) |
| 13 | fun MemberVisibility.isPublic(isPublishedApi: Boolean) = isPublic(visibility, isPublishedApi) |
| 14 | |
| 15 | fun MemberVisibility.isLateInit() = declaration != null && "lateinit var " in declaration |
| 16 | |
| 17 | private val varValPrefix = Regex("va[lr]\\s+") |
| 18 | fun ClassVisibility.findSetterForProperty(property: MemberVisibility): MemberVisibility? { |
| 19 | // ad-hoc solution: |
| 20 | val declaration = property.declaration ?: return null |
| 21 | val match = varValPrefix.find(declaration) ?: return null |
| 22 | val name = declaration.substring(match.range.endInclusive + 1).substringBefore(':') |
| 23 | val setterName = "<set-$name>" |
| 24 | return members.values.find { it.declaration?.contains(setterName) ?: false } |
| 25 | } |
| 26 | |
| 27 | fun readKotlinVisibilities(declarationFile: File): Map<String, ClassVisibility> { |
| 28 | val result = mutableListOf<ClassVisibility>() |
| 29 | declarationFile.bufferedReader().use { reader -> |
| 30 | val jsonReader = JsonReader(reader) |
| 31 | jsonReader.beginArray() |
| 32 | while (jsonReader.hasNext()) { |
| 33 | val classObject = Streams.parse(jsonReader).asJsonObject |
| 34 | result += with (classObject) { |
| 35 | val name = getAsJsonPrimitive("class").asString |
| 36 | val visibility = getAsJsonPrimitive("visibility")?.asString |
| 37 | val members = getAsJsonArray("members").map { it -> |
| 38 | with(it.asJsonObject) { |
| 39 | val name = getAsJsonPrimitive("name").asString |
| 40 | val desc = getAsJsonPrimitive("desc").asString |
| 41 | val declaration = getAsJsonPrimitive("declaration")?.asString |
| 42 | val visibility = getAsJsonPrimitive("visibility")?.asString |
| 43 | MemberVisibility(MemberSignature(name, desc), declaration, visibility) |
| 44 | } |
| 45 | } |
| 46 | ClassVisibility(name, visibility, members.associateByTo(hashMapOf()) { it.member }) |
| 47 | } |
| 48 | } |
| 49 | jsonReader.endArray() |
| 50 | } |
| 51 | |
| 52 | return result.associateByTo(hashMapOf()) { it.name } |
| 53 | } |