generateForAnnotatedElement method
- Element element,
- ConstantReader annotation,
- BuildStep buildStep
override
Implement to return source code to generate for element
.
This method is invoked based on finding elements annotated with an
instance of T
. The annotation
is provided as a ConstantReader.
Supported return values include a single String or multiple String instances within an Iterable or Stream. It is also valid to return a Future of String, Iterable, or Stream.
Implementations should return null
when no content is generated. Empty
or whitespace-only String instances are also ignored.
Implementation
@override
generateForAnnotatedElement(Element element, ConstantReader annotation, BuildStep buildStep) {
if (element is! ClassElement) {
throw InvalidGenerationSourceError("Lexer annotation is only valid for classes.");
}
int startState = annotation.read(_startStateField).intValue;
String classname = element.name;
List<MethodElement> children = element.methods;
List<(MethodElement, Rule)> rules = [];
for (var child in children) {
var rule = _ruleChecker.firstAnnotationOfExact(child);
if (rule != null) {
rules.add((child, Rule(rule.getField(_patternField)!.toStringValue()!, rule.getField(_priorityField)!.toIntValue()!,
state: rule.getField(_stateField)!.toIntValue())));
}
}
{
for (var r in rules) {
if (r.$2.pattern.isEmpty) {
throw InvalidGenerationSourceError("Rule has empty pattern: ${r.$1.name}");
}
}
}
var ruleLists = rules.groupListsBy((e) => e.$2.priority);
List<int> priorities = ruleLists.keys.sorted((a, b) => b - a).toList();
String rulesString = "";
for (int k in priorities) {
rulesString +=
"[${ruleLists[k]!.map((e) => _ruleToString(e.$2, e.$1.name)).reduce((value,
element) => "$value, $element")}],";
}
rulesString = "[$rulesString]";
String classCode = "abstract class _$classname<T extends Token> extends LexerBase<T> {\n";
for (var r in rules) {
classCode += "TokenResponse<T> ${r.$1.name}(String token, int line, int char, int index);\n";
}
classCode += "_$classname() : super($startState) {rules = $rulesString;}\n";
classCode += "}";
return classCode;
}