All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.gradle.utils.providerApiUtils.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/*
 * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
 * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
 */

package org.jetbrains.kotlin.gradle.utils

import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.provider.SetProperty
import org.gradle.api.provider.ValueSource
import org.gradle.api.provider.ValueSourceParameters
import java.io.File
import kotlin.reflect.KProperty

internal operator fun  Provider.getValue(thisRef: Any?, property: KProperty<*>) = get()

internal operator fun  Property.setValue(thisRef: Any?, property: KProperty<*>, value: T) {
    set(value)
}

internal fun  Project.newProperty(initialize: (() -> T)? = null): Property =
    @Suppress("UNCHECKED_CAST")
    (project.objects.property(Any::class.java) as Property).apply {
        if (initialize != null)
            set(provider(initialize))
    }

internal inline fun  ObjectFactory.property() = property(T::class.java)

internal inline fun  ObjectFactory.listProperty() = listProperty(T::class.java)

internal inline fun  ObjectFactory.setProperty() = setProperty(T::class.java)

internal inline fun  ObjectFactory.property(initialValue: T) = property().value(initialValue)

internal inline fun  ObjectFactory.property(initialValue: Provider) = property().value(initialValue)

internal inline fun  ObjectFactory.setPropertyWithValue(
    initialValue: Provider>
) = setProperty().value(initialValue)

internal inline fun  ObjectFactory.setPropertyWithLazyValue(
    noinline lazyValue: () -> Iterable
) = setPropertyWithValue(providerWithLazyConvention(lazyValue))

internal inline fun  ObjectFactory.propertyWithConvention(
    conventionValue: Provider
) = property().convention(conventionValue)

internal inline fun  ObjectFactory.propertyWithConvention(
    conventionValue: T
) = property().convention(conventionValue)

internal inline fun  ObjectFactory.listPropertyWithConvention(
    conventionValue: Iterable
) = listProperty().convention(conventionValue)

internal inline fun  ObjectFactory.providerWithLazyConvention(
    noinline lazyConventionValue: () -> T
) = property(lazyConventionValue).map { it.invoke() }

internal inline fun  ObjectFactory.newInstance() = newInstance(T::class.java)

internal inline fun  ObjectFactory.newInstance(vararg parameters: Any) =
    newInstance(T::class.java, *parameters)

internal inline fun  ObjectFactory.propertyWithNewInstance(
    vararg parameters: Any
) = propertyWithConvention(newInstance(T::class.java, *parameters))

internal fun > T.chainedFinalizeValueOnRead(): T =
    apply {
        finalizeValueOnRead()
    }

internal fun > T.chainedFinalizeValueOnRead(): T =
    apply {
        finalizeValueOnRead()
    }

internal fun > T.chainedFinalizeValue(): T =
    apply {
        finalizeValue()
    }

internal fun > T.chainedDisallowChanges(): T =
    apply {
        disallowChanges()
    }

// Before 5.0 fileProperty is created via ProjectLayout
// https://docs.gradle.org/current/javadoc/org/gradle/api/model/ObjectFactory.html#fileProperty--
internal fun Project.newFileProperty(initialize: (() -> File)? = null): RegularFileProperty {
    val regularFileProperty = project.objects.fileProperty()

    return regularFileProperty.apply {
        if (initialize != null) {
            set(project.layout.file(project.provider(initialize)))
        }
    }
}

internal fun Project.filesProvider(
    vararg buildDependencies: Any,
    provider: () -> Any?
): ConfigurableFileCollection {
    return project.files(provider).builtBy(*buildDependencies)
}

internal fun  T.outputFilesProvider(provider: T.() -> Any): ConfigurableFileCollection {
    return project.filesProvider(this) { provider() }
}

internal fun  T.outputFilesProvider(lazy: Lazy): ConfigurableFileCollection {
    return project.filesProvider(this) { lazy.value }
}

internal inline fun  Project.listProperty(noinline itemsProvider: () -> Iterable): ListProperty =
    objects.listProperty(T::class.java).apply { set(provider(itemsProvider)) }

internal inline fun  Project.setProperty(noinline itemsProvider: () -> Iterable): SetProperty =
    objects.setProperty(T::class.java).apply { set(provider(itemsProvider)) }

/**
 * Changing Provider will be evaluated every time it accessed.
 *
 * And its producing [code] will be serilalised to Configuration Cache as is
 * So that it still will be evaluated during Task Execution phase.
 * It is very convenient for Configuration Cache compatibility.
 *
 * It is recommended to use Task Output's and map/flatMap them to other Task Inputs but in cases when TaskOutput's is not available
 * as Gradle's Properties or Providers then this [changing] provider can be used.
 *
 * name `changing` and overall concept is borrowed from Gradle internal API [org.gradle.api.internal.provider.Providers.changing]
 *
 * @see org.gradle.api.internal.provider.ChangingProvider
 */
internal fun  ProviderFactory.changing(code: () -> T): Provider {
    @Suppress("UNCHECKED_CAST")
    val adhocValueSourceClass = AdhocValueSource::class.java as Class>
    return of(adhocValueSourceClass) { valueSourceSpec ->
        valueSourceSpec.parameters {
            it.producingLambda.set(code)
        }
    }
}

private abstract class AdhocValueSource : ValueSource {

    // this interface can't be parameterized with T since it breaks internal Gradle logic
    // This is why producingLambda is '() -> Any?' but not '() -> T'
    interface Parameters : ValueSourceParameters {
        val producingLambda: Property<() -> Any?>
    }

    override fun obtain(): T {
        @Suppress("UNCHECKED_CAST")
        return parameters.producingLambda.get().invoke() as T
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy