Skip to content

Commit c1d15dc

Browse files
fix(parser): Resolve compilation error and improve command type handling
Corrected a compilation error in CommandParser.kt caused by duplicate declarations of `MatchResultPlaceholder`. Additionally, refactored `processTextInternal` to: - Store `CommandTypeEnum` directly with parsed command matches using a new `ProcessedMatch` data class. - Use this directly stored `commandType` for single-instance command checks, eliminating a previous, less reliable method of comparing command builder lambdas. - Removed the `MatchResultPlaceholder` variable as it's no longer needed. These changes make the parser more robust and fix the build failure.
1 parent a4dcb28 commit c1d15dc

1 file changed

Lines changed: 33 additions & 57 deletions

File tree

app/src/main/kotlin/com/google/ai/sample/util/CommandParser.kt

Lines changed: 33 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ object CommandParser {
221221
* Process text to find commands
222222
*/
223223
private fun processTextInternal(text: String): List<Command> {
224-
val foundRawMatches = mutableListOf<Triple<Int, Int, Command>>()
224+
data class ProcessedMatch(val startIndex: Int, val endIndex: Int, val command: Command, val type: CommandTypeEnum)
225+
val foundRawMatches = mutableListOf<ProcessedMatch>()
225226
val finalCommands = mutableListOf<Command>()
226227
val addedSingleInstanceCommands = mutableSetOf<CommandTypeEnum>()
227228

@@ -230,8 +231,9 @@ object CommandParser {
230231
patternInfo.regex.findAll(text).forEach { matchResult ->
231232
try {
232233
val command = patternInfo.commandBuilder(matchResult)
233-
foundRawMatches.add(Triple(matchResult.range.first, matchResult.range.last, command))
234-
Log.d(TAG, "Found raw match: Start=${matchResult.range.first}, End=${matchResult.range.last}, Command=${command}, Pattern=${patternInfo.id}")
234+
// Store the commandType from the patternInfo that generated this command
235+
foundRawMatches.add(ProcessedMatch(matchResult.range.first, matchResult.range.last, command, patternInfo.commandType))
236+
Log.d(TAG, "Found raw match: Start=${matchResult.range.first}, End=${matchResult.range.last}, Command=${command}, Type=${patternInfo.commandType}, Pattern=${patternInfo.id}")
235237
} catch (e: Exception) {
236238
Log.e(TAG, "Error building command for pattern ${patternInfo.id} with match ${matchResult.value}: ${e.message}", e)
237239
}
@@ -242,58 +244,43 @@ object CommandParser {
242244
}
243245

244246
// Sort matches by start index
245-
foundRawMatches.sortBy { it.first }
247+
foundRawMatches.sortBy { it.startIndex }
246248
Log.d(TAG, "Sorted raw matches (${foundRawMatches.size}): $foundRawMatches")
247249

248250
var currentPosition = 0
249-
for ((startIndex, endIndex, command) in foundRawMatches) {
251+
for (processedMatch in foundRawMatches) {
252+
val (startIndex, endIndex, command, commandTypeFromMatch) = processedMatch // Destructure
250253
if (startIndex >= currentPosition) {
251-
// Handle single-instance commands
252-
val commandType = ALL_PATTERNS.find { it.commandBuilder(MatchResultPlaceholder) == command || (it.commandBuilder(MatchResultPlaceholder)::class == command::class && command is Command.WriteText) }?.commandType // This is a bit hacky for comparison
253-
254254
var canAdd = true
255-
if (commandType != null) {
256-
val isSingleInstanceType = when (commandType) {
257-
CommandTypeEnum.TAKE_SCREENSHOT,
258-
CommandTypeEnum.PRESS_HOME,
259-
CommandTypeEnum.PRESS_BACK,
260-
CommandTypeEnum.SHOW_RECENT_APPS,
261-
CommandTypeEnum.USE_HIGH_REASONING_MODEL,
262-
CommandTypeEnum.USE_LOW_REASONING_MODEL,
263-
CommandTypeEnum.PRESS_ENTER_KEY -> true
264-
else -> false
265-
}
266-
if (isSingleInstanceType) {
267-
if (addedSingleInstanceCommands.contains(commandType)) {
268-
canAdd = false
269-
Log.d(TAG, "Skipping duplicate single-instance command: $command (Type: $commandType)")
270-
} else {
271-
addedSingleInstanceCommands.add(commandType)
272-
}
255+
// Use commandTypeFromMatch directly here
256+
val isSingleInstanceType = when (commandTypeFromMatch) {
257+
CommandTypeEnum.TAKE_SCREENSHOT,
258+
CommandTypeEnum.PRESS_HOME,
259+
CommandTypeEnum.PRESS_BACK,
260+
CommandTypeEnum.SHOW_RECENT_APPS,
261+
CommandTypeEnum.USE_HIGH_REASONING_MODEL,
262+
CommandTypeEnum.USE_LOW_REASONING_MODEL,
263+
CommandTypeEnum.PRESS_ENTER_KEY -> true
264+
else -> false
265+
}
266+
if (isSingleInstanceType) {
267+
if (addedSingleInstanceCommands.contains(commandTypeFromMatch)) {
268+
canAdd = false
269+
Log.d(TAG, "Skipping duplicate single-instance command: $command (Type: $commandTypeFromMatch)")
270+
} else {
271+
addedSingleInstanceCommands.add(commandTypeFromMatch)
273272
}
274273
}
275274

276-
277275
if (canAdd) {
278-
// Basic duplicate check for parameterized commands based on content (already handled by some old logic, kept for safety)
279-
val isLikelyDuplicate = finalCommands.any {
280-
it::class == command::class && when(it) {
281-
is Command.ClickButton -> it.buttonText == (command as? Command.ClickButton)?.buttonText
282-
is Command.TapCoordinates -> it.x == (command as? Command.TapCoordinates)?.x && it.y == (command as? Command.TapCoordinates)?.y
283-
is Command.WriteText -> it.text == (command as? Command.WriteText)?.text
284-
is Command.OpenApp -> it.packageName == (command as? Command.OpenApp)?.packageName
285-
// Add more types if necessary
286-
else -> false // For non-parameterized or unique types, this won't prevent addition
287-
}
288-
}
289-
290-
if (!isLikelyDuplicate || commandType == null || !addedSingleInstanceCommands.contains(commandType)) { // Ensure single instance types are not re-added due to this check
291-
finalCommands.add(command)
292-
currentPosition = endIndex + 1
293-
Log.d(TAG, "Added command: $command. New currentPosition: $currentPosition")
294-
} else if (isLikelyDuplicate) {
295-
Log.d(TAG, "Skipping likely duplicate parameterized command: $command")
296-
}
276+
// Simplified duplicate check: if it's not a single instance type, allow it.
277+
// More sophisticated duplicate checks for parameterized commands can be added here if needed.
278+
// For now, only single-instance types are strictly controlled for duplication.
279+
// The overlap filter (startIndex >= currentPosition) already prevents identical commands
280+
// from the exact same text span.
281+
finalCommands.add(command)
282+
currentPosition = endIndex + 1
283+
Log.d(TAG, "Added command: $command. New currentPosition: $currentPosition")
297284
}
298285
} else {
299286
Log.d(TAG, "Skipping overlapping command: $command (startIndex $startIndex < currentPosition $currentPosition)")
@@ -303,12 +290,6 @@ object CommandParser {
303290
return finalCommands
304291
}
305292

306-
// Placeholder for commandBuilder comparison, not used for actual matching.
307-
private val MatchResultPlaceholder by lazy {
308-
Regex("").find("")!!
309-
}
310-
311-
312293
/**
313294
* Process text to find commands
314295
*/
@@ -317,11 +298,6 @@ object CommandParser {
317298
commands.addAll(extractedCommands)
318299
}
319300

320-
// Placeholder for commandBuilder comparison, not used for actual matching.
321-
private val MatchResultPlaceholder by lazy {
322-
Regex("").find("")!!
323-
}
324-
325301
/**
326302
* Normalize text by trimming whitespace and normalizing line breaks
327303
*/

0 commit comments

Comments
 (0)