Skip to content

Commit 8191832

Browse files
committed
Change logic to ensure compatibility
1 parent 6a4a80f commit 8191832

File tree

3 files changed

+66
-51
lines changed

3 files changed

+66
-51
lines changed

lldb/source/Interpreter/CommandInterpreter.cpp

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,23 +1019,25 @@ CommandInterpreter::VerifyUserMultiwordCmdPath(Args &path, bool leaf_is_command,
10191019
}
10201020

10211021
CommandObjectSP CommandInterpreter::GetFrameLanguageCommand() const {
1022-
if (auto frame_sp = GetExecutionContext().GetFrameSP()) {
1023-
auto frame_language = Language::GetPrimaryLanguage(
1024-
frame_sp->GuessLanguage().AsLanguageType());
1025-
1026-
auto it = m_command_dict.find("language");
1027-
if (it != m_command_dict.end()) {
1028-
// The root "language" command.
1029-
CommandObjectSP language_cmd_sp = it->second;
1030-
1031-
if (auto *plugin = Language::FindPlugin(frame_language)) {
1032-
// "cplusplus", "objc", etc.
1033-
auto lang_name = plugin->GetPluginName();
1034-
return language_cmd_sp->GetSubcommandSPExact(lang_name);
1035-
}
1036-
}
1037-
}
1038-
return {};
1022+
auto frame_sp = GetExecutionContext().GetFrameSP();
1023+
if (!frame_sp)
1024+
return {};
1025+
auto frame_language =
1026+
Language::GetPrimaryLanguage(frame_sp->GuessLanguage().AsLanguageType());
1027+
1028+
auto it = m_command_dict.find("language");
1029+
if (it == m_command_dict.end())
1030+
return {};
1031+
// The root "language" command.
1032+
CommandObjectSP language_cmd_sp = it->second;
1033+
1034+
auto *plugin = Language::FindPlugin(frame_language);
1035+
if (!plugin)
1036+
return {};
1037+
// "cplusplus", "objc", etc.
1038+
auto lang_name = plugin->GetPluginName();
1039+
1040+
return language_cmd_sp->GetSubcommandSPExact(lang_name);
10391041
}
10401042

10411043
CommandObjectSP
@@ -1070,20 +1072,11 @@ CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, bool include_aliases,
10701072
command_sp = pos->second;
10711073
}
10721074

1073-
// The `language` subcommand ("language objc", "language cplusplus", etc).
1074-
CommandObjectMultiword *lang_subcmd = nullptr;
1075-
if (!command_sp) {
1076-
if (auto subcmd_sp = GetFrameLanguageCommand()) {
1077-
lang_subcmd = subcmd_sp->GetAsMultiwordCommand();
1078-
command_sp = subcmd_sp->GetSubcommandSPExact(cmd_str);
1079-
}
1080-
}
1081-
10821075
if (!exact && !command_sp) {
10831076
// We will only get into here if we didn't find any exact matches.
10841077

10851078
CommandObjectSP user_match_sp, user_mw_match_sp, alias_match_sp,
1086-
real_match_sp, lang_match_sp;
1079+
real_match_sp;
10871080

10881081
StringList local_matches;
10891082
if (matches == nullptr)
@@ -1093,7 +1086,6 @@ CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, bool include_aliases,
10931086
unsigned int num_alias_matches = 0;
10941087
unsigned int num_user_matches = 0;
10951088
unsigned int num_user_mw_matches = 0;
1096-
unsigned int num_lang_matches = 0;
10971089

10981090
// Look through the command dictionaries one by one, and if we get only one
10991091
// match from any of them in toto, then return that, otherwise return an
@@ -1151,41 +1143,49 @@ CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, bool include_aliases,
11511143
user_mw_match_sp = pos->second;
11521144
}
11531145

