Initial commit
This commit is contained in:
commit
a683a58db2
11 changed files with 1474 additions and 0 deletions
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Files and directories created by pub.
|
||||
.dart_tool/
|
||||
.packages
|
||||
|
||||
# Conventional directory for build output.
|
||||
build/
|
||||
# Dart default executable location
|
||||
bin/tdlib_gen.exe
|
||||
|
||||
# tl files
|
||||
*.tl
|
24
.vscode/launch.json
vendored
Normal file
24
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "tdlib_gen",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"program": "bin/tdlib_gen.dart",
|
||||
"args": [
|
||||
"${workspaceFolder}/td_api.tl",
|
||||
"${workspaceFolder}/../tdlib_types/lib"
|
||||
],
|
||||
"windows": {
|
||||
"args": [
|
||||
"${workspaceFolder}/td_api.tl",
|
||||
"${workspaceFolder}\\..\\tdlib_types\\lib"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
3
CHANGELOG.md
Normal file
3
CHANGELOG.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
## 1.0.0
|
||||
|
||||
- Initial version.
|
1
README.md
Normal file
1
README.md
Normal file
|
@ -0,0 +1 @@
|
|||
A simple command-line application.
|
16
analysis_options.yaml
Normal file
16
analysis_options.yaml
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Defines a default set of lint rules enforced for projects at Google. For
|
||||
# details and rationale, see
|
||||
# https://github.com/dart-lang/pedantic#enabled-lints.
|
||||
|
||||
include: package:pedantic/analysis_options.yaml
|
||||
|
||||
# For lint rules and documentation, see http://dart-lang.github.io/linter/lints.
|
||||
|
||||
# Uncomment to specify additional rules.
|
||||
# linter:
|
||||
# rules:
|
||||
# - camel_case_types
|
||||
|
||||
# analyzer:
|
||||
# exclude:
|
||||
# - path/to/excluded/files/**
|
549
bin/tdlib_gen.dart
Normal file
549
bin/tdlib_gen.dart
Normal file
|
@ -0,0 +1,549 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'tl_scheme.dart';
|
||||
|
||||
import 'package:recase/recase.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
Future<void> main(List<String> arguments) async {
|
||||
if (arguments.length != 2) {
|
||||
print('The program must be run with 2 arguments:');
|
||||
print(' path to .tl schema');
|
||||
print(' path to Dart project source folder');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
final schemeFileStr = arguments[0];
|
||||
final srcFolderStr = arguments[1];
|
||||
|
||||
if (! await File.fromUri(Uri.file(schemeFileStr)).exists()) {
|
||||
print("Schema file $schemeFileStr doesn't exist");
|
||||
exit(1);
|
||||
}
|
||||
if (! await Directory.fromUri(Uri.directory(srcFolderStr)).exists()) {
|
||||
print("Dart project source folder $srcFolderStr doesn't exist");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
print('.tl schema folder: $schemeFileStr');
|
||||
print('Dart project source folder: $srcFolderStr');
|
||||
print('');
|
||||
|
||||
print('Reading .tl schema file...');
|
||||
final schemeFileContents = await File.fromUri(Uri.file(schemeFileStr)).readAsString();
|
||||
print('Parsing .tl schema file...');
|
||||
final scheme = TlSchema.parse(schemeFileContents);
|
||||
|
||||
print('Generating...');
|
||||
|
||||
final baseFile = File.fromUri(Uri.file(path.join(srcFolderStr, 'base.dart')));
|
||||
final abstractFile = File.fromUri(Uri.file(path.join(srcFolderStr, 'abstract.dart')));
|
||||
final objFile = File.fromUri(Uri.file(path.join(srcFolderStr, 'obj.dart')));
|
||||
final fnFile = File.fromUri(Uri.file(path.join(srcFolderStr, 'fn.dart')));
|
||||
await baseFile.writeAsString(makeBaseFile(scheme));
|
||||
await abstractFile.writeAsString(makeAbstractFile(scheme));
|
||||
await objFile.writeAsString(makeObjFile(scheme));
|
||||
await fnFile.writeAsString(makeFnFile(scheme));
|
||||
|
||||
print('Done!');
|
||||
}
|
||||
|
||||
String findDartType(
|
||||
String type,
|
||||
TlSchema scheme,
|
||||
{String abstractPrefix = 'a.',
|
||||
String objectPrefix = 'o.',
|
||||
String functionPrefix = 'f.',
|
||||
bool noNullCheck = false}
|
||||
) {
|
||||
if (type.startsWith('vector<')) {
|
||||
final tmp1 = type.replaceFirst('vector<', '');
|
||||
final tmp2 = tmp1.substring(0, tmp1.length - 1);
|
||||
final innerType = findDartType(
|
||||
tmp2,
|
||||
scheme,
|
||||
abstractPrefix: abstractPrefix,
|
||||
functionPrefix: functionPrefix,
|
||||
objectPrefix: objectPrefix,
|
||||
);
|
||||
return 'List<$innerType>';
|
||||
}
|
||||
|
||||
final predefined = {
|
||||
'double': 'double',
|
||||
'string': 'String',
|
||||
'int32': 'int',
|
||||
'int53': 'int',
|
||||
'int64': 'int',
|
||||
'bytes': 'Uint8List',
|
||||
'Bool': 'bool',
|
||||
};
|
||||
|
||||
if (predefined.containsKey(type)) {
|
||||
return predefined[type]!;
|
||||
}
|
||||
|
||||
final result = scheme.findType(type);
|
||||
if (result == null) {
|
||||
throw Exception("Couldn't find type: $type");
|
||||
}
|
||||
|
||||
if (result is TlSchemeAbstractClass) {
|
||||
final name = abstractPrefix + result.name.pascalCase;
|
||||
if (noNullCheck) {
|
||||
return name;
|
||||
}
|
||||
else {
|
||||
return '$name?';
|
||||
}
|
||||
}
|
||||
else if (result is TlSchemeObject) {
|
||||
final name = objectPrefix + result.name.pascalCase;
|
||||
if (noNullCheck) {
|
||||
return name;
|
||||
}
|
||||
else {
|
||||
return '$name?';
|
||||
}
|
||||
}
|
||||
else if (result is TlSchemeFunction) {
|
||||
final name = functionPrefix + result.name.pascalCase;
|
||||
if (noNullCheck) {
|
||||
return name;
|
||||
}
|
||||
else {
|
||||
return '$name?';
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw Exception('Unknown tl object: $result');
|
||||
}
|
||||
}
|
||||
|
||||
String findToJsonHandling(
|
||||
String type,
|
||||
String varName,
|
||||
TlSchema scheme,
|
||||
) {
|
||||
if (type.startsWith('vector<')) {
|
||||
final tmp1 = type.replaceFirst('vector<', '');
|
||||
final tmp2 = tmp1.substring(0, tmp1.length - 1);
|
||||
late String newVarName;
|
||||
if (varName.startsWith('_e')) {
|
||||
final num = int.parse(varName.substring(2));
|
||||
newVarName = '_e${num + 1}';
|
||||
}
|
||||
else {
|
||||
newVarName = '_e1';
|
||||
}
|
||||
final innerHandling = findToJsonHandling(
|
||||
tmp2,
|
||||
newVarName,
|
||||
scheme,
|
||||
);
|
||||
return '$varName.map(($newVarName) => $innerHandling).toList(growable: false)';
|
||||
}
|
||||
|
||||
final predefined = {
|
||||
'double': 'double',
|
||||
'string': 'String',
|
||||
'int32': 'int',
|
||||
'int53': 'int',
|
||||
'Bool': 'bool',
|
||||
};
|
||||
if (predefined.containsKey(type)) {
|
||||
return varName;
|
||||
}
|
||||
else if (type == 'int64') {
|
||||
return '$varName.toString()';
|
||||
}
|
||||
else if (type == 'bytes') {
|
||||
return 'base64.encode($varName)';
|
||||
}
|
||||
else {
|
||||
return '$varName?.toJson()';
|
||||
}
|
||||
}
|
||||
|
||||
String findFromJsonHandling(
|
||||
String type,
|
||||
String keyName,
|
||||
TlSchema scheme,
|
||||
{String abstractPrefix = 'a.',
|
||||
String objectPrefix = 'o.',
|
||||
String functionPrefix = 'f.',
|
||||
String? varNameInsteadOfKeyName}
|
||||
) {
|
||||
if (type.startsWith('vector<')) {
|
||||
final tmp1 = type.replaceFirst('vector<', '');
|
||||
final tmp2 = tmp1.substring(0, tmp1.length - 1);
|
||||
// final innerType = findDartType(tmp2, scheme, abstractPrefix: abstractPrefix, functionPrefix: functionPrefix, objectPrefix: objectPrefix);
|
||||
final innerHandler = findFromJsonHandling(
|
||||
tmp2,
|
||||
'',
|
||||
scheme,
|
||||
abstractPrefix: abstractPrefix,
|
||||
functionPrefix: functionPrefix,
|
||||
objectPrefix: objectPrefix,
|
||||
varNameInsteadOfKeyName: 'e',
|
||||
);
|
||||
return "(json['$keyName'] as List<dynamic>).map((e) => ($innerHandler)).toList(growable: false)";
|
||||
}
|
||||
|
||||
final varAccess = varNameInsteadOfKeyName ?? "json['$keyName']";
|
||||
final predefined = {
|
||||
'double': 'double',
|
||||
'string': 'String',
|
||||
'int32': 'int',
|
||||
'int53': 'int',
|
||||
'Bool': 'bool',
|
||||
};
|
||||
if (predefined.containsKey(type)) {
|
||||
return '$varAccess as ${predefined[type]}';
|
||||
}
|
||||
else if (type == 'int64') {
|
||||
return 'int.parse($varAccess)';
|
||||
}
|
||||
else if (type == 'bytes') {
|
||||
return 'base64.decode($varAccess)';
|
||||
}
|
||||
else {
|
||||
return 'b.TdBase.fromJson($varAccess) as ${findDartType(type, scheme, abstractPrefix: abstractPrefix, functionPrefix: functionPrefix, objectPrefix: objectPrefix)}';
|
||||
}
|
||||
}
|
||||
|
||||
String makeBaseFile(TlSchema scheme) {
|
||||
var result = r"""
|
||||
import 'obj.dart' as o;
|
||||
|
||||
abstract class TdBase {
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'td::TdBase()';
|
||||
}
|
||||
|
||||
static TdBase? fromJson(Map<String, dynamic>? json) {
|
||||
if (json == null) {
|
||||
return null;
|
||||
}
|
||||
final type = json['@type'] as String;
|
||||
final constructors = {
|
||||
""";
|
||||
for (final o in scheme.objects) {
|
||||
final normName = o.name.pascalCase;
|
||||
result += '''
|
||||
'${o.name}': (json) => o.$normName.fromJson(json),
|
||||
''';
|
||||
}
|
||||
|
||||
result += '''
|
||||
};
|
||||
return constructors[type]!(json);
|
||||
}
|
||||
}
|
||||
''';
|
||||
return result;
|
||||
}
|
||||
String makeAbstractFile(TlSchema scheme) {
|
||||
var result = r"""
|
||||
import 'dart:core' as dc show Error;
|
||||
|
||||
import 'base.dart' as b;
|
||||
import 'obj.dart' as o;
|
||||
|
||||
typedef Func1<T, TResult> = TResult Function(T);
|
||||
|
||||
class MatchError extends dc.Error {}
|
||||
|
||||
""";
|
||||
|
||||
for (final ac in scheme.abstractClasses) {
|
||||
final normName = ac.name.pascalCase;
|
||||
final implementors = scheme.objects.where((element) => element.baseType == ac.name).toList(growable: false);
|
||||
result += '''
|
||||
/// ${ac.doc}
|
||||
abstract class $normName extends b.TdBase {
|
||||
TResult match<TResult>({
|
||||
''';
|
||||
for (final impl in implementors) {
|
||||
final iNormName = impl.name.pascalCase;
|
||||
result += '''
|
||||
Func1<o.$iNormName, TResult>? is$iNormName,
|
||||
''';
|
||||
}
|
||||
result += '''
|
||||
Func1<$normName, TResult>? otherwise,
|
||||
}) {
|
||||
if (false) {} // ignore: dead_code
|
||||
''';
|
||||
for (final impl in implementors) {
|
||||
final iNormName = impl.name.pascalCase;
|
||||
result += '''
|
||||
else if (this is o.$iNormName) {
|
||||
if (is$iNormName != null) {
|
||||
return is$iNormName(this as o.$iNormName);
|
||||
}
|
||||
else if (otherwise != null) {
|
||||
return otherwise(this);
|
||||
}
|
||||
}
|
||||
''';
|
||||
}
|
||||
result += '''
|
||||
else if (otherwise != null) {
|
||||
otherwise(this);
|
||||
}
|
||||
else if (TResult == null.runtimeType) {
|
||||
return null as TResult;
|
||||
}
|
||||
throw MatchError();
|
||||
}
|
||||
}
|
||||
|
||||
''';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String makeObjFile(TlSchema scheme) {
|
||||
var result = r"""
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'base.dart' as b;
|
||||
import 'abstract.dart' as a;
|
||||
|
||||
""";
|
||||
|
||||
for (final o in scheme.objects) {
|
||||
final normName = o.name.pascalCase;
|
||||
final baseName = findDartType(o.baseType, scheme, objectPrefix: '', noNullCheck: true);
|
||||
result += '''
|
||||
/// ${o.doc}
|
||||
class $normName extends $baseName {
|
||||
''';
|
||||
|
||||
for (final param in o.parameters) {
|
||||
final normParamName = param.name.camelCase;
|
||||
final paramType = findDartType(param.type, scheme, objectPrefix: '');
|
||||
result += '''
|
||||
/// ${param.doc}
|
||||
final $paramType $normParamName;
|
||||
''';
|
||||
}
|
||||
|
||||
// Constructor
|
||||
if (o.parameters.isNotEmpty) {
|
||||
result += '''
|
||||
|
||||
$normName({
|
||||
''';
|
||||
for (final param in o.parameters) {
|
||||
final normParamName = param.name.camelCase;
|
||||
result += '''
|
||||
required this.$normParamName,
|
||||
''';
|
||||
}
|
||||
result += '''
|
||||
});
|
||||
|
||||
''';
|
||||
}
|
||||
else {
|
||||
result += '''
|
||||
$normName();
|
||||
|
||||
''';
|
||||
}
|
||||
|
||||
// toString
|
||||
result += '''
|
||||
@override
|
||||
String toString() {
|
||||
var s = 'td::$normName(';
|
||||
|
||||
// Params
|
||||
final params = <String>[];
|
||||
''';
|
||||
for (final param in o.parameters) {
|
||||
final normParamName = param.name.camelCase;
|
||||
result += '''
|
||||
params.add($normParamName.toString());
|
||||
''';
|
||||
}
|
||||
|
||||
result += '''
|
||||
s += params.join(', ');
|
||||
|
||||
s += ')';
|
||||
|
||||
return s;
|
||||
}
|
||||
''';
|
||||
|
||||
// toJson
|
||||
result += '''
|
||||
@override
|
||||
Map<String, dynamic> toJson() => {
|
||||
'@type': '${o.name}',
|
||||
''';
|
||||
for (final param in o.parameters) {
|
||||
final normParamName = param.name.camelCase;
|
||||
final jsonHandling = findToJsonHandling(param.type, normParamName, scheme);
|
||||
result += '''
|
||||
'${param.name}': $jsonHandling,
|
||||
''';
|
||||
}
|
||||
result += '''
|
||||
};
|
||||
|
||||
''';
|
||||
|
||||
// fromJson
|
||||
result += '''
|
||||
factory $normName.fromJson(Map<String, dynamic> json) => $normName(
|
||||
''';
|
||||
for (final param in o.parameters) {
|
||||
final normParamName = param.name.camelCase;
|
||||
final handle = findFromJsonHandling(param.type, param.name, scheme, objectPrefix: '');
|
||||
result += '''
|
||||
$normParamName: $handle,
|
||||
''';
|
||||
}
|
||||
result += '''
|
||||
);
|
||||
''';
|
||||
|
||||
result += '''
|
||||
}
|
||||
|
||||
''';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String makeFnFile(TlSchema scheme) {
|
||||
var result = r"""
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'base.dart' as b;
|
||||
import 'abstract.dart' as a;
|
||||
import 'obj.dart' as o;
|
||||
|
||||
abstract class TdFunction extends b.TdBase {}
|
||||
|
||||
""";
|
||||
|
||||
for (final f in scheme.functions) {
|
||||
final normName = f.name.pascalCase;
|
||||
result += '''
|
||||
/// ${f.doc}
|
||||
class $normName extends TdFunction {
|
||||
''';
|
||||
|
||||
// Parameters
|
||||
for (final param in f.parameters) {
|
||||
final pNormName = param.name.camelCase;
|
||||
final pType = findDartType(param.type, scheme, functionPrefix: '');
|
||||
result += '''
|
||||
/// ${param.doc}
|
||||
final $pType $pNormName;
|
||||
''';
|
||||
}
|
||||
|
||||
// Constructor
|
||||
if (f.parameters.isEmpty) {
|
||||
result += '''
|
||||
$normName();
|
||||
|
||||
''';
|
||||
}
|
||||
else {
|
||||
result += '''
|
||||
|
||||
$normName({
|
||||
''';
|
||||
for (final param in f.parameters) {
|
||||
final pNormName = param.name.camelCase;
|
||||
result += '''
|
||||
required this.$pNormName,
|
||||
''';
|
||||
}
|
||||
result += '''
|
||||
});
|
||||
|
||||
''';
|
||||
}
|
||||
|
||||
// toString
|
||||
result += '''
|
||||
@override
|
||||
String toString() {
|
||||
var s = 'td::$normName(';
|
||||
|
||||
// Params
|
||||
final params = <String>[];
|
||||
''';
|
||||
for (final param in f.parameters) {
|
||||
final normParamName = param.name.camelCase;
|
||||
result += '''
|
||||
params.add($normParamName.toString());
|
||||
''';
|
||||
}
|
||||
|
||||
result += '''
|
||||
s += params.join(', ');
|
||||
|
||||
s += ')';
|
||||
|
||||
return s;
|
||||
}
|
||||
''';
|
||||
|
||||
// toJson
|
||||
result += '''
|
||||
@override
|
||||
Map<String, dynamic> toJson() => {
|
||||
'@type': '${f.name}',
|
||||
''';
|
||||
for (final param in f.parameters) {
|
||||
final pNormName = param.name.camelCase;
|
||||
final jsonHandling = findToJsonHandling(param.type, pNormName, scheme);
|
||||
result += '''
|
||||
'${param.name}': $jsonHandling,
|
||||
''';
|
||||
}
|
||||
result += '''
|
||||
};
|
||||
|
||||
''';
|
||||
|
||||
// fromJson
|
||||
result += '''
|
||||
factory $normName.fromJson(Map<String, dynamic> json) => $normName(
|
||||
''';
|
||||
for (final param in f.parameters) {
|
||||
final normParamName = param.name.camelCase;
|
||||
final handle = findFromJsonHandling(param.type, param.name, scheme);
|
||||
result += '''
|
||||
$normParamName: $handle,
|
||||
''';
|
||||
}
|
||||
result += '''
|
||||
);
|
||||
''';
|
||||
|
||||
result += '''
|
||||
}
|
||||
|
||||
''';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
425
bin/tdlib_gen.dart.backup
Normal file
425
bin/tdlib_gen.dart.backup
Normal file
|
@ -0,0 +1,425 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'tl_scheme.dart';
|
||||
|
||||
import 'package:recase/recase.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
Future<void> main(List<String> arguments) async {
|
||||
if (arguments.length != 2) {
|
||||
print('The program must be run with 2 arguments:');
|
||||
print(' path to .tl schema');
|
||||
print(' path to Dart project source folder');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
final schemeFileStr = arguments[0];
|
||||
final srcFolderStr = arguments[1];
|
||||
|
||||
if (! await File.fromUri(Uri.file(schemeFileStr)).exists()) {
|
||||
print("Schema file $schemeFileStr doesn't exist");
|
||||
exit(1);
|
||||
}
|
||||
if (! await Directory.fromUri(Uri.directory(srcFolderStr)).exists()) {
|
||||
print("Dart project source folder $srcFolderStr doesn't exist");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
print('.tl schema folder: $schemeFileStr');
|
||||
print('Dart project source folder: $srcFolderStr');
|
||||
print('');
|
||||
|
||||
print('Reading .tl schema file...');
|
||||
final schemeFileContents = await File.fromUri(Uri.file(schemeFileStr)).readAsString();
|
||||
print('Parsing .tl schema file...');
|
||||
final scheme = TlSchema.parse(schemeFileContents);
|
||||
|
||||
print('Generating...');
|
||||
|
||||
final baseFile = File.fromUri(Uri.file(path.join(srcFolderStr, 'base.dart')));
|
||||
final abstractFile = File.fromUri(Uri.file(path.join(srcFolderStr, 'abstract.dart')));
|
||||
final objFile = File.fromUri(Uri.file(path.join(srcFolderStr, 'obj.dart')));
|
||||
final fnFile = File.fromUri(Uri.file(path.join(srcFolderStr, 'fn.dart')));
|
||||
await baseFile.writeAsString(makeBaseFile(scheme));
|
||||
await abstractFile.writeAsString(makeAbstractFile(scheme));
|
||||
await objFile.writeAsString(makeObjFile(scheme));
|
||||
await fnFile.writeAsString(makeFnFile(scheme));
|
||||
|
||||
print('Done!');
|
||||
}
|
||||
|
||||
String findDartType(
|
||||
String type,
|
||||
TlSchema scheme,
|
||||
{String abstractPrefix = 'a.',
|
||||
String objectPrefix = 'o.',
|
||||
String functionPrefix = 'f.'}
|
||||
) {
|
||||
if (type.startsWith('vector<')) {
|
||||
final tmp1 = type.replaceFirst('vector<', '');
|
||||
final tmp2 = tmp1.substring(0, tmp1.length - 1);
|
||||
final innerType = findDartType(
|
||||
tmp2,
|
||||
scheme,
|
||||
abstractPrefix: abstractPrefix,
|
||||
functionPrefix: functionPrefix,
|
||||
objectPrefix: objectPrefix,
|
||||
);
|
||||
return 'List<$innerType>';
|
||||
}
|
||||
|
||||
final predefined = {
|
||||
'double': 'double',
|
||||
'string': 'String',
|
||||
'int32': 'int',
|
||||
'int53': 'int',
|
||||
'int64': 'int',
|
||||
'bytes': 'Uint8List',
|
||||
'Bool': 'bool',
|
||||
};
|
||||
|
||||
if (predefined.containsKey(type)) {
|
||||
return predefined[type]!;
|
||||
}
|
||||
|
||||
final result = scheme.findType(type);
|
||||
if (result == null) {
|
||||
throw Exception("Couldn't find type: $type");
|
||||
}
|
||||
|
||||
if (result is TlSchemeAbstractClass) {
|
||||
return abstractPrefix + result.name.pascalCase;
|
||||
}
|
||||
else if (result is TlSchemeObject) {
|
||||
return objectPrefix + result.name.pascalCase;
|
||||
}
|
||||
else if (result is TlSchemeFunction) {
|
||||
return functionPrefix + result.name.pascalCase;
|
||||
}
|
||||
else {
|
||||
throw Exception('Unknown tl object: $result');
|
||||
}
|
||||
}
|
||||
|
||||
String findToJsonHandling(
|
||||
String type,
|
||||
String varName,
|
||||
TlSchema scheme,
|
||||
) {
|
||||
if (type.startsWith('vector<')) {
|
||||
final tmp1 = type.replaceFirst('vector<', '');
|
||||
final tmp2 = tmp1.substring(0, tmp1.length - 1);
|
||||
late String newVarName;
|
||||
if (varName.startsWith('_e')) {
|
||||
final num = int.parse(varName.substring(2));
|
||||
newVarName = '_e${num + 1}';
|
||||
}
|
||||
else {
|
||||
newVarName = '_e1';
|
||||
}
|
||||
final innerHandling = findToJsonHandling(
|
||||
tmp2,
|
||||
newVarName,
|
||||
scheme,
|
||||
);
|
||||
return '$varName.map(($newVarName) => $innerHandling).toList(growable: false)';
|
||||
}
|
||||
|
||||
final predefined = {
|
||||
'double': 'double',
|
||||
'string': 'String',
|
||||
'int32': 'int',
|
||||
'int53': 'int',
|
||||
'Bool': 'bool',
|
||||
};
|
||||
if (predefined.containsKey(type)) {
|
||||
return varName;
|
||||
}
|
||||
else if (type == 'int64') {
|
||||
return '$varName.toString()';
|
||||
}
|
||||
else if (type == 'bytes') {
|
||||
return 'base64.encode($varName)';
|
||||
}
|
||||
else {
|
||||
return '$varName.toJson()';
|
||||
}
|
||||
}
|
||||
|
||||
String findFromJsonHandling(
|
||||
String type,
|
||||
String keyName,
|
||||
TlSchema scheme,
|
||||
{String abstractPrefix = 'a.',
|
||||
String objectPrefix = 'o.',
|
||||
String functionPrefix = 'f.'}
|
||||
) {
|
||||
if (type.startsWith('vector<')) {
|
||||
final tmp1 = type.replaceFirst('vector<', '');
|
||||
final tmp2 = tmp1.substring(0, tmp1.length - 1);
|
||||
final innerType = findDartType(tmp2, scheme, abstractPrefix: abstractPrefix, functionPrefix: functionPrefix, objectPrefix: objectPrefix);
|
||||
return "(json['$keyName'] as List<dynamic>).map((e) => b.TdBase.fromJson(e) as $innerType).toList(growable: false)";
|
||||
}
|
||||
|
||||
final predefined = {
|
||||
'double': 'double',
|
||||
'string': 'String',
|
||||
'int32': 'int',
|
||||
'int53': 'int',
|
||||
'Bool': 'bool',
|
||||
};
|
||||
if (predefined.containsKey(type)) {
|
||||
return "json['$keyName']";
|
||||
}
|
||||
else if (type == 'int64') {
|
||||
return "int.parse(json['$keyName'])";
|
||||
}
|
||||
else if (type == 'bytes') {
|
||||
return "base64.decode(json['$keyName'])";
|
||||
}
|
||||
else {
|
||||
return "b.TdBase.fromJson(json['$keyName']) as ${findDartType(type, scheme, abstractPrefix: abstractPrefix, functionPrefix: functionPrefix, objectPrefix: objectPrefix)}";
|
||||
}
|
||||
}
|
||||
|
||||
String makeBaseFile(TlSchema scheme) {
|
||||
var result = r"""
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'abstract.dart' as a;
|
||||
import 'obj.dart' as o;
|
||||
import 'fn.dart' as f;
|
||||
|
||||
abstract class TdBase {
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
static TdBase fromJson(Map<String, dynamic> json) {
|
||||
final type = json['@type'] as String;
|
||||
if (false) {}
|
||||
""";
|
||||
for (final o in scheme.objects) {
|
||||
final normName = o.name.pascalCase;
|
||||
result += '''
|
||||
else if (type == '${o.name}') {
|
||||
return o.$normName.fromJson(json);
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
result += '''
|
||||
else {
|
||||
throw Exception('Unknown type: \$type');
|
||||
}
|
||||
}
|
||||
}
|
||||
''';
|
||||
return result;
|
||||
}
|
||||
|
||||
String makeAbstractFile(TlSchema scheme) {
|
||||
var result = r"""
|
||||
import 'base.dart' as b;
|
||||
|
||||
""";
|
||||
|
||||
for (final ac in scheme.abstractClasses) {
|
||||
final normName = ac.name.pascalCase;
|
||||
result += '''
|
||||
/// ${ac.doc}
|
||||
abstract class $normName extends b.TdBase {}
|
||||
|
||||
''';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String makeObjFile(TlSchema scheme) {
|
||||
var result = r"""
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'base.dart' as b;
|
||||
import 'abstract.dart' as a;
|
||||
|
||||
""";
|
||||
|
||||
for (final o in scheme.objects) {
|
||||
final normName = o.name.pascalCase;
|
||||
final baseName = findDartType(o.baseType, scheme, objectPrefix: '');
|
||||
result += '''
|
||||
/// ${o.doc}
|
||||
class $normName extends $baseName {
|
||||
''';
|
||||
|
||||
for (final param in o.parameters) {
|
||||
final normParamName = param.name.camelCase;
|
||||
final paramType = findDartType(param.type, scheme, objectPrefix: '');
|
||||
result += '''
|
||||
/// ${param.doc}
|
||||
final $paramType $normParamName;
|
||||
''';
|
||||
}
|
||||
|
||||
// Constructor
|
||||
if (o.parameters.isNotEmpty) {
|
||||
result += '''
|
||||
|
||||
$normName({
|
||||
''';
|
||||
for (final param in o.parameters) {
|
||||
final normParamName = param.name.camelCase;
|
||||
result += '''
|
||||
required this.$normParamName,
|
||||
''';
|
||||
}
|
||||
result += '''
|
||||
});
|
||||
|
||||
''';
|
||||
}
|
||||
else {
|
||||
result += '''
|
||||
$normName();
|
||||
|
||||
''';
|
||||
}
|
||||
|
||||
// toJson
|
||||
result += '''
|
||||
@override
|
||||
Map<String, dynamic> toJson() => {
|
||||
'@type': '${o.name}',
|
||||
''';
|
||||
for (final param in o.parameters) {
|
||||
final normParamName = param.name.camelCase;
|
||||
result += '''
|
||||
'${param.name}': $normParamName,
|
||||
''';
|
||||
}
|
||||
result += '''
|
||||
};
|
||||
|
||||
''';
|
||||
|
||||
// fromJson
|
||||
result += '''
|
||||
factory $normName.fromJson(Map<String, dynamic> json) => $normName(
|
||||
''';
|
||||
for (final param in o.parameters) {
|
||||
final normParamName = param.name.camelCase;
|
||||
final handle = findFromJsonHandling(param.type, param.name, scheme, objectPrefix: '');
|
||||
result += '''
|
||||
$normParamName: $handle,
|
||||
''';
|
||||
}
|
||||
result += '''
|
||||
);
|
||||
''';
|
||||
|
||||
result += '''
|
||||
}
|
||||
|
||||
''';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String makeFnFile(TlSchema scheme) {
|
||||
var result = r"""
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'base.dart' as b;
|
||||
import 'abstract.dart' as a;
|
||||
import 'obj.dart' as o;
|
||||
|
||||
abstract class TdFunction extends b.TdBase {}
|
||||
|
||||
""";
|
||||
|
||||
for (final f in scheme.functions) {
|
||||
final normName = f.name.pascalCase;
|
||||
result += '''
|
||||
/// ${f.doc}
|
||||
class $normName extends TdFunction {
|
||||
''';
|
||||
|
||||
// Parameters
|
||||
for (final param in f.parameters) {
|
||||
final pNormName = param.name.camelCase;
|
||||
final pType = findDartType(param.type, scheme, functionPrefix: '');
|
||||
result += '''
|
||||
/// ${param.doc}
|
||||
final $pType $pNormName;
|
||||
''';
|
||||
}
|
||||
|
||||
// Constructor
|
||||
if (f.parameters.isEmpty) {
|
||||
result += '''
|
||||
$normName();
|
||||
|
||||
''';
|
||||
}
|
||||
else {
|
||||
result += '''
|
||||
|
||||
$normName({
|
||||
''';
|
||||
for (final param in f.parameters) {
|
||||
final pNormName = param.name.camelCase;
|
||||
result += '''
|
||||
required this.$pNormName,
|
||||
''';
|
||||
}
|
||||
result += '''
|
||||
});
|
||||
|
||||
''';
|
||||
}
|
||||
|
||||
// toJson
|
||||
result += '''
|
||||
@override
|
||||
Map<String, dynamic> toJson() => {
|
||||
'@type': '${f.name}',
|
||||
''';
|
||||
for (final param in f.parameters) {
|
||||
final pNormName = param.name.camelCase;
|
||||
final jsonHandling = findToJsonHandling(param.type, pNormName, scheme);
|
||||
result += '''
|
||||
'${param.name}': $jsonHandling,
|
||||
''';
|
||||
}
|
||||
result += '''
|
||||
};
|
||||
|
||||
''';
|
||||
|
||||
// fromJson
|
||||
result += '''
|
||||
factory $normName.fromJson(Map<String, dynamic> json) => $normName(
|
||||
''';
|
||||
for (final param in f.parameters) {
|
||||
final normParamName = param.name.camelCase;
|
||||
final handle = findFromJsonHandling(param.type, param.name, scheme);
|
||||
result += '''
|
||||
$normParamName: $handle,
|
||||
''';
|
||||
}
|
||||
result += '''
|
||||
);
|
||||
''';
|
||||
|
||||
result += '''
|
||||
}
|
||||
|
||||
''';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
266
bin/tl_scheme.dart
Normal file
266
bin/tl_scheme.dart
Normal file
|
@ -0,0 +1,266 @@
|
|||
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);
|
||||
}
|
139
bin/tl_token.dart
Normal file
139
bin/tl_token.dart
Normal file
|
@ -0,0 +1,139 @@
|
|||
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';
|
||||
}
|
||||
}
|
26
pubspec.lock
Normal file
26
pubspec.lock
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
path:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
pedantic:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: pedantic
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.11.0"
|
||||
recase:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: recase
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
sdks:
|
||||
dart: ">=2.12.0 <3.0.0"
|
14
pubspec.yaml
Normal file
14
pubspec.yaml
Normal file
|
@ -0,0 +1,14 @@
|
|||
name: tdlib_gen
|
||||
description: A simple command-line application.
|
||||
version: 1.0.0
|
||||
# homepage: https://www.example.com
|
||||
|
||||
environment:
|
||||
sdk: '>=2.12.0 <3.0.0'
|
||||
|
||||
dependencies:
|
||||
recase: ^4.0.0
|
||||
path: ^1.8.0
|
||||
|
||||
dev_dependencies:
|
||||
pedantic: ^1.10.0
|
Loading…
Add table
Reference in a new issue