getBestConstructorsFor method
List<ConstructorReflection<O> >
getBestConstructorsFor({
- Iterable<
String> requiredParameters = const <String>[], - Iterable<
String> optionalParameters = const <String>[], - Iterable<
String> nullableParameters = const <String>[], - Iterable<
String> presentParameters = const <String>[], - bool allowEmptyConstructors = true,
- bool allowOptionalOnlyConstructors = true,
- bool jsonName = false,
Returns a List of the best ConstructorReflection for requiredParameters, optionalParameters,
nullableParameters and presentParameters.
Implementation
List<ConstructorReflection<O>> getBestConstructorsFor({
Iterable<String> requiredParameters = const <String>[],
Iterable<String> optionalParameters = const <String>[],
Iterable<String> nullableParameters = const <String>[],
Iterable<String> presentParameters = const <String>[],
bool allowEmptyConstructors = true,
bool allowOptionalOnlyConstructors = true,
bool jsonName = false,
}) {
if (nullableParameters is! List && nullableParameters is! Set) {
nullableParameters = nullableParameters.toList(growable: false);
}
var constructors = allConstructors().toList();
if (constructors.isEmpty) return <ConstructorReflection<O>>[];
if (!allowEmptyConstructors) {
var emptyConstructors = constructors
.where((c) => c.parametersLength == 0)
.toList();
if (emptyConstructors.isNotEmpty) {
constructors = constructors
.where((c) => !emptyConstructors.contains(c))
.toList();
}
if (constructors.isEmpty) return <ConstructorReflection<O>>[];
}
if (!allowOptionalOnlyConstructors) {
var optionalOnlyConstructors = constructors
.where(
(c) =>
(c.normalParameters.isEmpty &&
c.optionalParameters.none((c) => c.required) &&
c.namedParameters.values.none((c) => c.required)),
)
.toList();
if (optionalOnlyConstructors.isNotEmpty) {
constructors = constructors
.where((c) => !optionalOnlyConstructors.contains(c))
.toList();
}
if (constructors.isEmpty) return <ConstructorReflection<O>>[];
}
var presentParametersResolved = presentParameters.toSet();
String paramNameResolver(ParameterReflection p, String name) {
var f = field(p.name);
var alias = f?.jsonFieldAliasAnnotations.alias;
return alias ?? name;
}
var paramNameResolverJson = jsonName ? paramNameResolver : null;
var invalidConstructors = constructors.where((c) {
var paramsRequired = c
.parametersNamesWhere(
(p) => p.required && !p.nullable,
jsonName: jsonName,
nameResolver: paramNameResolverJson,
)
.toList();
return _elementsInCount(
presentParameters,
paramsRequired,
_nameNormalizer,
) <
paramsRequired.length;
}).toList();
if (invalidConstructors.isNotEmpty) {
constructors = constructors
.where((c) => !invalidConstructors.contains(c))
.toList();
if (constructors.isEmpty) return <ConstructorReflection<O>>[];
}
if (requiredParameters.isNotEmpty) {
var constructorsWithRequired = constructors.where((c) {
var paramsAll = c
.parametersNamesWhere(
(p) => true,
jsonName: jsonName,
nameResolver: paramNameResolverJson,
)
.toList();
return _elementsInCount<String>(
requiredParameters,
paramsAll,
_nameNormalizer,
) ==
requiredParameters.length;
}).toList();
constructors = constructorsWithRequired;
if (constructors.isEmpty) return <ConstructorReflection<O>>[];
presentParametersResolved.addAll(requiredParameters);
}
if (nullableParameters.isNotEmpty) {
var constructorsWithNullables = constructors.where((c) {
var paramsNullable = c
.parametersNamesWhere(
(p) => p.nullable || !p.required,
jsonName: jsonName,
nameResolver: paramNameResolverJson,
)
.toList();
return _elementsInCount(
nullableParameters,
paramsNullable,
_nameNormalizer,
) ==
nullableParameters.length;
}).toList();
constructors = constructorsWithNullables;
if (constructors.isEmpty) return <ConstructorReflection<O>>[];
presentParametersResolved.addAll(nullableParameters);
}
presentParametersResolved.addAll(optionalParameters);
constructors = constructors.where((c) {
var paramsRequired = c
.parametersNamesWhere(
(p) => p.required,
jsonName: jsonName,
nameResolver: paramNameResolverJson,
)
.toList();
return _elementsInCount<String>(
presentParametersResolved,
paramsRequired,
_nameNormalizer,
) ==
paramsRequired.length;
}).toList();
if (constructors.length <= 1) {
return constructors;
}
var constructorsInfo = Map.fromEntries(
constructors.map((c) {
var requiredCount = c
.getParametersByNames(requiredParameters, jsonName: jsonName)
.length;
var optionalCount = c
.getParametersByNames(optionalParameters, jsonName: jsonName)
.length;
return MapEntry(c, [requiredCount, optionalCount]);
}),
);
constructors.sort((c1, c2) {
var i1 = constructorsInfo[c1]!;
var i2 = constructorsInfo[c2]!;
var req1 = i1[0];
var req2 = i2[0];
var cmp = req2.compareTo(req1);
if (cmp == 0) {
var opt1 = i1[1];
var opt2 = i2[1];
cmp = opt2.compareTo(opt1);
}
return cmp;
});
return constructors;
}