Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion android/extract_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ func extractObject(class *javaTypes.RawClass) (types.TLInterface, error) {
}
}
}
if !isMethod {
if inheritedMethod, inheritedResult := findInheritedMethodResult(class.ParentLink); inheritedMethod {
isMethod = true
methodResult = inheritedResult
}
}
var deserializedParams, serializedParams []types.Parameter
if serializePos != 0 {
params, err := extractParams(class, serializePos)
Expand Down Expand Up @@ -97,7 +103,11 @@ func extractObject(class *javaTypes.RawClass) (types.TLInterface, error) {
}
if len(packageName) == 0 {
if isMethod {
packageName = "messages"
if containerNamespace := methodNamespaceFromPrefix(class.Prefix); len(containerNamespace) > 0 {
packageName = containerNamespace
} else {
packageName = "messages"
}
}
} else {
packageName = strings.ToLower(packageName)
Expand Down Expand Up @@ -136,3 +146,39 @@ func extractObject(class *javaTypes.RawClass) (types.TLInterface, error) {
}, nil
}
}

func methodNamespaceFromPrefix(prefix string) string {
if prefix == "TLRPC" || prefix == "TL" {
return ""
}
trimmed := strings.TrimPrefix(prefix, "TL_")
if trimmed == prefix || len(trimmed) == 0 {
return ""
}
return strings.ToLower(trimmed)
}

