Skip to content

Commit

Permalink
More accurate core library desugaring support
Browse files Browse the repository at this point in the history
The main idea is to use a custom wrapper around Animal Sniffer (instead of the Gradle plugin) so that we can 

* change class names in signatures, e.g. `DesugarDate` -> `Date`
* relax the superclass validation when merging signatures (i.e. we don't care whether `Long8` extends `Object` or `Number` but Animal Sniffer normally does)

Additional changes include:

* Treat android sdk as a Gradle artifact. This involves setting up an Ivy repo to match the custom layout of the Google SDK repository and a Gradle artifact transform that can extract android.jar from the SDK archive and seamlessly expose it as a dependency. This ensures SDKs are cached between `gradle clean`s and removes a whole bunch of custom download / unzip logic (at the expense of a bunch of Gradle artifact handling code).
* Rename some modules to better describe their purpose (maybe?).
  • Loading branch information
ogolberg authored Oct 27, 2020
1 parent 0d4b36b commit 81d29eb
Show file tree
Hide file tree
Showing 47 changed files with 591 additions and 222 deletions.
9 changes: 3 additions & 6 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ jobs:
key: v1-gradle-wrapper-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}
- restore_cache:
key: v1-gradle-cache-{{ checksum "build.gradle.kts" }}
- restore_cache:
key: v1-sdk-cache-{{ checksum "build.gradle.kts" }}

- run:
name: Build and test
Expand All @@ -32,10 +30,6 @@ jobs:
paths:
- ~/.gradle/caches
key: v1-gradle-cache-{{ checksum "build.gradle.kts" }}
- save_cache:
paths:
- build/sdk-archives
key: v1-sdk-cache-{{ checksum "build.gradle.kts" }}

- run:
name: Save test results
Expand All @@ -49,6 +43,9 @@ jobs:
- store_artifacts:
path: ~/test-results/junit

- run:
name: Deploy locally
command: ./gradlew publishToMavenLocal
- run:
name: Deploy (if release)
command: "if [[ \"$CIRCLE_BRANCH\" == master ]]; then ./gradlew publish closeAndReleaseRepository -Dorg.gradle.internal.http.socketTimeout=120000 -Dorg.gradle.internal.network.retry.max.attempts=1 -Dorg.gradle.internal.publish.checksums.insecure=true; else echo skipping publishing; fi"
Expand Down
3 changes: 1 addition & 2 deletions api/19/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

buildSignatures(
apiLevel = name,
sdkDir = "android-4.4.2",
sdkFile = "android-19_r04.zip",
sdk = "android-19:r04",
coreLibDesugaring = true
)
3 changes: 1 addition & 2 deletions api/20/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

buildSignatures(
apiLevel = name,
sdkDir = "android-4.4W.2",
sdkFile = "android-20_r02.zip",
sdk = "android-20:r02",
coreLibDesugaring = true
)
3 changes: 1 addition & 2 deletions api/21/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

buildSignatures(
apiLevel = name,
sdkDir = "android-5.0.1",
sdkFile = "android-21_r02.zip",
sdk = "android-21:r02",
coreLibDesugaring = true
)
3 changes: 1 addition & 2 deletions api/22/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

buildSignatures(
apiLevel = name,
sdkDir = "android-5.1.1",
sdkFile = "android-22_r02.zip",
sdk = "android-22:r02",
coreLibDesugaring = true
)
3 changes: 1 addition & 2 deletions api/23/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

buildSignatures(
apiLevel = name,
sdkDir = "android-6.0",
sdkFile = "platform-23_r03.zip",
sdk = "platform-23:r03",
coreLibDesugaring = true
)
3 changes: 1 addition & 2 deletions api/24/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

buildSignatures(
apiLevel = name,
sdkDir = "android-7.0",
sdkFile = "platform-24_r02.zip",
sdk = "platform-24:r02",
coreLibDesugaring = true
)
3 changes: 1 addition & 2 deletions api/25/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

buildSignatures(
apiLevel = name,
sdkDir = "android-7.1.1",
sdkFile = "platform-25_r03.zip",
sdk = "platform-25:r03",
coreLibDesugaring = true
)
3 changes: 1 addition & 2 deletions api/26/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

buildSignatures(
apiLevel = name,
sdkDir = "android-8.0.0",
sdkFile = "platform-26_r02.zip",
sdk = "platform-26:r02",
coreLibDesugaring = true
)
3 changes: 1 addition & 2 deletions api/27/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

buildSignatures(
apiLevel = name,
sdkDir = "android-8.1.0",
sdkFile = "platform-27_r03.zip",
sdk = "platform-27:r03",
coreLibDesugaring = true
)
3 changes: 1 addition & 2 deletions api/28/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,5 @@

buildSignatures(
apiLevel = name,
sdkDir = "android-9",
sdkFile = "platform-28_r06.zip"
sdk = "platform-28:r06"
)
3 changes: 1 addition & 2 deletions api/29/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,5 @@

buildSignatures(
apiLevel = name,
sdkDir = "android-10",
sdkFile = "platform-29_r04.zip"
sdk = "platform-29:r04"
)
3 changes: 1 addition & 2 deletions api/30/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,5 @@

buildSignatures(
apiLevel = name,
sdkDir = "android-11",
sdkFile = "platform-30_r03.zip"
sdk = "platform-30:r03"
)
5 changes: 5 additions & 0 deletions basic-sugar/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Standard Desugared APIs

Contains stubs for APIs desugared by vanilla D8 in AGP 3.x+ without core library desugaring.

Currently must be compiled with java 8.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package java.lang;

