blob: a3d57179e9c9f461c51cb00ff34c23f4d591098f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
package mcprepack
import net.fabricmc.stitch.commands.tinyv2.TinyFile
import java.io.StringReader
sealed interface TypeDescriptor {
fun mapClassName(tinyFile: TinyFile): TypeDescriptor {
return when (this) {
is Class ->
Class(tinyFile.mapClassesByFirstNamespace()[this.name]?.classNames?.get(2) ?: this.name)
else -> this
}
}
fun toProguardString(): String {
return when (this) {
is Array -> this.elementType.toProguardString() + "[]"
Boolean -> "boolean"
Byte -> "byte"
Char -> "char"
is Class -> this.name.replace("/", ".")
Double -> "double"
Float -> "float"
Int -> "int"
Long -> "long"
Short -> "short"
Void -> "void"
}
}
sealed interface FieldDescriptor : TypeDescriptor
object Void : TypeDescriptor
object Double : FieldDescriptor
object Boolean : FieldDescriptor
object Float : FieldDescriptor
object Int : FieldDescriptor
object Long : FieldDescriptor
object Short : FieldDescriptor
object Byte : FieldDescriptor
object Char : FieldDescriptor
data class Class(val name: String) : FieldDescriptor
data class Array(val elementType: TypeDescriptor) : FieldDescriptor
}
data class FieldDescriptor(
val type: TypeDescriptor.FieldDescriptor
) {
companion object {
fun parseFieldDescriptor(descriptor: String) =
FieldDescriptor(readType(StringReader(descriptor)) as? TypeDescriptor.FieldDescriptor ?: error("Cannot have void as a field type"))
}
}
data class MethodDescriptor(
val arguments: List<TypeDescriptor.FieldDescriptor>,
val returnType: TypeDescriptor
) {
companion object {
fun parseMethodDescriptor(descriptor: String): MethodDescriptor {
val reader = StringReader(descriptor)
require(reader.readChar() == '(')
val arguments = mutableListOf<TypeDescriptor.FieldDescriptor>()
while (reader.peek() != ')') {
arguments.add(
readType(reader) as? TypeDescriptor.FieldDescriptor ?: error("Cannot have void type as argument")
)
}
reader.readChar() // Consume the ')'
return MethodDescriptor(arguments, readType(reader))
}
}
}
fun StringReader.readChar() = CharArray(1).let {
if (read(it) < 0) null
else it[0]
}
fun StringReader.readUntil(search: Char): String? {
val s = StringBuilder()
while (true) {
val justRead = readChar() ?: return null
if (justRead == search) return s.toString()
s.append(justRead)
}
}
fun StringReader.peek(): Char? {
mark(0)
val x = readChar()
reset()
return x
}
fun readType(reader: StringReader): TypeDescriptor {
return when (reader.readChar()) {
'L' -> TypeDescriptor.Class(reader.readUntil(';') ?: error("Unfinished class type descriptor"))
'V' -> TypeDescriptor.Void
'Z' -> TypeDescriptor.Boolean
'B' -> TypeDescriptor.Byte
'I' -> TypeDescriptor.Int
'D' -> TypeDescriptor.Double
'J' -> TypeDescriptor.Long
'S' -> TypeDescriptor.Short
'F' -> TypeDescriptor.Float
'C' -> TypeDescriptor.Char
'[' -> TypeDescriptor.Array(readType(reader))
else -> error("Unknown or unfinished type descriptor")
}
}
|