Skip to content

Commit

Permalink
WIP - Immediately compute arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
BenWoodworth committed Nov 11, 2023
1 parent 5f688a1 commit e039271
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 78 deletions.
2 changes: 1 addition & 1 deletion src/commonMain/kotlin/ParameterState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ internal class ParameterState<@Suppress("unused") out T> internal constructor()
*/
internal fun nextArgument() {
val arguments = checkNotNull(arguments) {
"Cannot iterate arguments before parameter delegate has been declared"
"Cannot iterate arguments before parameter argument has been declared"
}

check(argument != Uninitialized) {
Expand Down
10 changes: 5 additions & 5 deletions src/commonMain/kotlin/ParameterizeState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ internal class ParameterizeState {
if (it != null) throw ParameterizeException("Nesting parameters is not currently supported: `${property.name}` was declared within `${it.name}`'s arguments")
}

val parameterIndex = parameterCount++
val parameterIndex = parameterCount

val parameter = if (parameterIndex in parameters.indices) {
parameters[parameterIndex]
Expand All @@ -57,8 +57,8 @@ internal class ParameterizeState {
property.trackNestedUsage {
parameter.parameterState.declare(property, arguments)
}
// getParameterArgument(parameter, property)

parameterCount++
return parameter
}

Expand Down Expand Up @@ -94,18 +94,18 @@ internal class ParameterizeState {
}

/**
* Iterate the last parameter (by the order they're first used) that has a
* Iterate the last parameter (by order of when arguments are calculated) that has a
* next argument, and reset all parameters that were first used after it
* (since they may depend on the now changed value, and may be computed
* differently).
* differently). TODO Update
*
* Returns `true` if the arguments are at a new permutation.
*/
private fun nextArgumentPermutationOrFalse(): Boolean {
var iterated = false

val declaredParameterIterator = parameters
.listIterator(parameters.lastIndex + 1)
.listIterator(parameterCount)

while (declaredParameterIterator.hasPrevious()) {
val parameter = declaredParameterIterator.previous()
Expand Down
17 changes: 3 additions & 14 deletions src/commonTest/kotlin/ParameterStateSpec.kt
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,7 @@ class ParameterStateSpec {
parameter.nextArgument()
}

assertEquals("Cannot iterate arguments before parameter delegate has been declared", failure.message)
}

@Test
fun next_before_initialized_should_throw_IllegalStateException() {
parameter.declare(::property, emptyList())

val failure = assertFailsWith<IllegalStateException> {
parameter.nextArgument()
}

assertEquals("Cannot iterate arguments before parameter argument has been initialized", failure.message)
assertEquals("Cannot iterate arguments before parameter argument has been declared", failure.message)
}

@Test
Expand Down Expand Up @@ -209,10 +198,10 @@ class ParameterStateSpec {

@Test
fun redeclare_with_different_parameter_should_throw_ParameterizeException() {
parameter.declare(::property, emptyList())
parameter.declare(::property, listOf(Unit))

assertFailsWith<ParameterizeException> {
parameter.declare(::differentProperty, emptyList())
parameter.declare(::differentProperty, listOf(Unit))
}
}

Expand Down
61 changes: 3 additions & 58 deletions src/commonTest/kotlin/ParameterizeSpec.kt
Original file line number Diff line number Diff line change
Expand Up @@ -196,52 +196,7 @@ class ParameterizeSpec {
}

@Test
fun parameters_that_are_used_out_of_order_should_iterate_in_declaration_order() {
// Because they should iterate in the order their arguments are calculated, and that happens at declaration.

// Parameters that (potentially) depend on another parameter should iterate first, since if it were the other
// way around, and the depended on parameter iterates first, the dependent parameter's argument would be based
// on a now changed value and wouldn't be valid.

// Basic test
testParameterize(
listOf("a1", "a2", "b1", "b2")
) {
val first by parameterOf("a", "b")
val second by parameterOf(1, 2)

useParameter(second)
useParameter(first)

"$first$second"
}

// More contrived test
testParameterize(
listOf("a1", "b1", "b2", "c1", "c2", "c3")
) {
var secondCount = 1 // Based on first: a=1, b=2, ...

class SecondIterator : Iterator<Int> {
var nextInt: Int = 1
override fun hasNext(): Boolean = nextInt <= secondCount
override fun next(): Int = nextInt++
}

val first by parameterOf('a', 'b', 'c')
val second by parameter(Iterable(::SecondIterator))

useParameter(second)
useParameter(first)

secondCount = first - 'a' + 1

"$first$second"
}
}

@Test
fun parameters_that_are_used_out_of_order_should_iterate_in_declaration_order_contrived() = testParameterize(
fun parameters_that_are_used_out_of_order_should_iterate_in_declaration_order() = testParameterize(
listOf("a1", "a2", "b1", "b2")
) {
// Because they should iterate in the order their arguments are calculated, and that happens at declaration.
Expand All @@ -250,22 +205,12 @@ class ParameterizeSpec {
// way around, and the depended on parameter iterates first, the dependent parameter's argument would be based
// on a now changed value and wouldn't be valid.

var secondCount = 1 // Based on `first`: a=1, b=2, ...

class SecondIterator : Iterator<Int> {
var nextInt: Int = 1
override fun hasNext(): Boolean = nextInt <= secondCount
override fun next(): Int = nextInt++
}

val first by parameterOf('a', 'b', 'c')
val second by parameter(Iterable(::SecondIterator))
val first by parameterOf("a", "b")
val second by parameterOf(1, 2)

useParameter(second)
useParameter(first)

secondCount = first - 'a' + 1

"$first$second"
}

Expand Down

0 comments on commit e039271

Please sign in to comment.