com.zeoflow.depot.DepotProcessor.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of depot-compiler Show documentation
Show all versions of depot-compiler Show documentation
The Depot persistence library provides an abstraction layer over SQLite to allow for more robust database access while using the full power of SQLite.
The newest version!
/*
* Copyright (C) 2021 ZeoFlow SRL
*
* 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.
*/
package com.zeoflow.depot
import com.zeoflow.depot.compiler.processing.XProcessingEnv
import com.zeoflow.depot.compiler.processing.XProcessingStep.Companion.asAutoCommonProcessor
import com.zeoflow.depot.processor.Context
import com.zeoflow.depot.processor.ProcessorErrors
import com.zeoflow.depot.util.SimpleJavaVersion
import com.zeoflow.depot.vo.Warning
import com.google.auto.common.BasicAnnotationProcessor
import javax.lang.model.SourceVersion
/**
* Annotation processor option to tell Gradle that Depot is an isolating annotation processor.
*/
private const val ISOLATING_ANNOTATION_PROCESSORS_INDICATOR =
"org.gradle.annotation.processing.isolating"
/**
* The annotation processor for Depot.
*/
class DepotProcessor : BasicAnnotationProcessor() {
/** Helper variable to avoid reporting the warning twice. */
private var jdkVersionHasBugReported = false
override fun steps(): MutableIterable {
return mutableListOf(
DatabaseProcessingStep().asAutoCommonProcessor(processingEnv)
)
}
override fun getSupportedOptions(): MutableSet {
val supportedOptions = Context.ARG_OPTIONS.toMutableSet()
// x processing is a cheap wrapper so it is fine to re-create.
val xProcessing = XProcessingEnv.create(processingEnv)
if (Context.BooleanProcessorOptions.INCREMENTAL.getValue(xProcessing)) {
if (methodParametersVisibleInClassFiles()) {
// Depot can be incremental
supportedOptions.add(ISOLATING_ANNOTATION_PROCESSORS_INDICATOR)
} else {
if (!jdkVersionHasBugReported) {
Context(xProcessing).logger.w(
Warning.JDK_VERSION_HAS_BUG, ProcessorErrors.JDK_VERSION_HAS_BUG
)
jdkVersionHasBugReported = true
}
}
}
return supportedOptions
}
/**
* Returns `true` if the method parameters in class files can be accessed by Depot.
*
* Context: Depot requires access to the real parameter names of constructors (see
* PojoProcessor.getParamNames). Depot uses the ExecutableElement.getParemters() API on the
* constructor element to do this.
*
* When Depot is not yet incremental, the above API is working as expected. However, if we make
* Depot incremental, during an incremental compile Gradle may want to pass class files instead
* source files to annotation processors (to avoid recompiling the source files that haven't
* changed). Due to JDK bug https://bugs.openjdk.java.net/browse/JDK-8007720, the class files
* may lose the real parameter names of constructors, which would break Depot.
*
* The above JDK bug was fixed in JDK 11. The fix was also cherry-picked back into the
* embedded JDK that was shipped with Android Studio 3.5+.
*
* Therefore, for Depot to be incremental, we need to check whether the JDK being used has the
* fix: Either it is JDK 11+ or it is an embedded JDK that has the cherry-picked fix (version
* 1.8.0_202-release-1483-b39-5509098 or higher).
*/
private fun methodParametersVisibleInClassFiles(): Boolean {
val currentJavaVersion = SimpleJavaVersion.getCurrentVersion() ?: return false
if (currentJavaVersion >= SimpleJavaVersion.VERSION_11_0_0) {
return true
}
val isEmbeddedJdk =
System.getProperty("java.vendor")?.contains("JetBrains", ignoreCase = true)
?: false
// We are interested in 3 ranges of Android Studio (AS) versions:
// 1. AS 3.5.0-alpha09 and lower use JDK 1.8.0_152 or lower.
// 2. AS 3.5.0-alpha10 up to 3.5.0-beta01 use JDK 1.8.0_202-release-1483-b39-5396753.
// 3. AS 3.5.0-beta02 and higher use JDK 1.8.0_202-release-1483-b39-5509098 or higher,
// which have the cherry-picked JDK fix.
// Therefore, if the JDK version is 1.8.0_202, we need to filter out those in range #2.
return if (isEmbeddedJdk && (currentJavaVersion > SimpleJavaVersion.VERSION_1_8_0_202)) {
true
} else if (isEmbeddedJdk && (currentJavaVersion == SimpleJavaVersion.VERSION_1_8_0_202)) {
System.getProperty("java.runtime.version")
?.let { it != "1.8.0_202-release-1483-b39-5396753" }
?: false
} else {
false
}
}
override fun getSupportedSourceVersion(): SourceVersion {
return SourceVersion.latest()
}
}