Reputation: 2264
I'm working on a builder package and would like access to the class name defined as the super constraint. When first building, it won't exist so I'm guessing source_gen
just excludes it from its analysis
For example, considering I require the user to define
@fireproof
class User extends _$User {
final UserBase data;
User({
required this.data,
required DocumentSnapshot snapshot,
}) : super(snapshot);
factory User.fromSnapshot(DocumentSnapshot snapshot) =>
_$UserFromSnapshot(snapshot);
}
How do I get the name of the as yet undefined class _$User
? I want to be dynamic so even if the user decides to name it something else I can adapt to that name.
I've tried most fields on the element but can't find anything that would give me it:
@override
FutureOr<String> generateForAnnotatedElement(
Element element,
ConstantReader annotation,
BuildStep buildStep,
) async {
final classElement = element as ClassElement;
classElement.supertype; // Object
classElement.displayName; // class User
// I want _$User somehow
}
Maybe the answer involves getting the ast but I'm not super experienced with that.
Upvotes: 0
Views: 232
Reputation: 2264
I was poking around freezed
and I found a helper function that lets you get the the ast node of an element.
Future<AstNode> tryGetAstNodeForElement(
Element element,
BuildStep buildStep,
) async {
var library = element.library!;
while (true) {
try {
return library.session
.getParsedLibraryByElement(library)
.getElementDeclaration(element)!
.node;
} on InconsistentAnalysisException {
library = await buildStep.resolver.libraryFor(
await buildStep.resolver.assetIdForElement(element.library!),
);
}
}
}
Using that function you can the ast node and then you can iterate through its children looking for the pattern you want. In freezed
, it goes like this
Token? equalToken = ast.endToken;
while (true) {
if (equalToken == null ||
equalToken.charOffset < constructor.nameOffset) {
return null;
}
if (equalToken.stringValue == '=>') return null;
if (equalToken.stringValue == '=') {
break;
}
equalToken = equalToken.previous;
}
so they go through the tokens backwards until they find that the token equals the token they want (the equal token that they then use to get the redirected constructor).
In my case, I'd just look for the closing and opening <
>
for the types and store the inner types as string. AST doesn't disregard undefined tokens.
All credit goes to Rémi Rousselet and his package
Upvotes: 0