in lib/src/builder.dart [1268:1350]
Expression _expressionFromDartObject(DartObject object,
[ParameterElement? parameter]) {
final constant = ConstantReader(object);
if (constant.isNull) {
return literalNull;
} else if (constant.isBool) {
return literalBool(constant.boolValue);
} else if (constant.isDouble) {
return literalNum(constant.doubleValue);
} else if (constant.isInt) {
return literalNum(constant.intValue);
} else if (constant.isString) {
return literalString(constant.stringValue, raw: true);
} else if (constant.isList) {
return literalConstList([
for (var element in constant.listValue)
_expressionFromDartObject(element)
]);
} else if (constant.isMap) {
return literalConstMap({
for (var pair in constant.mapValue.entries)
_expressionFromDartObject(pair.key!):
_expressionFromDartObject(pair.value!)
});
} else if (constant.isSet) {
return literalConstSet({
for (var element in constant.setValue)
_expressionFromDartObject(element)
});
} else if (constant.isType) {
// TODO(srawlins): It seems like this might be revivable, but Angular
// does not revive Types; we should investigate this if users request it.
var type = object.toTypeValue()!;
var typeStr = type.getDisplayString(withNullability: false);
throw _ReviveException('default value is a Type: $typeStr.');
} else {
// If [constant] is not null, a literal, or a type, then it must be an
// object constructed with `const`. Revive it.
var revivable = constant.revive();
if (revivable.isPrivate) {
final privateReference = revivable.accessor.isNotEmpty
? '${revivable.source}::${revivable.accessor}'
: '${revivable.source}';
throw _ReviveException(
'default value has a private type: $privateReference.');
}
if (object.toFunctionValue() != null) {
// A top-level function, like `void f() {}` must be referenced by its
// identifier, rather than a revived value.
var element = object.toFunctionValue();
return referImported(revivable.accessor, _typeImport(element));
} else if (revivable.source.fragment.isEmpty) {
// We can create this invocation by referring to a const field or
// top-level variable.
return referImported(
revivable.accessor, _typeImport(object.type!.element));
}
final name = revivable.source.fragment;
final positionalArgs = [
for (var argument in revivable.positionalArguments)
_expressionFromDartObject(argument)
];
final namedArgs = {
for (var pair in revivable.namedArguments.entries)
pair.key: _expressionFromDartObject(pair.value)
};
final element = parameter != null && name != object.type!.element!.name
? parameter.type.element
: object.type!.element;
final type = referImported(name, _typeImport(element));
if (revivable.accessor.isNotEmpty) {
return type.constInstanceNamed(
revivable.accessor,
positionalArgs,
namedArgs,
// No type arguments. See
// https://github.com/dart-lang/source_gen/issues/478.
);
}
return type.constInstance(positionalArgs, namedArgs);
}
}