func findInheritedMethodResult(class *javaTypes.RawClass) (bool, string) {
if class == nil {
return false, ""
}
if class.Prefix == "TLObject" || class.Prefix == "TLMethod" {
return false, ""
}
compileResult := regexp.MustCompile(`(return|=) *(.*?)\.TLdeserialize`)
for _, line := range class.Content {
if java.CheckMethodDec(line, "deserializeResponse") || java.CheckMethodDec(line, "deserializeResponseT") {
for _, resultLine := range class.Content {
if matches := compileResult.FindAllStringSubmatch(resultLine.Line, -1); len(matches) > 0 {
formattedType, err := java.FormatType(matches[0][2], true)
if err != nil {
return true, ""
}
return true, formattedType
}
}
return true, ""
}
}
return findInheritedMethodResult(class.ParentLink)
}
17 changes: 13 additions & 4 deletions android/extract_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func extractParams(class *javaTypes.RawClass, declarationPos int) ([]schemeTypes
var flagName string
flagValue := -1
//fastCheck := regexp.MustCompile(`this\.\w+`)
compileVars := regexp.MustCompile(`\(?(this|tLRPC[^.]+)\.([^. )]+)( \?|\.\w+Value\(\)|\.add|\.get|\.serialize|\)| !| = (Boolean\.valueOf\(abstractSerializedData|abstractSerializedData|inputSerializedData|i[0-9+]*;|read|TLdeserialize;|Vector\.deserialize|\([^(]|\w+\$\w+\.\w+deserialize))\)?`)
compileVars := regexp.MustCompile(`\(?(this|tLRPC[^.]+)\.([^. )]+)( \?|\.\w+Value\(\)|\.add|\.get|\.serialize|\)| !| = (Boolean\.valueOf\(abstractSerializedData|abstractSerializedData|inputSerializedData|i[0-9+]*;|read|TLdeserialize;|Vector\.deserialize|\([^(]|\w+(\$\w+)?\.\w+deserialize))\)?`)
compileVarBuffer := regexp.MustCompile(`^(this|tLRPC\$[^.]+)*\.*\w* *=* *((Boolean\.valueOf\()?(abstractSerializedData|inputSerializedData)[0-9]*|)?(\.write|\.read|TLRPC\$)([^(.]+).*?\);`)
compileVarFlag := regexp.MustCompile(`this\.flags[0-9]* = readInt[0-9]+;`)
compileVarBool := regexp.MustCompile(`this\.\w+ = \([^)]*readInt32[0-9]*[^)]*\)`)
Expand Down Expand Up @@ -100,18 +100,27 @@ func extractParams(class *javaTypes.RawClass, declarationPos int) ([]schemeTypes
forNesting = line.Nesting - 1
}
if matches := compileVars.FindAllStringSubmatch(line.Line, -1); len(matches) > 0 {
// Skip matches where the captured field name is a method call (e.g. "serializeToStream(...)")
fieldName := matches[0][2]
if strings.Contains(fieldName, "(") || strings.Contains(fieldName, "$") {
continue
}
// Skip comparison matches ("this.X != ...") unless inside a flag context
if strings.HasPrefix(matches[0][3], " !") && !openedFlags {
continue
}
var parameter schemeTypes.Parameter
var fromBuffer bool
parameter.Name = matches[0][2]
if matchedType := compileVarBuffer.FindAllStringSubmatch(line.Line, -1); len(matchedType) > 0 {
if matchedType := compileVarBuffer.FindAllStringSubmatch(line.Line, -1); len(matchedType) > 0 && !compileFlags.MatchString(line.Line) {
parameter.Type = java.ParseType(matchedType[0][6])
fromBuffer = true
} else if declaredType, ok := class.Vars[matches[0][2]]; ok {
parameter.Type = java.ParseType(declaredType)
} else if compileVarFlag.MatchString(line.Line) {
parameter.Type = "int"
} else if compileVarBool.MatchString(line.Line) {
parameter.Type = "bool"
parameter.Type = "Bool"
} else if strings.HasPrefix(matches[0][1], "tLRPC") {
escapedVar := regexp.QuoteMeta(matches[0][1])
compileReverseName := regexp.MustCompile(fmt.Sprintf("(%s =|this\\.)(\\w+)(;| = %s)", escapedVar, escapedVar))
Expand Down Expand Up @@ -159,7 +168,7 @@ func extractParams(class *javaTypes.RawClass, declarationPos int) ([]schemeTypes
if flagValue == -1 {
return nil, consts.FlagNotFound
}
if !fromBuffer && parameter.Type == "Bool" {
if !fromBuffer && strings.EqualFold(parameter.Type, "Bool") {
parameter.Type = "true"
}

Expand Down
1 change: 1 addition & 0 deletions consts/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ var (
regexp.MustCompile(`^secret$`),
regexp.MustCompile(`Layer[0-9]+$`),
regexp.MustCompile(`^TL_messages\.SendEncryptedMultiMedia$`),
regexp.MustCompile(`(?i)legacy$`),
}
BrokenNames = map[*regexp.Regexp]string{
regexp.MustCompile(`^((?P<first>is_admin)|is_(?P<second>.*))$`): "$first$second",
Expand Down
7 changes: 7 additions & 0 deletions java/format_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ func FormatType(name string, clearTLName bool) (string, error) {
}
fileName := strings.Split(name, "$")
name = fileName[len(fileName)-1]
if !strings.ContainsAny(name, "<>") {
if dotParts := strings.SplitN(name, ".", 2); len(dotParts) > 1 && len(dotParts[0]) > 0 {
if first := dotParts[0][0]; first >= 'A' && first <= 'Z' {
name = dotParts[1]
}
}
}
if clearTLName {
for _, prefix := range []string{"TL", "Tl", "_"} {
name = strings.TrimPrefix(name, prefix)
Expand Down
17 changes: 11 additions & 6 deletions java/parse_class.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,20 @@ func ParseClass(name, content string) (*types.RawClass, error) {
tlName.Content = parseLines(content)
for _, line := range tlName.Content {
if className := GetParentClass(line); len(className) > 0 {
tlName.ParentClass, err = FormatType(className, false)
parentPrefix := ""
parentName := className
if parentData := strings.Split(className, "$"); len(parentData) > 1 {
parentPrefix = parentData[0]
parentName = parentData[1]
} else if parentData := strings.Split(className, "."); len(parentData) > 1 {
parentPrefix = parentData[0]
parentName = parentData[len(parentData)-1]
}
tlName.ParentClass, err = FormatType(parentName, false)
if err != nil {
return nil, err
}
if parentData := strings.Split(className, "$"); len(parentData) > 1 {
tlName.ParentPrefix = parentData[0]
} else {
tlName.ParentPrefix = ""
}
tlName.ParentPrefix = parentPrefix
}
}
return &tlName, nil
Expand Down
27 changes: 25 additions & 2 deletions java/split_classes.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ func SplitClasses(className, content string, replaceClasses []string) map[string
classNames = append(classNames, strings.Split(name, "$")[1])
}
namesJoined := regexp.MustCompile(fmt.Sprintf(`(\b)(%s)(\b)`, strings.Join(classNames, "|")))
thisFieldAccess := regexp.MustCompile(`this\.\w+$`)
fieldDeclaration := regexp.MustCompile(`^public [\w<>.\[\]$]+ (\w+)( =.*)?;$`)
var dynamicRegex *regexp.Regexp
replaceNames := make(map[string]string)
appendName := func(base, name string) {
Expand All @@ -51,8 +53,29 @@ func SplitClasses(className, content string, replaceClasses []string) map[string
replaceNames = make(map[string]string)
for i, line := range classLines {
line = compileParentClasses.ReplaceAllString(line, `$1$$$2`)
if namesJoined.MatchString(line) {
line = namesJoined.ReplaceAllString(line, fmt.Sprintf("${1}%s$$$2$3", className))
declaredFieldName := ""
if declMatches := fieldDeclaration.FindStringSubmatch(strings.TrimSpace(line)); declMatches != nil {
declaredFieldName = declMatches[1]
}
if idxs := namesJoined.FindAllStringSubmatchIndex(line, -1); len(idxs) > 0 {
var b strings.Builder
lastEnd := 0
for _, idx := range idxs {
matchStart, matchEnd := idx[0], idx[1]
matchedName := line[idx[4]:idx[5]]
if thisFieldAccess.MatchString(line[:matchEnd]) || matchedName == declaredFieldName {
continue
}
b.WriteString(line[lastEnd:matchStart])
b.WriteString(line[idx[2]:idx[3]])
b.WriteString(className)
b.WriteString("$")
b.WriteString(line[idx[4]:idx[5]])
b.WriteString(line[idx[6]:idx[7]])
lastEnd = matchEnd
}
b.WriteString(line[lastEnd:])
line = b.String()
}
if matches := compileClassInitializer2.FindAllStringSubmatch(line, -1); len(matches) > 0 {
appendName(matches[0][1], matches[0][2])
Expand Down
6 changes: 3 additions & 3 deletions utils/merge_parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ func MergeParameters(old, new []types.Parameter, isSameConstructor bool) []types
if i < len(old) {
content := old[i]
res := flagExtractor.FindAllStringSubmatch(content.Type, -1)
if len(res) > 0 && slices.Contains(availableFlags, res[0][1]) &&
!slices.Contains(addableKeys, content.Name) &&
if !slices.Contains(addableKeys, content.Name) &&
!slices.Contains(keys, content.Name) &&
isSameConstructor {
isSameConstructor &&
(len(res) == 0 || slices.Contains(availableFlags, res[0][1])) {
mergedList = append(mergedList, content)
keys = append(keys, content.Name)
}
Expand Down