generateForAnnotatedElement method
dynamic
generateForAnnotatedElement(
- Element element,
- ConstantReader annotation,
- BuildStep buildStep,
- List<
ClassElement> allClasses,
Implementation
@override
dynamic generateForAnnotatedElement(
Element element,
ConstantReader annotation,
BuildStep buildStep,
List<ClassElement> allClasses,
) {
var sb = StringBuffer();
if (element is! ClassElement) {
throw Exception("not a class");
}
var classElement = element;
var className = classElement.name ?? "";
_allAnnotatedClasses[className] = classElement;
var hasConstConstructor = classElement.constructors.any((e) => e.isConst);
var nonSealed = annotation.read('nonSealed').boolValue;
var isAbstract = className.startsWith("\$\$") && !nonSealed;
if (classElement.supertype?.element.name != "Object") {
throw Exception("you must use implements, not extends");
}
var docComment = classElement.documentationComment;
var allInterfaces = <InterfaceType>[];
var processedInterfaces = <String>{};
void addInterface(InterfaceType interface) {
var interfaceName = interface.element.name ?? "";
if (interfaceName == "Object" || interfaceName == "Enum") return;
if (processedInterfaces.contains(interfaceName)) return;
processedInterfaces.add(interfaceName);
allInterfaces.add(interface);
for (var supertype in interface.element.allSupertypes) {
addInterface(supertype);
}
}
for (var supertype in classElement.allSupertypes) {
addInterface(supertype);
}
var interfaces = allInterfaces.map((e) {
var interfaceName = e.element.name ?? "";
var implementedName = interfaceName.startsWith("\$\$")
? interfaceName.replaceAll("\$\$", "")
: interfaceName.replaceAll("\$", "");
return InterfaceWithComment(
implementedName,
e.typeArguments.map(typeToString).toList(),
e.element.typeParameters.map((x) => x.name ?? "").toList(),
e.element.fields
.map((f) => NameType(f.name ?? "", typeToString(f.type)))
.toList(),
comment: e.element.documentationComment,
isSealed: interfaceName.startsWith("\$\$"),
hidePublicConstructor: false,
);
}).toList();
var allFields = getAllFieldsIncludingSubtypes(classElement);
var allFieldsDistinct = getDistinctFields(allFields, interfaces);
var classGenerics = classElement.typeParameters.map((e) {
final bound = e.bound;
return NameTypeClassComment(
e.name ?? "",
bound == null ? null : typeToString(bound),
null,
);
}).toList();
var typesExplicit = <Interface>[];
if (!annotation.read('explicitSubTypes').isNull) {
typesExplicit = annotation.read('explicitSubTypes').listValue.map((x) {
var typeValue = x.toTypeValue();
if (typeValue?.element is! ClassElement) {
throw Exception("each type for the copywith def must all be classes");
}
var el = typeValue!.element as ClassElement;
_allAnnotatedClasses[el.name ?? ""] = el;
var fields = getAllFieldsIncludingSubtypes(
el,
).where((f) => f.name != "hashCode").toList();
var nameTypeFields = fields
.map((f) => NameType(f.name, f.type ?? ""))
.toList();
return Interface.fromGenerics(
el.name ?? "",
el.typeParameters.map((tp) {
final bound = tp.bound;
return NameType(
tp.name ?? "",
bound == null ? null : typeToString(bound),
);
}).toList(),
nameTypeFields,
true,
);
}).toList();
}
var allValueTInterfaces = allInterfaces
.map((e) {
var interfaceName = e.element.name ?? "";
var fields = getAllFieldsIncludingSubtypes(
e.element as ClassElement,
).where((f) => f.name != "hashCode").toList();
var nameTypeFields = fields
.map((f) => NameType(f.name, f.type ?? ""))
.toList();
return Interface.fromGenerics(
interfaceName.startsWith("\$\$")
? interfaceName.replaceAll("\$\$", "")
: interfaceName.replaceAll("\$", ""),
e.typeArguments.asMap().entries.map((entry) {
final index = entry.key;
final typeArg = entry.value;
final paramName = e.element.typeParameters.length > index
? e.element.typeParameters[index].name ??
"T" + index.toString()
: "T" + index.toString();
return NameType(paramName, typeToString(typeArg));
}).toList(),
nameTypeFields,
false,
interfaceName.startsWith("\$\$"),
false,
);
})
.cast<Interface>()
.toList();
sb.writeln(
createZorphy(
isAbstract,
allFieldsDistinct,
className,
docComment ?? "",
interfaces,
allValueTInterfaces,
classGenerics,
hasConstConstructor,
annotation.read('generateJson').boolValue,
annotation.read('hidePublicConstructor').boolValue,
typesExplicit,
nonSealed,
annotation.read('explicitToJson').boolValue,
annotation.read('generateCompareTo').boolValue,
annotation.read('generateCopyWithFn').boolValue,
[],
_allAnnotatedClasses,
{}, // ownFields - empty for builder2
),
);
return sb.toString();
}