Skip to content

Commit f31c556

Browse files
committed
add hex popup to decompiler
1 parent 6e13c49 commit f31c556

3 files changed

Lines changed: 57 additions & 43 deletions

File tree

composeApp/src/commonMain/kotlin/me/lkl/dalvikus/ui/editor/EditorView.kt

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,14 @@ import androidx.compose.foundation.text.KeyboardOptions
77
import androidx.compose.material.icons.Icons
88
import androidx.compose.material.icons.filled.SaveAs
99
import androidx.compose.material.icons.outlined.SentimentDissatisfied
10-
import androidx.compose.material3.CircularProgressIndicator
11-
import androidx.compose.material3.ExtendedFloatingActionButton
12-
import androidx.compose.material3.Icon
13-
import androidx.compose.material3.MaterialTheme
14-
import androidx.compose.material3.Scaffold
15-
import androidx.compose.material3.Text
10+
import androidx.compose.material3.*
1611
import androidx.compose.runtime.*
1712
import androidx.compose.ui.Alignment
1813
import androidx.compose.ui.Modifier
1914
import androidx.compose.ui.focus.FocusRequester
2015
import androidx.compose.ui.focus.focusRequester
2116
import androidx.compose.ui.graphics.Color
2217
import androidx.compose.ui.graphics.SolidColor
23-
import androidx.compose.ui.text.AnnotatedString
2418
import androidx.compose.ui.text.TextLayoutResult
2519
import androidx.compose.ui.text.TextStyle
2620
import androidx.compose.ui.text.input.ImeAction
@@ -33,17 +27,17 @@ import dalvikus.composeapp.generated.resources.Res
3327
import dalvikus.composeapp.generated.resources.editor_cannot_open
3428
import dalvikus.composeapp.generated.resources.fab_save_and_assemble
3529
import kotlinx.coroutines.delay
36-
import me.lkl.dalvikus.tabs.TabElement
37-
import me.lkl.dalvikus.theme.JetBrainsMono
38-
import me.lkl.dalvikus.ui.editor.highlight.defaultCodeHighlightColors
39-
import me.lkl.dalvikus.util.handleFocusedCtrlShortcuts
4030
import me.lkl.dalvikus.settings.shortcutSave
4131
import me.lkl.dalvikus.tabs.SmaliTab
32+
import me.lkl.dalvikus.tabs.TabElement
33+
import me.lkl.dalvikus.theme.JetBrainsMono
4234
import me.lkl.dalvikus.theme.LocalThemeIsDark
35+
import me.lkl.dalvikus.ui.editor.highlight.defaultCodeHighlightColors
4336
import me.lkl.dalvikus.ui.editor.suggestions.AssistPopup
4437
import me.lkl.dalvikus.ui.editor.suggestions.ErrorPopup
4538
import me.lkl.dalvikus.ui.editor.suggestions.HexPopup
4639
import me.lkl.dalvikus.ui.editor.suggestions.LookupPopup
40+
import me.lkl.dalvikus.util.handleFocusedCtrlShortcuts
4741
import org.jetbrains.compose.resources.stringResource
4842

