/*
* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
* This source file is part of the Cangjie project, licensed under Apache-2.0
* with Runtime Library Exception.
*
* See https://cangjie-lang.cn/pages/LICENSE for license information.
*/
protected package std.deriving.impl
import std.deriving.api.*
import std.ast.*
import std.collection.*
func settingsForClassLike(
inputOptions: InputOptions,
clazz: ClassLikeDecl,
logger: Logger
): SettingsOutput {
let allFields = clazz.allFields()
let allProperties = clazz.allProperties()
let includedSet = inputOptions.included |> collectHashSet
let excludedSet = inputOptions.excluded |> collectHashSet
let allFieldsMap = allFields |> associateBy<TargetNamedAttribute> { f => f.identifier }
let excludedFields = excludedSet |>
mapNotNone { id: Identifier => allFieldsMap.get(id) } |>
collectArray
let includedProperties = allProperties |> filter<PropDecl> { p =>
includedSet.contains(Identifier(p.identifier))
} |> collectArray
let orderedFields = if (inputOptions.ordering.isEmpty()) {
allFields |> filterFields(includedSet, excludedSet) |> collectArray
} else {
applyFieldsOrder(allFieldsMap, inputOptions.ordering, includedSet, excludedSet)
}
let interfaceSettings = mapInterfaceSettings(clazz.allGenerics(), inputOptions.origin, logger)
let settings = DerivingSettings(
interfaceSettings,
excludedFields,
[], // enum cases order
inputOptions.ordering,
includedProperties
)
let target = DerivingTarget(
inputOptions.decl,
orderedFields,
[], // enum cases
settings
)
return SettingsOutput(settings, target)
}
func applyFieldsOrder(
allFieldsMap: HashMap<Identifier, TargetNamedAttribute>,
userDefinedOrder: Array<Identifier>,
includedSet: HashSet<Identifier>,
excludedSet: HashSet<Identifier>
): Array<TargetNamedAttribute> {
// first collect fields and properties by the order defined by user
let ordered = userDefinedOrder |> mapNotNone<Identifier, TargetNamedAttribute> { id =>
allFieldsMap.get(id)
} |> filterFields(includedSet, excludedSet) |> collectArrayList
// after that append fields and properties that should be considered
// but missing in the user defined order list
// this is an error and it will be reported by diagnoseOrdering() at later stage
let missing = allFieldsMap.values() |>
filterFields(includedSet, excludedSet) |>
filter<TargetNamedAttribute> { field =>
!userDefinedOrder.contains(field.identifier)
} |> collectArrayList
ordered.add(all: missing)
return ordered.toArray()
}
func filterFields(
includedSet: HashSet<Identifier>,
excludedSet: HashSet<Identifier>
): (it: Iterable<TargetNamedAttribute>) -> Iterator<TargetNamedAttribute> {{ iter =>
iter |> filter<TargetNamedAttribute> { it =>
match (it) {
case PropertyAttribute(_) => includedSet.contains(it.identifier)
case ConstructorFieldAttribute(_) => !excludedSet.contains(it.identifier)
case FieldAttribute(_) => !excludedSet.contains(it.identifier)
}
}
}}