initial commit
This commit is contained in:
commit
6358d0754b
34 changed files with 82616 additions and 0 deletions
74
tlparser/code.go
Normal file
74
tlparser/code.go
Normal file
|
@ -0,0 +1,74 @@
|
|||
package tlparser
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ParseCode(reader io.Reader, schema *Schema) error {
|
||||
var prevLine string
|
||||
var curLine string
|
||||
|
||||
userMethods := map[string]bool{}
|
||||
botMethods := map[string]bool{}
|
||||
|
||||
scanner := bufio.NewScanner(reader)
|
||||
for scanner.Scan() {
|
||||
prevLine = curLine
|
||||
curLine = scanner.Text()
|
||||
|
||||
if strings.Contains(curLine, "CHECK_IS_USER();") {
|
||||
fields := strings.Fields(prevLine)
|
||||
for _, field := range fields {
|
||||
var methodName string
|
||||
n, err := fmt.Sscanf(field, "td_api::%s", &methodName)
|
||||
if err == nil && n > 0 {
|
||||
userMethods[methodName] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if strings.Contains(curLine, "CHECK_IS_BOT();") {
|
||||
fields := strings.Fields(prevLine)
|
||||
for _, field := range fields {
|
||||
var methodName string
|
||||
n, err := fmt.Sscanf(field, "td_api::%s", &methodName)
|
||||
if err == nil && n > 0 {
|
||||
botMethods[methodName] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err := scanner.Err()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var ok bool
|
||||
|
||||
for index, _ := range schema.Functions {
|
||||
hasType := false
|
||||
_, ok = userMethods[schema.Functions[index].Name]
|
||||
if ok {
|
||||
schema.Functions[index].Type = FUNCTION_TYPE_USER
|
||||
hasType = true
|
||||
}
|
||||
|
||||
_, ok = botMethods[schema.Functions[index].Name]
|
||||
if ok {
|
||||
schema.Functions[index].Type = FUNCTION_TYPE_BOT
|
||||
hasType = true
|
||||
}
|
||||
|
||||
if !hasType {
|
||||
schema.Functions[index].Type = FUNCTION_TYPE_COMMON
|
||||
}
|
||||
|
||||
ok = false
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
174
tlparser/parser.go
Normal file
174
tlparser/parser.go
Normal file
|
@ -0,0 +1,174 @@
|
|||
package tlparser
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Parse(reader io.Reader) (*Schema, error) {
|
||||
schema := &Schema{
|
||||
Types: []*Type{},
|
||||
Classes: []*Class{},
|
||||
Functions: []*Function{},
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(reader)
|
||||
|
||||
hitFunctions := false
|
||||
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
|
||||
switch {
|
||||
case strings.HasPrefix(line, "//@description"):
|
||||
if hitFunctions {
|
||||
schema.Functions = append(schema.Functions, parseFunction(line, scanner))
|
||||
} else {
|
||||
schema.Types = append(schema.Types, parseType(line, scanner))
|
||||
}
|
||||
|
||||
case strings.HasPrefix(line, "//@class"):
|
||||
schema.Classes = append(schema.Classes, parseClass(line, scanner))
|
||||
|
||||
case strings.Contains(line, "---functions---"):
|
||||
hitFunctions = true
|
||||
|
||||
case line == "":
|
||||
|
||||
default:
|
||||
bodyFields := strings.Fields(line)
|
||||
name := bodyFields[0]
|
||||
class := strings.TrimRight(bodyFields[len(bodyFields)-1], ";")
|
||||
if hitFunctions {
|
||||
schema.Functions = append(schema.Functions, &Function{
|
||||
Name: name,
|
||||
Description: "",
|
||||
Class: class,
|
||||
Properties: []*Property{},
|
||||
IsSynchronous: false,
|
||||
Type: FUNCTION_TYPE_UNKNOWN,
|
||||
})
|
||||
} else {
|
||||
if name == "vector" {
|
||||
name = "vector<t>"
|
||||
class = "Vector<T>"
|
||||
}
|
||||
|
||||
schema.Types = append(schema.Types, &Type{
|
||||
Name: name,
|
||||
Description: "",
|
||||
Class: class,
|
||||
Properties: []*Property{},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return schema, nil
|
||||
}
|
||||
|
||||
func parseType(firstLine string, scanner *bufio.Scanner) *Type {
|
||||
name, description, class, properties, _ := parseEntity(firstLine, scanner)
|
||||
return &Type{
|
||||
Name: name,
|
||||
Description: description,
|
||||
Class: class,
|
||||
Properties: properties,
|
||||
}
|
||||
}
|
||||
|
||||
func parseFunction(firstLine string, scanner *bufio.Scanner) *Function {
|
||||
name, description, class, properties, isSynchronous := parseEntity(firstLine, scanner)
|
||||
return &Function{
|
||||
Name: name,
|
||||
Description: description,
|
||||
Class: class,
|
||||
Properties: properties,
|
||||
IsSynchronous: isSynchronous,
|
||||
Type: FUNCTION_TYPE_UNKNOWN,
|
||||
}
|
||||
}
|
||||
|
||||
func parseClass(firstLine string, scanner *bufio.Scanner) *Class {
|
||||
class := &Class{
|
||||
Name: "",
|
||||
Description: "",
|
||||
}
|
||||
|
||||
classLineParts := strings.Split(firstLine, "@")
|
||||
|
||||
_, class.Name = parseProperty(classLineParts[1])
|
||||
_, class.Description = parseProperty(classLineParts[2])
|
||||
|
||||
return class
|
||||
}
|
||||
|
||||
func parseEntity(firstLine string, scanner *bufio.Scanner) (string, string, string, []*Property, bool) {
|
||||
name := ""
|
||||
description := ""
|
||||
class := ""
|
||||
properties := []*Property{}
|
||||
|
||||
propertiesLine := strings.TrimLeft(firstLine, "//")
|
||||
|
||||
Loop:
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
|
||||
switch {
|
||||
case strings.HasPrefix(line, "//@"):
|
||||
propertiesLine += " " + strings.TrimLeft(line, "//")
|
||||
|
||||
case strings.HasPrefix(line, "//-"):
|
||||
propertiesLine += " " + strings.TrimLeft(line, "//-")
|
||||
|
||||
default:
|
||||
bodyFields := strings.Fields(line)
|
||||
name = bodyFields[0]
|
||||
|
||||
for _, rawProperty := range bodyFields[1 : len(bodyFields)-2] {
|
||||
propertyParts := strings.Split(rawProperty, ":")
|
||||
property := &Property{
|
||||
Name: propertyParts[0],
|
||||
Type: propertyParts[1],
|
||||
}
|
||||
properties = append(properties, property)
|
||||
}
|
||||
class = strings.TrimRight(bodyFields[len(bodyFields)-1], ";")
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
|
||||
rawProperties := strings.Split(propertiesLine, "@")
|
||||
for _, rawProperty := range rawProperties[1:] {
|
||||
name, value := parseProperty(rawProperty)
|
||||
switch {
|
||||
case name == "description":
|
||||
description = value
|
||||
default:
|
||||
name = strings.TrimPrefix(name, "param_")
|
||||
property := getProperty(properties, name)
|
||||
property.Description = value
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return name, description, class, properties, strings.Contains(description, "Can be called synchronously")
|
||||
}
|
||||
|
||||
func parseProperty(str string) (string, string) {
|
||||
strParts := strings.Fields(str)
|
||||
|
||||
return strParts[0], strings.Join(strParts[1:], " ")
|
||||
}
|
||||
|
||||
func getProperty(properties []*Property, name string) *Property {
|
||||
for _, property := range properties {
|
||||
if property.Name == name {
|
||||
return property
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
43
tlparser/type.go
Normal file
43
tlparser/type.go
Normal file
|
@ -0,0 +1,43 @@
|
|||
package tlparser
|
||||
|
||||
type Schema struct {
|
||||
Types []*Type `json:"types"`
|
||||
Classes []*Class `json:"classes"`
|
||||
Functions []*Function `json:"functions"`
|
||||
}
|
||||
|
||||
type Type struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Class string `json:"class"`
|
||||
Properties []*Property `json:"properties"`
|
||||
}
|
||||
|
||||
type Class struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type FunctionType int
|
||||
|
||||
const (
|
||||
FUNCTION_TYPE_UNKNOWN FunctionType = iota
|
||||
FUNCTION_TYPE_COMMON
|
||||
FUNCTION_TYPE_USER
|
||||
FUNCTION_TYPE_BOT
|
||||
)
|
||||
|
||||
type Function struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Class string `json:"class"`
|
||||
Properties []*Property `json:"properties"`
|
||||
IsSynchronous bool `json:"is_synchronous"`
|
||||
Type FunctionType `json:"type"`
|
||||
}
|
||||
|
||||
type Property struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Description string `json:"description"`
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue