Readonly round 2

This commit is contained in:
yairm210 2025-07-11 15:16:44 +03:00
parent 694354af09
commit 4819cf1053
5 changed files with 20 additions and 3 deletions

View File

@ -45,10 +45,13 @@ allprojects {
apply(plugin = "io.github.yairm210.purity-plugin")
configure<yairm210.purity.PurityConfiguration>{
wellKnownPureFunctions = setOf("kotlin.internal.ir.CHECK_NOT_NULL")
wellKnownPureFunctions = setOf()
wellKnownReadonlyFunctions = setOf(
"kotlin.collections.any",
"kotlin.collections.Iterator.hasNext"
"kotlin.collections.all",
"kotlin.ranges.coerceAtLeast",
// Looks like the Collection.contains is not considered overridden :thunk:
"java.util.AbstractCollection.contains",
)
}

View File

@ -1,5 +1,7 @@
package com.unciv.logic
import org.jetbrains.annotations.Contract
object MultiFilter {
private const val andPrefix = "{"
private const val andSeparator = "} {"
@ -17,6 +19,7 @@ object MultiFilter {
* @param filterFunction The single filter implementation
* @param forUniqueValidityTests Inverts the `non-[filter]` test because Unique validity doesn't check for actual matching
*/
@Contract("readonly") @Suppress("purity")
fun multiFilter(
input: String,
filterFunction: (String) -> Boolean,
@ -33,6 +36,7 @@ object MultiFilter {
return filterFunction(input)
}
@Contract("readonly")
fun getAllSingleFilters(input: String): Sequence<String> = when {
input.hasSurrounding(andPrefix, andSuffix) && input.contains(andSeparator) ->
// Resolve "AND" filters
@ -45,6 +49,7 @@ object MultiFilter {
else -> sequenceOf(input)
}
@Contract("readonly")
fun String.hasSurrounding(prefix: String, suffix: String) =
startsWith(prefix) && endsWith(suffix)
}

View File

@ -28,6 +28,7 @@ import com.unciv.models.stats.GameResource
import com.unciv.models.stats.INamed
import com.unciv.models.stats.Stat
import com.unciv.models.stats.SubStat
import org.jetbrains.annotations.Contract
import java.util.UUID
import kotlin.math.roundToInt
@ -169,6 +170,7 @@ class City : IsPartOfGameInfoSerialization, INamed {
fun getCenterTileOrNull(): Tile? = if (::centerTile.isInitialized) centerTile else null
fun getTiles(): Sequence<Tile> = tiles.asSequence().map { tileMap[it] }
fun getWorkableTiles() = tilesInRange.asSequence().filter { it.getOwner() == civ }
@Contract("readonly")
fun isWorked(tile: Tile) = workedTiles.contains(tile.position)
fun isCapital(): Boolean = cityConstructions.builtBuildingUniqueMap.hasUnique(UniqueType.IndicatesCapital, state)

View File

@ -34,6 +34,7 @@ import com.unciv.utils.DebugUtils
import com.unciv.utils.Log
import com.unciv.utils.withItem
import com.unciv.utils.withoutItem
import org.jetbrains.annotations.Contract
import kotlin.collections.ArrayList
import kotlin.collections.HashSet
import kotlin.math.abs
@ -257,6 +258,7 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
return null
}
@Contract("readonly")
fun getCity(): City? = owningCity
internal fun getNaturalWonder(): Terrain =
@ -351,6 +353,7 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
fun getBaseTerrain(): Terrain = baseTerrainObject
@Contract("readonly")
fun getOwner(): Civilization? = getCity()?.civ
fun getRoadOwner(): Civilization? {
@ -401,6 +404,7 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
return uniques
}
@Contract("readonly")
fun getWorkingCity(): City? {
val civInfo = getOwner() ?: return null
if (owningCity?.isWorked(this) == true) return owningCity // common case
@ -433,6 +437,7 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
return false
}
@Contract("readonly")
fun isWorked(): Boolean = getWorkingCity() != null
fun providesYield(): Boolean {
if (getCity() == null) return false
@ -481,10 +486,12 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
}
/** Implements [UniqueParameterType.TileFilter][com.unciv.models.ruleset.unique.UniqueParameterType.TileFilter] */
@Contract("readonly")
fun matchesFilter(filter: String, civInfo: Civilization? = null): Boolean {
return MultiFilter.multiFilter(filter, { matchesSingleFilter(it, civInfo) })
}
@Contract("readonly") @Suppress("purity")
private fun matchesSingleFilter(filter: String, civInfo: Civilization? = null): Boolean {
if (matchesSingleTerrainFilter(filter, civInfo)) return true
if ((improvement == null || improvementIsPillaged) && filter == "unimproved") return true

View File

@ -96,7 +96,7 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
return true
}
@Contract("readonly") @Suppress("purity")
@Contract("readonly")
private fun getUniqueMultiplier(stateForConditionals: StateForConditionals): Int {
if (stateForConditionals == StateForConditionals.IgnoreMultiplicationForCaching)
return 1