Skip to content

Commit

Permalink
KSP Support (#158)
Browse files Browse the repository at this point in the history
* KSP support

* many things converted, need to fix javac specifics

* checks all pass

* Update r finder and package config

* fix package info resources causing failed tests (from bad previous refactor)

* extract resource scanner interface

* implement KspResourceScanner without testing

* Create shared abstract processor class for javac and ksp

* set up ksp plugin

* upgrade to agp 7.0.1

* before renaming attr argument from value

* ksp resource processor working, bug some ksp bugs prevent compilation

* project compiles with ksp, fixed property naming generation

* kotlin compile testing set up, not all tests migrate

* move test resources to input/output

* fix test names

* Fix comments formatting

* Fix including parameter name in java resource

* Fix attrs test

* fix java getter field in ksp

* Update more tests

* processor tests all pass with ksp testing

* Try to make extensions test, not yet working

* extensions kapt test passes

* fix companion object as bad key of type elements

* fix double parens, all tests pass

* add more style extensions tests

* remove deprecated asynctask

* bump version

* fix type element formatting

* Clean up

* Fix originating elements and clean up

* checks all pass

* Bump version to airbnb5

* revert compile version bump

* Workaround protected visibility override bug

* Improve logging details

* Support type aliased imports

* Clean up

* travis to java 11

* update travis config

* fix connected tests

* ignore drawable comparisons

* fix originating elements

* fix typealias matching

* fix fully qualified r import

* improve error messaging

* add option for aggregateStyleablesOnClassPath

* Adding timing logs

* update docs and dependencies
  • Loading branch information
elihart authored Sep 18, 2021
1 parent 42f1a3a commit 8893584
Show file tree
Hide file tree
Showing 162 changed files with 3,060 additions and 1,166 deletions.
9 changes: 0 additions & 9 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 41 additions & 18 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,52 @@
language: android

android:
components:
- tools
- platform-tools
- build-tools-28.0.3
- build-tools-29.0.2
- android-28
- extra-google-google_play_services
- extra-android-m2repository
- extra-google-m2repository

jdk:
- oraclejdk8
jdk: oraclejdk11

branches:
except:
- gh-pages
- gh-pages

notifications:
email: false

script: "./gradlew check"
env:
global:
- ADB_INSTALL_TIMEOUT=8

android:
licenses:
- 'android-sdk-preview-license-.+'
- 'android-sdk-license-.+'
- 'google-gdk-license-.+'
components:
- tools
- platform-tools
- build-tools-30.0.2
- android-21
- android-28
- android-29
- android-30
- extra-google-google_play_services
- extra-android-m2repository
- extra-google-m2repository
- sys-img-armeabi-v7a-android-21

before_install:
- mkdir "$ANDROID_HOME/licenses" || true
- echo "24333f8a63b6825ea9c5514f83c2829b004d1fee" > "$ANDROID_HOME/licenses/android-sdk-license"

before_script:
- android list targets
- echo no | android create avd --force -n test -t android-21 --abi armeabi-v7a
- emulator -avd test -no-skin -no-window &
- android-wait-for-emulator
- adb shell input keyevent 82 &
- adb shell settings put secure long_press_timeout 1500

script:
- ./gradlew check --stacktrace
- ./gradlew connectedDebugAndroidTest --stacktrace

cache:
directories:
- $HOME/.m2
- $HOME/.gradle
- $HOME/.m2
- $HOME/.gradle
64 changes: 64 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,67 @@
# 2.0.0
Paris now supports Kotlin Symbol Processing for faster builds! https://github.com/google/ksp

Breaking changes needed to support KSP:
- ParisConfig annotation can no longer be used on package elements, only on class or interfaces
- R class references used in annotations cannot be star imported
- Added `aggregateStyleablesOnClassPath` parameter to @ParisConfig. This must now be set to true to have the module generate a Paris class using only classpath dependencies if there are no Styleables in the module sources.

Note: Due to a bug in KSP (https://github.com/google/ksp/issues/630) it is recommended to disable KSP incremental compilation until the bug is fixed in KSP, otherwise you may encounter spurious build failures.

Additionally, if you are using R2 generation via the butterknife gradle plugin you must configure KSP to be aware of those generated sources.
This can be done either via the experiment KSP setting `allowSourcesFromOtherPlugins`
```
// build.gradle.kts
ksp {
allowSourceFromOtherPlugins=true
}
```

Or by manually registering R2 sources as an input to KSP
```kotlin
// In a gradle plugin or build.gradle.kts
project.afterEvaluate {
setUpR2TaskDependency()
}

fun Project.setUpR2TaskDependency() {
requireAndroidVariants().forEach { variant ->
val r2Task = runCatching { project.tasks.named("generate${variant.name.capitalize()}R2") }.getOrNull()
if (r2Task != null) {
project.tasks.named("ksp${variant.name.capitalize()}Kotlin").dependsOn(r2Task)

project.extensions.configure(KotlinAndroidProjectExtension::class.java) {
sourceSets.getByName(variant.name)
.kotlin
.srcDir("build/generated/source/r2/${variant.name}")
}
}
}
}

/**
* Return the Android variants for this module, or error if this is not a module with a known Android plugin.
*/
fun Project.requireAndroidVariants(): DomainObjectSet<out BaseVariant> {
return androidVariants() ?: error("no known android extension found for ${project.name}")
}

/**
* Return the Android variants for this module, or null if this is not a module with a known Android plugin.
*/
fun Project.androidVariants(): DomainObjectSet<out BaseVariant>? {
return when (val androidExtension = this.extensions.findByName("android")) {
is LibraryExtension -> {
androidExtension.libraryVariants
}
is AppExtension -> {
androidExtension.applicationVariants
}
else -> null
}
}
```

# 1.7.3 (April 13, 2021)

- Fix generated code consistency in module class (#154)
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ Paris lets you define and apply styles programmatically to Android views, includ
In your project's `build.gradle`:
```gradle
dependencies {
implementation 'com.airbnb.android:paris:1.7.3'
// If you're using Paris annotations.
kapt 'com.airbnb.android:paris-processor:1.7.3'
implementation 'com.airbnb.android:paris:2.0.0'
// Apply the Paris processor if you're using Paris annotations for code gen.
kapt 'com.airbnb.android:paris-processor:2.0.0'
// or if you are using Kotlin Symbol Processing
ksp 'com.airbnb.android:paris-processor:2.0.0'
}
```

Expand Down
35 changes: 19 additions & 16 deletions blessedDeps.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ rootProject.ext {
ANDROIDX_APPCOMPAT_VERSION = '1.3.1'
ANDROIDX_CONSTRAINTLAYOUT_VERSION = '2.1.0'
ANDROIDX_ESPRESSO_VERSION = '3.4.0'
COROUTINES_VERSION = '1.5.2'
INCAP_VERSION = "0.3"
JAVAPOET_VERSION = '1.13.0'
JUNIT_VERSION = '4.13.2'
Expand All @@ -20,24 +21,26 @@ rootProject.ext {
MOCKITO_VERSION = '3.11.2'
ROBOLECTRIC_VERSION = '4.6.1'
TESTING_COMPILE_VERSION = '0.19'
KOTLIN_TESTING_COMPILE_VERSION = '1.4.4'

deps = [
// Keep these alphabetized
androidAnnotations: "androidx.annotation:annotation:$ANDROIDX_ANNOTATIONS_VERSION",
appcompat : "androidx.appcompat:appcompat:$ANDROIDX_APPCOMPAT_VERSION",
constraintLayout : "androidx.constraintlayout:constraintlayout:$ANDROIDX_CONSTRAINTLAYOUT_VERSION",
javaPoet : "com.squareup:javapoet:$JAVAPOET_VERSION",
espresso : "androidx.test.espresso:espresso-core:$ANDROIDX_ESPRESSO_VERSION",
incapRuntime : "net.ltgt.gradle.incap:incap:$INCAP_VERSION",
incapProcessor : "net.ltgt.gradle.incap:incap-processor:$INCAP_VERSION",
junit : "junit:junit:$JUNIT_VERSION",
kotlin : "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$KOTLIN_VERSION",
kotlinReflect : "org.jetbrains.kotlin:kotlin-reflect:$KOTLIN_VERSION",
kotlinPoet : "com.squareup:kotlinpoet:$KOTLINPOET_VERSION",
kotlinTest : "io.kotlintest:kotlintest:$KOTLIN_TEST_VERSION",
mockitoCore : "org.mockito:mockito-core:$MOCKITO_VERSION",
mockitoAndroid : "org.mockito:mockito-android:$MOCKITO_VERSION",
robolectric : "org.robolectric:robolectric:$ROBOLECTRIC_VERSION",
testingCompile : "com.google.testing.compile:compile-testing:$TESTING_COMPILE_VERSION",
androidAnnotations : "androidx.annotation:annotation:$ANDROIDX_ANNOTATIONS_VERSION",
appcompat : "androidx.appcompat:appcompat:$ANDROIDX_APPCOMPAT_VERSION",
constraintLayout : "androidx.constraintlayout:constraintlayout:$ANDROIDX_CONSTRAINTLAYOUT_VERSION",
coroutines : "org.jetbrains.kotlinx:kotlinx-coroutines-core:$COROUTINES_VERSION",
javaPoet : "com.squareup:javapoet:$JAVAPOET_VERSION",
espresso : "androidx.test.espresso:espresso-core:$ANDROIDX_ESPRESSO_VERSION",
incapRuntime : "net.ltgt.gradle.incap:incap:$INCAP_VERSION",
incapProcessor : "net.ltgt.gradle.incap:incap-processor:$INCAP_VERSION",
junit : "junit:junit:$JUNIT_VERSION",
kotlinCompileTesting: "com.github.tschuchortdev:kotlin-compile-testing-ksp:$KOTLIN_TESTING_COMPILE_VERSION",
kotlinReflect : "org.jetbrains.kotlin:kotlin-reflect:$KOTLIN_VERSION",
kotlinPoet : "com.squareup:kotlinpoet:$KOTLINPOET_VERSION",
kotlinTest : "io.kotlintest:kotlintest:$KOTLIN_TEST_VERSION",
mockitoCore : "org.mockito:mockito-core:$MOCKITO_VERSION",
mockitoAndroid : "org.mockito:mockito-android:$MOCKITO_VERSION",
robolectric : "org.robolectric:robolectric:$ROBOLECTRIC_VERSION",
testingCompile : "com.google.testing.compile:compile-testing:$TESTING_COMPILE_VERSION",
]
}
16 changes: 10 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
apply plugin: "com.github.ben-manes.versions"

buildscript {
ext {
ANDROID_PLUGIN_VERSION = '4.1.3'
BUTTERKNIFE_VERSION = '10.2.1'
KOTLIN_VERSION = '1.5.21'
ANDROID_PLUGIN_VERSION = '7.0.1'
BUTTERKNIFE_VERSION = '10.2.3'
KOTLIN_VERSION = '1.5.30'
VERSIONS_VERSION = '0.39.0'
KSP_VERSION = '1.5.30-1.0.0'
}

repositories {
Expand All @@ -26,6 +25,12 @@ buildscript {
}
}

plugins {
id "com.google.devtools.ksp" version "$KSP_VERSION"
}

apply plugin: "com.github.ben-manes.versions"

allprojects {
repositories {
google()
Expand All @@ -39,7 +44,6 @@ allprojects {

subprojects { project ->
apply from: "$rootDir/blessedDeps.gradle"
// TODO Same for maven upload script?
}

task clean(type: Delete) {
Expand Down
5 changes: 3 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERSION_NAME=1.7.3
VERSION_NAME=2.0.0
GROUP=com.airbnb.android
POM_DESCRIPTION=Paris is a system for creating and applying styles to views in Android.
POM_URL=https://github.com/airbnb/paris
Expand All @@ -17,9 +17,10 @@ android.useAndroidX=true
org.gradle.parallel=true
org.gradle.incremental=true
org.gradle.configureondemand=true
org.gradle.daemon=true
kotlin.incremental=true
kapt.includeCompileClasspath=false

# Dokka fails without a larger metaspace https://github.com/Kotlin/dokka/issues/1405
org.gradle.jvmargs=-XX:MaxMetaspaceSize=1g
org.gradle.daemon=true
#org.gradle.debug=true
Binary file added libs/rt.jar
Binary file not shown.
Binary file added libs/tools.jar
Binary file not shown.
1 change: 0 additions & 1 deletion paris-annotations/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ sourceCompatibility = rootProject.JAVA_SOURCE_VERSION
targetCompatibility = rootProject.JAVA_TARGET_VERSION

dependencies {
implementation deps.kotlin
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,26 @@
import java.lang.annotation.Target;

/**
* Note that when using KAPT with incremental annotation processing it is recommended to only use this annotation on class or interface elements,
* not on package elements in package-info.java. This is because there is a bug where package-info is not properly reprocessed in incremental builds.
* Place this annotation on a single class or interface within your module to specify configuration options for that module.
*/
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.PACKAGE, ElementType.TYPE})
@Target(ElementType.TYPE)
public @interface ParisConfig {

String defaultStyleNameFormat() default "";

Class<?> rClass() default Void.class;

/**
* This is an experimental gradle flag (android.namespacedRClass=true). Setting to true allows Paris to generate code compatible
* with R files that only have resources from the module the resource was declared in.
* This is an experimental gradle flag (android.namespacedRClass=true). Setting to true allows Paris to generate code compatible with R files that
* only have resources from the module the resource was declared in.
*/
boolean namespacedResourcesEnabled() default false;

/**
* By default no Paris class is generated if a module contains no @Styleable classes.
* However, if this is set to true a Paris class will still be generated in that case, using only
* the @Styleables that are discovered on the class path.
*/
boolean aggregateStyleablesOnClassPath() default false;
}
22 changes: 16 additions & 6 deletions paris-processor/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,31 @@ targetCompatibility = rootProject.JAVA_TARGET_VERSION

dependencies {
implementation project(':paris-annotations')
implementation "com.google.devtools.ksp:symbol-processing-api:$KSP_VERSION"
implementation "com.google.devtools.ksp:symbol-processing:$KSP_VERSION"
implementation "androidx.room:room-compiler-processing:2.4.0-alpha04"
// Compiler needed to resolve resource references in annotations
implementation "org.jetbrains.kotlin:kotlin-compiler-embeddable:$KOTLIN_VERSION"

implementation deps.androidAnnotations
implementation deps.kotlin

implementation deps.javaPoet
implementation deps.kotlinPoet
compileOnly deps.incapRuntime
kapt deps.incapProcessor

compileOnly files(Jvm.current().getToolsJar())
compileOnly files(rootProject.file("libs/tools.jar"))

testImplementation "androidx.room:room-compiler-processing-testing:2.4.0-alpha04"
testImplementation deps.junit
testImplementation "io.strikt:strikt-core:0.31.0"
testImplementation deps.kotlinTest
}

compileKotlin {
kotlinOptions.jvmTarget = "1.8"
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
freeCompilerArgs += "-Xopt-in=kotlin.contracts.ExperimentalContracts"
freeCompilerArgs += "-Xopt-in=androidx.room.compiler.processing.ExperimentalProcessingApi"
freeCompilerArgs += "-Xopt-in=com.google.devtools.ksp.KspExperimental"
}
}
Loading

0 comments on commit 8893584

Please sign in to comment.