266 lines
7.4 KiB
Dart
266 lines
7.4 KiB
Dart
import 'tl_token.dart';
|
|
|
|
class TlSchema {
|
|
final List<TlSchemeAbstractClass> abstractClasses;
|
|
final List<TlSchemeObject> objects;
|
|
final List<TlSchemeFunction> functions;
|
|
|
|
TlSchema({
|
|
required this.abstractClasses,
|
|
required this.objects,
|
|
required this.functions,
|
|
});
|
|
|
|
TlSchemeItem? findType(String type) {
|
|
TlSchemeItem? find(List<TlSchemeItem> list) {
|
|
for (final item in list) {
|
|
if (item.name == type) {
|
|
return item;
|
|
}
|
|
}
|
|
}
|
|
|
|
return find(abstractClasses) ?? find(objects) ?? find(functions);
|
|
}
|
|
|
|
factory TlSchema.parse(String file) {
|
|
var abstractClasses = <String, TlSchemeAbstractClass>{};
|
|
var objects = <String, TlSchemeObject>{};
|
|
var functions = <String, TlSchemeFunction>{};
|
|
|
|
var comments = <TlTokenCommentTag>[];
|
|
|
|
void finishBuilder(_TlSchemeItemBuilder builder) {
|
|
comments.clear();
|
|
if (builder is _TlSchemeAbstractClassBuilder) {
|
|
final ac = builder.build();
|
|
abstractClasses[ac.name] = ac;
|
|
}
|
|
else if (builder is _TlSchemeObjectBuilder) {
|
|
final obj = builder.build();
|
|
objects[obj.name] = obj;
|
|
if (!abstractClasses.containsKey(obj.baseType)) {
|
|
abstractClasses[obj.baseType] = TlSchemeAbstractClass(
|
|
name: obj.baseType,
|
|
doc: ''
|
|
);
|
|
}
|
|
}
|
|
else if (builder is _TlSchemeFunctionBuilder) {
|
|
final fn = builder.build();
|
|
functions[fn.name] = fn;
|
|
}
|
|
else {
|
|
throw Exception('Unknown builder: $builder');
|
|
}
|
|
}
|
|
|
|
var buildingFunctions = false;
|
|
_TlSchemeItemBuilder? builder;
|
|
|
|
for (final token in TlToken.tokenize(file)) {
|
|
if (token is TlTokenNone) {
|
|
if (builder != null) {
|
|
finishBuilder(builder);
|
|
}
|
|
builder = null;
|
|
}
|
|
else if (token is TlTokenFunctionsDelimiter) {
|
|
buildingFunctions = true;
|
|
}
|
|
else if (token is TlTokenCommentTag) {
|
|
if (token.name == 'class' && comments.isEmpty && builder == null) {
|
|
builder = _TlSchemeAbstractClassBuilder(
|
|
name: token.value,
|
|
);
|
|
}
|
|
else if (builder is _TlSchemeAbstractClassBuilder && token.name == 'description') {
|
|
builder.doc = token.value;
|
|
}
|
|
else {
|
|
comments.add(token);
|
|
}
|
|
}
|
|
else if (token is TlTokenClassTag) {
|
|
// Check for skippable
|
|
final skippable = [
|
|
'double',
|
|
'string',
|
|
'int32',
|
|
'int53',
|
|
'int64',
|
|
'bytes',
|
|
'boolFalse',
|
|
'boolTrue',
|
|
'vector',
|
|
];
|
|
if (skippable.contains(token.name)) {
|
|
comments.clear();
|
|
builder = null;
|
|
continue;
|
|
}
|
|
|
|
var typeDoc = '';
|
|
var paramDoc = <String, String>{};
|
|
|
|
for (final comment in comments) {
|
|
if (comment.name == 'description') {
|
|
typeDoc = comment.value;
|
|
}
|
|
else if (comment.name == 'param_description') {
|
|
paramDoc['description'] = comment.value;
|
|
}
|
|
else {
|
|
paramDoc[comment.name] = comment.value;
|
|
}
|
|
}
|
|
|
|
if (buildingFunctions) {
|
|
builder = _TlSchemeFunctionBuilder(
|
|
returnType: token.baseType,
|
|
name: token.name,
|
|
doc: typeDoc,
|
|
parameters: token.parameters.map((t) => _TlSchemeParamBuilder(
|
|
name: t.name,
|
|
type: t.type,
|
|
doc: paramDoc[t.name]!,
|
|
)).toList(growable: false),
|
|
);
|
|
}
|
|
else {
|
|
builder = _TlSchemeObjectBuilder(
|
|
baseType: token.baseType,
|
|
name: token.name,
|
|
doc: typeDoc,
|
|
parameters: token.parameters.map((t) => _TlSchemeParamBuilder(
|
|
name: t.name,
|
|
type: t.type,
|
|
doc: paramDoc[t.name]!,
|
|
)).toList(growable: false),
|
|
);
|
|
}
|
|
finishBuilder(builder);
|
|
builder = null;
|
|
}
|
|
}
|
|
|
|
return TlSchema(
|
|
abstractClasses: abstractClasses.values.toList(growable: false),
|
|
objects: objects.values.toList(growable: false),
|
|
functions: functions.values.toList(growable: false),
|
|
);
|
|
}
|
|
}
|
|
|
|
abstract class TlSchemeItem {
|
|
final String name;
|
|
final String doc;
|
|
TlSchemeItem({required this.name, required this.doc});
|
|
}
|
|
abstract class _TlSchemeItemBuilder<T extends TlSchemeItem> {
|
|
T build();
|
|
}
|
|
|
|
class TlSchemeAbstractClass extends TlSchemeItem {
|
|
TlSchemeAbstractClass({required String name, required String doc})
|
|
: super(name: name, doc: doc);
|
|
|
|
@override
|
|
String toString() {
|
|
return 'abstract $name';
|
|
}
|
|
}
|
|
class _TlSchemeAbstractClassBuilder extends _TlSchemeItemBuilder<TlSchemeAbstractClass> {
|
|
String name;
|
|
String doc;
|
|
_TlSchemeAbstractClassBuilder({this.name = '', this.doc = ''});
|
|
@override
|
|
TlSchemeAbstractClass build() => TlSchemeAbstractClass(name: name, doc: doc);
|
|
}
|
|
|
|
class TlSchemeObject extends TlSchemeItem {
|
|
final String baseType;
|
|
final List<TlSchemeParam> parameters;
|
|
TlSchemeObject({
|
|
required this.baseType,
|
|
required String name,
|
|
required String doc,
|
|
required this.parameters,
|
|
}) : super(name: name, doc: doc);
|
|
|
|
@override
|
|
String toString() {
|
|
return 'class $name(${parameters.join(', ')}) : $baseType';
|
|
}
|
|
}
|
|
class _TlSchemeObjectBuilder extends _TlSchemeItemBuilder<TlSchemeObject> {
|
|
String baseType;
|
|
String name;
|
|
String doc;
|
|
List<_TlSchemeParamBuilder> parameters;
|
|
_TlSchemeObjectBuilder({
|
|
this.baseType = '',
|
|
this.name = '',
|
|
this.doc = '',
|
|
this.parameters = const <_TlSchemeParamBuilder>[]
|
|
});
|
|
@override
|
|
TlSchemeObject build() => TlSchemeObject(
|
|
baseType: baseType,
|
|
name: name,
|
|
doc: doc,
|
|
parameters: parameters.map((b) => b.build()).toList(growable: false),
|
|
);
|
|
}
|
|
|
|
class TlSchemeFunction extends TlSchemeItem {
|
|
final String returnType;
|
|
final List<TlSchemeParam> parameters;
|
|
TlSchemeFunction({
|
|
required this.returnType,
|
|
required String name,
|
|
required String doc,
|
|
required this.parameters,
|
|
}) : super(name: name, doc: doc);
|
|
@override
|
|
String toString() {
|
|
return 'fn $name(${parameters.join(', ')}) -> $returnType';
|
|
}
|
|
}
|
|
class _TlSchemeFunctionBuilder extends _TlSchemeItemBuilder<TlSchemeFunction> {
|
|
String returnType;
|
|
String name;
|
|
String doc;
|
|
List<_TlSchemeParamBuilder> parameters;
|
|
_TlSchemeFunctionBuilder({
|
|
this.returnType = '',
|
|
this.name = '',
|
|
this.doc = '',
|
|
this.parameters = const <_TlSchemeParamBuilder>[]
|
|
});
|
|
@override
|
|
TlSchemeFunction build() => TlSchemeFunction(
|
|
returnType: returnType,
|
|
name: name,
|
|
doc: doc,
|
|
parameters: parameters.map((b) => b.build()).toList(growable: false),
|
|
);
|
|
}
|
|
|
|
class TlSchemeParam {
|
|
final String name;
|
|
final String type;
|
|
final String doc;
|
|
TlSchemeParam({required this.name, required this.type, required this.doc});
|
|
@override
|
|
String toString() {
|
|
return '$name: $type';
|
|
}
|
|
}
|
|
class _TlSchemeParamBuilder {
|
|
String name;
|
|
String type;
|
|
String doc;
|
|
_TlSchemeParamBuilder({this.name = '', this.type = '', this.doc = ''});
|
|
TlSchemeParam build() => TlSchemeParam(name: name, type: type, doc: doc);
|
|
}
|