4943
data class LayoutSnapshot(val layout: TextLayoutResult, val textFieldValue: TextFieldValue)
@@ -118,17 +112,20 @@ fun EditorView(tabElement: TabElement) {
118112
Scaffold(
119113
containerColor = Color.Transparent,
120114
floatingActionButton = {
121-
if(viewModel.hasUnsavedChanges())
122-
ExtendedFloatingActionButton(
123-
modifier = Modifier.padding(bottom = 8.dp, end = 8.dp),
124-
onClick = { viewModel.saveCode(coroutine) },
125-
icon = {
126-
Icon(Icons.Default.SaveAs, contentDescription = stringResource(Res.string.fab_save_and_assemble))
127-
},
128-
text = {
129-
Text(stringResource(Res.string.fab_save_and_assemble))
130-
}
131-
)
115+
if (viewModel.hasUnsavedChanges())
116+
ExtendedFloatingActionButton(
117+
modifier = Modifier.padding(bottom = 8.dp, end = 8.dp),
118+
onClick = { viewModel.saveCode(coroutine) },
119+
icon = {
120+
Icon(
121+
Icons.Default.SaveAs,
122+
contentDescription = stringResource(Res.string.fab_save_and_assemble)
123+
)
124+
},
125+
text = {
126+
Text(stringResource(Res.string.fab_save_and_assemble))
127+
}
128+
)
132129
},
133130
modifier = Modifier.fillMaxSize().then(viewModel.popupKeyEvents)
134131
) {
@@ -174,7 +171,8 @@ fun EditorView(tabElement: TabElement) {
174171
.focusRequester(focusRequester)
175172
.handleFocusedCtrlShortcuts(
176173
enabled = viewModel.editable,
177-
mapOf(shortcutSave to { viewModel.saveCode(coroutine) })),
174+
mapOf(shortcutSave to { viewModel.saveCode(coroutine) })
175+
),
178176

179177
textStyle = textStyle.copy(
180178
color = Color.Black.copy(alpha = 0.0f)
@@ -204,30 +202,34 @@ fun EditorView(tabElement: TabElement) {
204202
}
205203
}
206204
)
207-
if(tabElement is SmaliTab) {
205+
if (tabElement is SmaliTab) {
208206
AssistPopup(
209207
assistPopupState = viewModel.assistPopupState,
210208
viewModel = viewModel,
211209
lastLayoutSnapshot = lastLayoutSnapshot,
212210
textStyle = textStyle,
213211
highlightColors = viewModel.highlightColors
214212
)
215-
val start = viewModel.internalContent.selection.start
216-
val end = viewModel.internalContent.selection.end
213+
}
214+
val start = viewModel.internalContent.selection.start
215+
val end = viewModel.internalContent.selection.end
217216

218-
// these are annotated in the smali highlighter
219-
listOf("error", "class", "hex").forEach { tag ->
220-
viewModel.highlightedText.getStringAnnotations(tag, start, end).firstOrNull()?.let {
221-
when (tag) {
222-
"error" -> ErrorPopup(lastLayoutSnapshot, it, viewModel, textStyle)
223-
"class" -> LookupPopup(tabElement, lastLayoutSnapshot, it, viewModel, textStyle)
224-
"hex" -> HexPopup(it, textStyle, lastLayoutSnapshot, viewModel)
217+
// these are annotated in the smali highlighter
218+
listOf("error", "class", "hex").forEach { tag ->
219+
viewModel.highlightedText.getStringAnnotations(tag, start, end).firstOrNull()?.let {
220+
when (tag) {
221+
"error" -> ErrorPopup(lastLayoutSnapshot, it, viewModel, textStyle)
222+
"class" -> {
223+
if (tabElement is SmaliTab) {
224+
LookupPopup(tabElement, lastLayoutSnapshot, it, viewModel, textStyle)
225+
}
225226
}
226-
return@forEach // stops after showing the first popup
227+
"hex" -> HexPopup(it, textStyle, lastLayoutSnapshot, viewModel)
227228
}
229+
return@forEach // stops after showing the first popup
228230
}
229-
230231
}
232+
231233
}
232234

233235
VerticalScrollbar(
@@ -253,7 +255,7 @@ fun EditorView(tabElement: TabElement) {
253255
@Composable
254256
fun EditorCannotOpen() {
255257
Box(Modifier.fillMaxSize().padding(32.dp), contentAlignment = Alignment.Center) {
256-
Column (
258+
Column(
257259
horizontalAlignment = Alignment.CenterHorizontally,
258260
verticalArrangement = Arrangement.Center
259261
) {

composeApp/src/commonMain/kotlin/me/lkl/dalvikus/ui/editor/suggestions/Popups.kt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,31 +120,30 @@ fun HexPopup(
120120
lastLayoutSnapshot: LayoutSnapshot?,
121121
viewModel: EditorViewModel
122122
) {
123-
val rawHex = annotation.item.trim()
123+
val rawHex = annotation.item.trim().lowercase()
124124
val isNegative = rawHex.startsWith("-")
125-
val cleanedHex = rawHex.removePrefix("-").removePrefix("0x").removePrefix("0X")
125+
val cleanedHex = rawHex.removePrefix("-").removePrefix("0x")
126126

127127
val infoText = try {
128128
val unsignedValue = cleanedHex.toBigInteger(16)
129129
val signedValue = if (isNegative) -unsignedValue else unsignedValue
130130

131131
when (cleanedHex.length) {
132132
8 -> {
133-
println(cleanedHex)
134133
if(cleanedHex.startsWith("7e") || cleanedHex.startsWith("7f")) {
135134
"$cleanedHex (resource ID) = ${viewModel.tryResolveResIdText(unsignedValue)} (resolved) "
136135
} else {
137136
val floatValue = Float.fromBits(signedValue.toInt())
138-
"$signedValue (base 10) = $floatValue (float)"
137+
"$signedValue (dec) = $floatValue (float)"
139138
}
140139
}
141140

142141
16 -> {
143142
val doubleValue = Double.fromBits(signedValue.toLong())
144-
"$signedValue (base 10) = $doubleValue (double)"
143+
"$signedValue (dec) = $doubleValue (double)"
145144
}
146145

147-
else -> "$signedValue (base 10)"
146+
else -> "$rawHex (hex) = $signedValue (dec)"
148147
}
149148
} catch (e: Exception) {
150149
"Invalid hex: $rawHex"

composeApp/src/jvmMain/kotlin/me/lkl/dalvikus/lexer/JavaLexerHighlight.jvm.kt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,21 @@ actual fun highlightJavaCode(code: String, colors: CodeHighlightColors): Annotat
2525
for (token in tokens.tokens) {
2626
if (token.type == -1 || token.text.isBlank()) continue
2727

28+
val start = token.startIndex
29+
val end = token.stopIndex + 1
30+
31+
if (token.type == Java20Lexer.IntegerLiteral) {
32+
if (token.text.startsWith("0x") || token.text.startsWith("-0x")) {
33+
addStringAnnotation("hex", token.text, start, end)
34+
} else {
35+
token.text.toLongOrNull()?.let {
36+
addStringAnnotation("hex", "0x${it.toString(16).uppercase()}", start, end)
37+
}
38+
}
39+
}
40+
2841
getJava20TokenStyle(token.type, colors)?.let {
29-
addStyle(it, token.startIndex, token.stopIndex + 1)
42+
addStyle(it, start, end)
3043
}
3144
}
3245
}

0 commit comments

Comments
 (0)