140 lines
4.1 KiB
Dart
140 lines
4.1 KiB
Dart
|
abstract class TlToken {
|
||
|
static Iterable<TlToken> tokenize(String file) sync* {
|
||
|
var lastWasNone = false;
|
||
|
for (final untrimmedLine in file.split(RegExp(r'[\r\n]'))) {
|
||
|
final line = untrimmedLine.trim();
|
||
|
if (line.isEmpty) {
|
||
|
if (!lastWasNone) {
|
||
|
yield TlTokenNone();
|
||
|
lastWasNone = true;
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
else {
|
||
|
lastWasNone = false;
|
||
|
if (line.startsWith('//')) {
|
||
|
// Comment
|
||
|
if (!line.contains('@')) {
|
||
|
yield TlTokenCommentLine(line);
|
||
|
continue;
|
||
|
}
|
||
|
// Skip to first @tag
|
||
|
final interestLine = line.substring(line.indexOf('@'));
|
||
|
for (final unTrimmedTaggedChunk in interestLine.split('@')) {
|
||
|
final taggedChunk = unTrimmedTaggedChunk.trim();
|
||
|
if (taggedChunk.isEmpty) {
|
||
|
continue;
|
||
|
}
|
||
|
final firstWs = taggedChunk.indexOf(RegExp(r'\s'));
|
||
|
final tagName = taggedChunk.substring(0, firstWs);
|
||
|
final tagValue = taggedChunk.substring(firstWs).trim();
|
||
|
yield TlTokenCommentTag(name: tagName, value: tagValue);
|
||
|
}
|
||
|
}
|
||
|
else if (line == '---functions---') {
|
||
|
yield TlTokenFunctionsDelimiter();
|
||
|
}
|
||
|
else {
|
||
|
// class
|
||
|
// Split by space
|
||
|
final chunksIt = line.split(RegExp(r'\s+')).iterator;
|
||
|
// First is name
|
||
|
chunksIt.moveNext();
|
||
|
final name = chunksIt.current;
|
||
|
// Then there are parameters until =
|
||
|
final parameters = <TlTokenClassParam>[];
|
||
|
do {
|
||
|
chunksIt.moveNext();
|
||
|
if (chunksIt.current == '=') {
|
||
|
break;
|
||
|
}
|
||
|
// Params are defined as name:type
|
||
|
// Ignore oddities
|
||
|
if (!chunksIt.current.contains(':')) {
|
||
|
continue;
|
||
|
}
|
||
|
final splitted = chunksIt.current.split(':');
|
||
|
parameters.add(TlTokenClassParam(
|
||
|
name: splitted[0],
|
||
|
type: splitted[1]
|
||
|
));
|
||
|
} while (true);
|
||
|
// Finally, there is the base type (abstract class)
|
||
|
chunksIt.moveNext();
|
||
|
String removeSemicolon(String input) {
|
||
|
while (input.codeUnits.last == ';'.codeUnits[0]) {
|
||
|
input = input.substring(0, input.length - 1);
|
||
|
}
|
||
|
return input;
|
||
|
}
|
||
|
final baseType = removeSemicolon(chunksIt.current);
|
||
|
|
||
|
yield TlTokenClassTag(
|
||
|
name: name,
|
||
|
parameters: parameters,
|
||
|
baseType: baseType,
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
class TlTokenFunctionsDelimiter extends TlToken {
|
||
|
@override
|
||
|
String toString() {
|
||
|
return 'TlToken: ---functions---';
|
||
|
}
|
||
|
}
|
||
|
class TlTokenNone extends TlToken {
|
||
|
@override
|
||
|
String toString() {
|
||
|
return 'TlToken.';
|
||
|
}
|
||
|
}
|
||
|
class TlTokenCommentLine extends TlToken {
|
||
|
/// The content of the comment including the leading slashes
|
||
|
final String content;
|
||
|
TlTokenCommentLine(this.content);
|
||
|
|
||
|
@override
|
||
|
String toString() {
|
||
|
return 'TlToken: //$content';
|
||
|
}
|
||
|
}
|
||
|
class TlTokenCommentTag extends TlToken {
|
||
|
/// The name of the tag, excluding the ampersand: description
|
||
|
final String name;
|
||
|
/// The value of the tag: Provides ...
|
||
|
final String value;
|
||
|
|
||
|
TlTokenCommentTag({required this.name, required this.value});
|
||
|
|
||
|
@override
|
||
|
String toString() {
|
||
|
return 'TlToken: //@$name $value';
|
||
|
}
|
||
|
}
|
||
|
class TlTokenClassTag extends TlToken {
|
||
|
/// The name of the class
|
||
|
final String name;
|
||
|
final List<TlTokenClassParam> parameters;
|
||
|
final String baseType;
|
||
|
TlTokenClassTag({required this.name, required this.parameters, required this.baseType});
|
||
|
|
||
|
@override
|
||
|
String toString() {
|
||
|
final params = parameters.join(', ');
|
||
|
return 'TlToken: $name($params) = $baseType';
|
||
|
}
|
||
|
}
|
||
|
class TlTokenClassParam {
|
||
|
final String name;
|
||
|
final String type;
|
||
|
TlTokenClassParam({required this.name, required this.type});
|
||
|
|
||
|
@override
|
||
|
String toString() {
|
||
|
return '$name:$type';
|
||
|
}
|
||
|
}
|