From: Yuka Takahashi Date: Tue, 29 Aug 2017 17:46:46 +0000 (+0000) Subject: [Bash-autocomplete] Refactor autocomplete code into own function X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c39ec45ed8e34f24e29e6005a1c1cbb3a6292944;p=clang [Bash-autocomplete] Refactor autocomplete code into own function Summary: We wrote many codes in HandleImediateArgs, so I've refactored it into handleAutocompletions. Reviewers: v.g.vassilev, teemperor Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D37249 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@312018 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h index e81fe4635f..a3662872a9 100644 --- a/include/clang/Driver/Driver.h +++ b/include/clang/Driver/Driver.h @@ -425,6 +425,10 @@ public: // FIXME: This should be in CompilationInfo. std::string GetProgramPath(StringRef Name, const ToolChain &TC) const; + /// handleAutocompletions - Handle --autocomplete by searching and printing + /// possible flags, descriptions, and its arguments. + void handleAutocompletions(StringRef PassedFlags) const; + /// HandleImmediateArgs - Handle any arguments which should be /// treated before building actions or binding tools. /// diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 5340d8abe1..cf0962b286 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -1156,6 +1156,56 @@ static void PrintDiagnosticCategories(raw_ostream &OS) { OS << i << ',' << DiagnosticIDs::getCategoryNameFromID(i) << '\n'; } +void Driver::handleAutocompletions(StringRef PassedFlags) const { + // Print out all options that start with a given argument. This is used for + // shell autocompletion. + std::vector SuggestedCompletions; + + unsigned short DisableFlags = + options::NoDriverOption | options::Unsupported | options::Ignored; + // We want to show cc1-only options only when clang is invoked as "clang + // -cc1". + // When clang is invoked as "clang -cc1", we add "#" to the beginning of an + // --autocomplete + // option so that the clang driver can distinguish whether it is requested to + // show cc1-only options or not. + if (PassedFlags[0] == '#') { + DisableFlags &= ~options::NoDriverOption; + PassedFlags = PassedFlags.substr(1); + } + + if (PassedFlags.find(',') == StringRef::npos) { + // If the flag is in the form of "--autocomplete=-foo", + // we were requested to print out all option names that start with "-foo". + // For example, "--autocomplete=-fsyn" is expanded to "-fsyntax-only". + SuggestedCompletions = Opts->findByPrefix(PassedFlags, DisableFlags); + + // We have to query the -W flags manually as they're not in the OptTable. + // TODO: Find a good way to add them to OptTable instead and them remove + // this code. + for (StringRef S : DiagnosticIDs::getDiagnosticFlags()) + if (S.startswith(PassedFlags)) + SuggestedCompletions.push_back(S); + } else { + // If the flag is in the form of "--autocomplete=foo,bar", we were + // requested to print out all option values for "-foo" that start with + // "bar". For example, + // "--autocomplete=-stdlib=,l" is expanded to "libc++" and "libstdc++". + StringRef Option, Arg; + std::tie(Option, Arg) = PassedFlags.split(','); + SuggestedCompletions = Opts->suggestValueCompletions(Option, Arg); + } + + // Sort the autocomplete candidates so that shells print them out in a + // deterministic order. We could sort in any way, but we chose + // case-insensitive sorting for consistency with the -help option + // which prints out options in the case-insensitive alphabetical order. + std::sort(SuggestedCompletions.begin(), SuggestedCompletions.end(), + [](StringRef A, StringRef B) { return A.compare_lower(B) < 0; }); + + llvm::outs() << llvm::join(SuggestedCompletions, "\n") << '\n'; +} + bool Driver::HandleImmediateArgs(const Compilation &C) { // The order these options are handled in gcc is all over the place, but we // don't expect inconsistencies w.r.t. that to matter in practice. @@ -1249,50 +1299,8 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { } if (Arg *A = C.getArgs().getLastArg(options::OPT_autocomplete)) { - // Print out all options that start with a given argument. This is used for - // shell autocompletion. StringRef PassedFlags = A->getValue(); - std::vector SuggestedCompletions; - - unsigned short DisableFlags = options::NoDriverOption | options::Unsupported | options::Ignored; - // We want to show cc1-only options only when clang is invoked as "clang -cc1". - // When clang is invoked as "clang -cc1", we add "#" to the beginning of an --autocomplete - // option so that the clang driver can distinguish whether it is requested to show cc1-only options or not. - if (PassedFlags[0] == '#') { - DisableFlags &= ~options::NoDriverOption; - PassedFlags = PassedFlags.substr(1); - } - - if (PassedFlags.find(',') == StringRef::npos) { - // If the flag is in the form of "--autocomplete=-foo", - // we were requested to print out all option names that start with "-foo". - // For example, "--autocomplete=-fsyn" is expanded to "-fsyntax-only". - SuggestedCompletions = Opts->findByPrefix(PassedFlags, DisableFlags); - - // We have to query the -W flags manually as they're not in the OptTable. - // TODO: Find a good way to add them to OptTable instead and them remove - // this code. - for (StringRef S : DiagnosticIDs::getDiagnosticFlags()) - if (S.startswith(PassedFlags)) - SuggestedCompletions.push_back(S); - } else { - // If the flag is in the form of "--autocomplete=foo,bar", we were - // requested to print out all option values for "-foo" that start with - // "bar". For example, - // "--autocomplete=-stdlib=,l" is expanded to "libc++" and "libstdc++". - StringRef Option, Arg; - std::tie(Option, Arg) = PassedFlags.split(','); - SuggestedCompletions = Opts->suggestValueCompletions(Option, Arg); - } - - // Sort the autocomplete candidates so that shells print them out in a - // deterministic order. We could sort in any way, but we chose - // case-insensitive sorting for consistency with the -help option - // which prints out options in the case-insensitive alphabetical order. - std::sort(SuggestedCompletions.begin(), SuggestedCompletions.end(), - [](StringRef A, StringRef B) { return A.compare_lower(B) < 0; }); - - llvm::outs() << llvm::join(SuggestedCompletions, "\n") << '\n'; + handleAutocompletions(PassedFlags); return false; }