public abstract class Boolean implements java.io.Serializable, Comparable<Boolean> {
public abstract class Boolean {
public static int hashCode(boolean b) {
throw new RuntimeException();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package java.lang;

public abstract class Byte extends Number implements Comparable<Byte> {
public abstract class Byte {
public static int hashCode(byte i) {
throw new RuntimeException();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package java.lang;

public abstract class Character implements java.io.Serializable, Comparable<Character> {
public abstract class Character {
public static int compare(char a, char b) {
throw new RuntimeException();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package java.lang;

public abstract class Double extends Number implements Comparable<Double> {
public abstract class Double {
public static boolean isFinite(double d) {
throw new RuntimeException();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package java.lang;

public abstract class Float extends Number implements Comparable<Float> {
public abstract class Float {
public static int hashCode(float d) {
throw new RuntimeException();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package java.lang;

public abstract class Integer extends Number implements Comparable<Integer> {
public abstract class Integer {
public static int hashCode(int value) {
throw new RuntimeException();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package java.lang;

public abstract class Long extends Number implements Comparable<Long> {
public abstract class Long {
public static int hashCode(long value) {
throw new RuntimeException();
}
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package java.lang;

public abstract class Short extends Number implements Comparable<Short> {
public abstract class Short {
public static int hashCode(short i) {
throw new RuntimeException();
}
Expand Down
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ allprojects {
repositories {
google()
jcenter()

androidSdk()
}
}

Expand Down
2 changes: 0 additions & 2 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,5 @@ plugins {
}

dependencies {
implementation("de.undercouch:gradle-download-task:4.0.2")
implementation("ru.vyarus:gradle-animalsniffer-plugin:1.5.0")
implementation("io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.21.2")
}
22 changes: 22 additions & 0 deletions buildSrc/src/main/kotlin/Scopes.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2020. Toast Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

object Scopes {
const val generator = "generator"
const val sdk = "sdk"
const val standardSugar = "sugar"
const val exerciseStandardSugar = "exerciseStandardSugar"
const val coreLibSugar = "coreLibSugar"
}
97 changes: 97 additions & 0 deletions buildSrc/src/main/kotlin/androidSdk.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2020. Toast Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import org.gradle.api.Project
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.artifacts.transform.InputArtifact
import org.gradle.api.artifacts.transform.TransformAction
import org.gradle.api.artifacts.transform.TransformOutputs
import org.gradle.api.artifacts.transform.TransformParameters
import org.gradle.api.attributes.Attribute
import org.gradle.api.file.FileSystemLocation
import org.gradle.api.provider.Provider
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.registerTransform
import java.util.zip.ZipFile

const val SDK_GROUP = "com.google.android.sdk"

private const val ANDROID_JAR = "android.jar"
private val ARTIFACT_TYPE_ATTRIBUTE = Attribute.of("artifactType", String::class.java)
private val UNPACKED_SDK_ATTRIBUTE = Attribute.of("unpackedSdk", Boolean::class.javaObjectType)

/**
* This [artifact transform](https://docs.gradle.org/current/userguide/artifact_transforms.html)
* extracts android.jar from the Android SDK Platform zip archive.
*/
abstract class ExtractSdkTransform : TransformAction<TransformParameters.None> {
@get:InputArtifact
abstract val inputArtifact: Provider<FileSystemLocation>

override fun transform(outputs: TransformOutputs) {
val sdkArchive = ZipFile(inputArtifact.get().asFile)

val androidJarEntry = sdkArchive.entries().asSequence().find { it.name.endsWith(ANDROID_JAR) }

sdkArchive.getInputStream(androidJarEntry).use { i ->
outputs.file(ANDROID_JAR).outputStream().use { o ->
i.copyTo(o)
}
}
}
}

fun Project.extractSdk() {
configurations.named("sdk") {
attributes.attribute(UNPACKED_SDK_ATTRIBUTE, true)
}

dependencies {
attributesSchema {
attribute(UNPACKED_SDK_ATTRIBUTE)
}

artifactTypes.create("zip") {
attributes.attribute(UNPACKED_SDK_ATTRIBUTE, false)
}

registerTransform(ExtractSdkTransform::class) {
from.attribute(UNPACKED_SDK_ATTRIBUTE, false).attribute(ARTIFACT_TYPE_ATTRIBUTE, "zip")
to.attribute(UNPACKED_SDK_ATTRIBUTE, true).attribute(ARTIFACT_TYPE_ATTRIBUTE, "jar")
}
}
}


/**
* Enables Gradle to download artifacts from the Android SDK (non-Maven) repository.
*/
fun RepositoryHandler.androidSdk() {
ivy {
setUrl("https://dl.google.com/android/repository")

content {
includeGroup(SDK_GROUP)
}

patternLayout {
artifact("/[module]_[revision].[ext]")
}

metadataSources {
artifact()
}
}
}
6 changes: 5 additions & 1 deletion buildSrc/src/main/kotlin/dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,20 @@
*/

object versions {
const val animalSniffer = "1.16"
const val clikt = "3.0.1"
const val desugarJdkLibs = "1.0.10"
const val r8 = "1.5.68"
const val kotlin = "1.3.60"
const val kotlin = "1.4.10"
const val javapoet = "1.11.1"
const val javassist = "3.26.0-GA"
const val junit = "4.12"
const val truth = "1.0"
}

object libraries {
val animalSniffer = "org.codehaus.mojo:animal-sniffer:${versions.animalSniffer}"
val clikt = "com.github.ajalt.clikt:clikt:${versions.clikt}"
val desugarJdkLibs = "com.android.tools:desugar_jdk_libs:${versions.desugarJdkLibs}"
val r8 = "com.android.tools:r8:${versions.r8}"
val javapoet = "com.squareup:javapoet:${versions.javapoet}"
Expand Down
Loading

0 comments on commit 81d29eb

Please sign in to comment.