1154-
if (lang_subcmd) {
1155-
num_lang_matches =
1156-
AddNamesMatchingPartialString(lang_subcmd->GetSubcommandDictionary(),
1157-
cmd_str, *matches, descriptions);
1158-
}
1159-
1160-
if (num_lang_matches == 1) {
1161-
cmd.assign(matches->GetStringAtIndex(num_cmd_matches + num_alias_matches +
1162-
num_user_matches +
1163-
num_user_mw_matches));
1164-
1165-
auto &lang_dict = lang_subcmd->GetSubcommandDictionary();
1166-
auto pos = lang_dict.find(cmd);
1167-
if (pos != lang_dict.end())
1168-
lang_match_sp = pos->second;
1169-
}
1170-
11711146
// If we got exactly one match, return that, otherwise return the match
11721147
// list.
11731148

11741149
if (num_user_matches + num_user_mw_matches + num_cmd_matches +
1175-
num_alias_matches + num_lang_matches ==
1150+
num_alias_matches ==
11761151
1) {
11771152
if (num_cmd_matches)
11781153
return real_match_sp;
11791154
else if (num_alias_matches)
11801155
return alias_match_sp;
11811156
else if (num_user_mw_matches)
11821157
return user_mw_match_sp;
1183-
else if (num_user_matches)
1184-
return user_match_sp;
11851158
else
1186-
return lang_match_sp;
1159+
return user_match_sp;
1160+
}
1161+
}
1162+
1163+
// When no single match is found, attempt to resolve the command as a language
1164+
// plugin subcommand.
1165+
if (!command_sp) {
1166+
// The `language` subcommand ("language objc", "language cplusplus", etc).
1167+
CommandObjectMultiword *lang_subcmd = nullptr;
1168+
if (auto lang_subcmd_sp = GetFrameLanguageCommand()) {
1169+
lang_subcmd = lang_subcmd_sp->GetAsMultiwordCommand();
1170+
command_sp = lang_subcmd_sp->GetSubcommandSPExact(cmd_str);
1171+
}
1172+
1173+
if (!command_sp && !exact && lang_subcmd) {
1174+
StringList lang_matches;
1175+
AddNamesMatchingPartialString(lang_subcmd->GetSubcommandDictionary(),
1176+
cmd_str, lang_matches, descriptions);
1177+
if (matches)
1178+
matches->AppendList(lang_matches);
1179+
if (lang_matches.GetSize() == 1) {
1180+
const auto &lang_dict = lang_subcmd->GetSubcommandDictionary();
1181+
auto pos = lang_dict.find(lang_matches[0]);
1182+
if (pos != lang_dict.end())
1183+
return pos->second;
1184+
}
11871185
}
1188-
} else if (matches && command_sp) {
1186+
}
1187+
1188+
if (matches && command_sp) {
11891189
matches->AppendString(cmd_str);
11901190
if (descriptions)
11911191
descriptions->AppendString(command_sp->GetHelp());

lldb/test/API/commands/command/language/TestFrameLanguageCommands.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from lldbsuite.test.decorators import *
44
import lldbsuite.test.lldbutil as lldbutil
55

6-
76
class TestCase(TestBase):
87
def test(self):
98
self.build()
@@ -48,3 +47,14 @@ def test(self):
4847
"info -- Dump information on a tagged pointer.",
4948
],
5049
)
50+
51+
# To ensure compatability with existing scripts, a language specific
52+
# command must not be invoked if another command (such as a python
53+
# command) has the language specific command name as its prefix.
54+
#
55+
# For example, this test loads a `tagged-pointer-collision` command. A
56+
# script could exist that invokes this command using its prefix
57+
# `tagged-pointer`, under the assumption that "tagged-pointer" uniquely
58+
# identifies the python command `tagged-pointer-collision`.
59+
self.runCmd("command script import commands.py")
60+
self.expect("tagged-pointer", startstr="ran tagged-pointer-collision")
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import lldb
2+
3+
@lldb.command("tagged-pointer-collision")
4+
def noop(dbg, cmdstr, ctx, result, _):
5+
print("ran tagged-pointer-collision", file=result)

0 commit comments

Comments
 (0)