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;
}