Exemplo n.º 1
0
TEST(Option, SlurpJoinedOneJoined) {
  TestOptTable T;
  unsigned MAI, MAC;

  const char *MyArgs[] = { "-A", "-slurpjoinedfoo" };
  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
  EXPECT_TRUE(AL.hasArg(OPT_A));
  EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));
  EXPECT_EQ(AL.getAllArgValues(OPT_SlurpJoined).size(), 1U);
  EXPECT_EQ(AL.getAllArgValues(OPT_SlurpJoined)[0], "foo");
}
Exemplo n.º 2
0
TEST(Option, AliasArgs) {
  TestOptTable T;
  unsigned MAI, MAC;

  const char *MyArgs[] = { "-J", "-Joo" };
  std::unique_ptr<InputArgList> AL(
      T.ParseArgs(MyArgs, array_endof(MyArgs), MAI, MAC));
  EXPECT_TRUE(AL->hasArg(OPT_B));
  EXPECT_EQ(AL->getAllArgValues(OPT_B)[0], "foo");
  EXPECT_EQ(AL->getAllArgValues(OPT_B)[1], "bar");
}
Exemplo n.º 3
0
TEST(DISABLED_Option, FindNearestFIXME) {
  TestOptTable T;
  std::string Nearest;

  // FIXME: Options with joined values should not have those values considered
  // when calculating distance. The test below would fail if run, but it should
  // succeed.
  EXPECT_EQ(1U, T.findNearest("--erbghFoo", Nearest));
  EXPECT_EQ(Nearest, "--ermghFoo");

}
Exemplo n.º 4
0
TEST(Option, FlagAliasToJoined) {
  TestOptTable T;
  unsigned MAI, MAC;

  // Check that a flag alias provides an empty argument to a joined option.
  const char *MyArgs[] = { "-K" };
  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
  EXPECT_EQ(AL.size(), 1U);
  EXPECT_TRUE(AL.hasArg(OPT_B));
  EXPECT_EQ(1U, AL.getAllArgValues(OPT_B).size());
  EXPECT_EQ("", AL.getAllArgValues(OPT_B)[0]);
}
TEST(Option, DashDash) {
  TestOptTable T;
  unsigned MAI, MAC;

  const char *MyArgs[] = { "-A", "--", "-B", "--" };
  OwningPtr<InputArgList> AL(T.ParseArgs(MyArgs, array_endof(MyArgs), MAI, MAC));
  EXPECT_TRUE(AL->hasArg(OPT_A));
  EXPECT_FALSE(AL->hasArg(OPT_B));
  EXPECT_EQ(AL->getAllArgValues(OPT_INPUT).size(), 2U);
  EXPECT_EQ(AL->getAllArgValues(OPT_INPUT)[0], "-B");
  EXPECT_EQ(AL->getAllArgValues(OPT_INPUT)[1], "--");
}
Exemplo n.º 6
0
void TestOptions::printHelp(bool ShowHidden) const {

  // Based off of swift/lib/Driver/Driver.cpp, at Driver::printHelp
  //FIXME: should we use IncludedFlagsBitmask and ExcludedFlagsBitmask?
  // Maybe not for modes such as Interactive, Batch, AutolinkExtract, etc,
  // as in Driver.cpp. But could be useful for extra info, like HelpHidden.

  TestOptTable Table;

  Table.PrintHelp(llvm::outs(), "sourcekitd-test", "SourceKit Testing Tool",
                      ShowHidden);
}
Exemplo n.º 7
0
TEST(Option, SlurpJoinedButSeparate) {
  TestOptTable T;
  unsigned MAI, MAC;

  const char *MyArgs[] = { "-A", "-slurpjoined", "foo", "bar", "baz" };
  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
  EXPECT_TRUE(AL.hasArg(OPT_A));
  EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));
  EXPECT_EQ(3U, AL.getAllArgValues(OPT_SlurpJoined).size());
  EXPECT_EQ("foo", AL.getAllArgValues(OPT_SlurpJoined)[0]);
  EXPECT_EQ("bar", AL.getAllArgValues(OPT_SlurpJoined)[1]);
  EXPECT_EQ("baz", AL.getAllArgValues(OPT_SlurpJoined)[2]);
}
Exemplo n.º 8
0
TEST(Option, Slurp) {
  TestOptTable T;
  unsigned MAI, MAC;

  const char *MyArgs[] = { "-A", "-slurp", "-B", "--", "foo" };
  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
  EXPECT_EQ(AL.size(), 2U);
  EXPECT_TRUE(AL.hasArg(OPT_A));
  EXPECT_FALSE(AL.hasArg(OPT_B));
  EXPECT_TRUE(AL.hasArg(OPT_Slurp));
  EXPECT_EQ(3U, AL.getAllArgValues(OPT_Slurp).size());
  EXPECT_EQ("-B", AL.getAllArgValues(OPT_Slurp)[0]);
  EXPECT_EQ("--", AL.getAllArgValues(OPT_Slurp)[1]);
  EXPECT_EQ("foo", AL.getAllArgValues(OPT_Slurp)[2]);
}
Exemplo n.º 9
0
TEST(Option, Slurp) {
  TestOptTable T;
  unsigned MAI, MAC;

  const char *MyArgs[] = { "-A", "-slurp", "-B", "--", "foo" };
  std::unique_ptr<InputArgList> AL(
      T.ParseArgs(MyArgs, array_endof(MyArgs), MAI, MAC));
  EXPECT_EQ(AL->size(), 2U);
  EXPECT_TRUE(AL->hasArg(OPT_A));
  EXPECT_FALSE(AL->hasArg(OPT_B));
  EXPECT_TRUE(AL->hasArg(OPT_Slurp));
  EXPECT_EQ(AL->getAllArgValues(OPT_Slurp).size(), 3U);
  EXPECT_EQ(AL->getAllArgValues(OPT_Slurp)[0], "-B");
  EXPECT_EQ(AL->getAllArgValues(OPT_Slurp)[1], "--");
  EXPECT_EQ(AL->getAllArgValues(OPT_Slurp)[2], "foo");
}
Exemplo n.º 10
0
TEST(Option, OptionParsing) {
  TestOptTable T;
  unsigned MAI, MAC;
  InputArgList AL = T.ParseArgs(Args, MAI, MAC);

  // Check they all exist.
  EXPECT_TRUE(AL.hasArg(OPT_A));
  EXPECT_TRUE(AL.hasArg(OPT_B));
  EXPECT_TRUE(AL.hasArg(OPT_C));
  EXPECT_TRUE(AL.hasArg(OPT_D));
  EXPECT_TRUE(AL.hasArg(OPT_E));
  EXPECT_TRUE(AL.hasArg(OPT_F));
  EXPECT_TRUE(AL.hasArg(OPT_G));

  // Check the values.
  EXPECT_EQ("hi", AL.getLastArgValue(OPT_B));
  EXPECT_EQ("bye", AL.getLastArgValue(OPT_C));
  EXPECT_EQ("adena", AL.getLastArgValue(OPT_D));
  std::vector<std::string> Es = AL.getAllArgValues(OPT_E);
  EXPECT_EQ("apple", Es[0]);
  EXPECT_EQ("bloom", Es[1]);
  EXPECT_EQ("42", AL.getLastArgValue(OPT_F));
  std::vector<std::string> Gs = AL.getAllArgValues(OPT_G);
  EXPECT_EQ("chuu", Gs[0]);
  EXPECT_EQ("2", Gs[1]);

  // Check the help text.
  std::string Help;
  raw_string_ostream RSO(Help);
  T.PrintHelp(RSO, "test", "title!");
  EXPECT_NE(std::string::npos, Help.find("-A"));

  // Check usage line.
  T.PrintHelp(RSO, "name [options] file...", "title!");
  EXPECT_NE(std::string::npos, Help.find("USAGE: name [options] file...\n"));

  // Test aliases.
  auto Cs = AL.filtered(OPT_C);
  ASSERT_NE(Cs.begin(), Cs.end());
  EXPECT_EQ("desu", StringRef((*Cs.begin())->getValue()));
  ArgStringList ASL;
  (*Cs.begin())->render(AL, ASL);
  ASSERT_EQ(2u, ASL.size());
  EXPECT_EQ("-C", StringRef(ASL[0]));
  EXPECT_EQ("desu", StringRef(ASL[1]));
}
Exemplo n.º 11
0
TEST(Support, OptionParsing) {
  TestOptTable T;
  unsigned MAI, MAC;
  OwningPtr<InputArgList>
    AL(T.ParseArgs(Args,
                   Args + (sizeof(Args) / sizeof(Args[0])),
                   MAI,
                   MAC));

  // Check they all exist.
  EXPECT_TRUE(AL->hasArg(OPT_A));
  EXPECT_TRUE(AL->hasArg(OPT_B));
  EXPECT_TRUE(AL->hasArg(OPT_C));
  EXPECT_TRUE(AL->hasArg(OPT_D));
  EXPECT_TRUE(AL->hasArg(OPT_E));
  EXPECT_TRUE(AL->hasArg(OPT_F));
  EXPECT_TRUE(AL->hasArg(OPT_G));

  // Check the values.
  EXPECT_EQ(AL->getLastArgValue(OPT_B), "hi");
  EXPECT_EQ(AL->getLastArgValue(OPT_C), "bye");
  EXPECT_EQ(AL->getLastArgValue(OPT_D), "adena");
  std::vector<std::string> Es = AL->getAllArgValues(OPT_E);
  EXPECT_EQ(Es[0], "apple");
  EXPECT_EQ(Es[1], "bloom");
  EXPECT_EQ(AL->getLastArgValue(OPT_F), "42");
  std::vector<std::string> Gs = AL->getAllArgValues(OPT_G);
  EXPECT_EQ(Gs[0], "chuu");
  EXPECT_EQ(Gs[1], "2");

  // Check the help text.
  std::string Help;
  raw_string_ostream RSO(Help);
  T.PrintHelp(RSO, "test", "title!");
  EXPECT_NE(Help.find("-A"), std::string::npos);

  // Test aliases.
  arg_iterator Cs = AL->filtered_begin(OPT_C);
  ASSERT_NE(Cs, AL->filtered_end());
  EXPECT_EQ(StringRef((*Cs)->getValue()), "desu");
  ArgStringList ASL;
  (*Cs)->render(*AL, ASL);
  ASSERT_EQ(ASL.size(), 2u);
  EXPECT_EQ(StringRef(ASL[0]), "-C");
  EXPECT_EQ(StringRef(ASL[1]), "desu");
}
Exemplo n.º 12
0
bool TestOptions::parseArgs(llvm::ArrayRef<const char *> Args) {
    if (Args.empty())
        return false;

    // Parse command line options using Options.td
    TestOptTable Table;
    unsigned MissingIndex;
    unsigned MissingCount;
    llvm::opt::InputArgList ParsedArgs =
        Table.ParseArgs(Args, MissingIndex, MissingCount);
    if (MissingCount) {
        llvm::errs() << "error: missing argument value for '"
                     << ParsedArgs.getArgString(MissingIndex) << "', expected "
                     << MissingCount << " argument(s)\n";
        return true;
    }

    for (auto InputArg : ParsedArgs) {
        switch (InputArg->getOption().getID()) {
        case OPT_req:
            Request = llvm::StringSwitch<SourceKitRequest>(InputArg->getValue())
                      .Case("version", SourceKitRequest::ProtocolVersion)
                      .Case("demangle", SourceKitRequest::DemangleNames)
                      .Case("mangle", SourceKitRequest::MangleSimpleClasses)
                      .Case("index", SourceKitRequest::Index)
                      .Case("complete", SourceKitRequest::CodeComplete)
                      .Case("complete.open", SourceKitRequest::CodeCompleteOpen)
                      .Case("complete.close", SourceKitRequest::CodeCompleteClose)
                      .Case("complete.update", SourceKitRequest::CodeCompleteUpdate)
                      .Case("complete.cache.ondisk", SourceKitRequest::CodeCompleteCacheOnDisk)
                      .Case("complete.setpopularapi", SourceKitRequest::CodeCompleteSetPopularAPI)
                      .Case("cursor", SourceKitRequest::CursorInfo)
                      .Case("related-idents", SourceKitRequest::RelatedIdents)
                      .Case("syntax-map", SourceKitRequest::SyntaxMap)
                      .Case("structure", SourceKitRequest::Structure)
                      .Case("format", SourceKitRequest::Format)
                      .Case("expand-placeholder", SourceKitRequest::ExpandPlaceholder)
                      .Case("doc-info", SourceKitRequest::DocInfo)
                      .Case("sema", SourceKitRequest::SemanticInfo)
                      .Case("interface-gen", SourceKitRequest::InterfaceGen)
                      .Case("interface-gen-open", SourceKitRequest::InterfaceGenOpen)
                      .Case("find-usr", SourceKitRequest::FindUSR)
                      .Case("find-interface", SourceKitRequest::FindInterfaceDoc)
                      .Case("open", SourceKitRequest::Open)
                      .Case("edit", SourceKitRequest::Edit)
                      .Case("print-annotations", SourceKitRequest::PrintAnnotations)
                      .Case("print-diags", SourceKitRequest::PrintDiags)
                      .Case("extract-comment", SourceKitRequest::ExtractComment)
                      .Case("module-groups", SourceKitRequest::ModuleGroups)
                      .Default(SourceKitRequest::None);
            if (Request == SourceKitRequest::None) {
                llvm::errs() << "error: invalid request, expected one of "
                             << "version/demangle/mangle/index/complete/cursor/related-idents/syntax-map/structure/"
                             "format/expand-placeholder/doc-info/sema/interface-gen/interface-gen-open/"
                             "find-usr/find-interface/open/edit/print-annotations/extract-comment/"
                             "module-groups\n";
                return true;
            }
            break;

        case OPT_offset:
            if (StringRef(InputArg->getValue()).getAsInteger(10, Offset)) {
                llvm::errs() << "error: expected integer for 'offset'\n";
                return true;
            }
            break;

        case OPT_length:
            if (StringRef(InputArg->getValue()).getAsInteger(10, Length)) {
                llvm::errs() << "error: expected integer for 'length'\n";
                return true;
            }
            break;

        case OPT_pos: {
            auto linecol = parseLineCol(InputArg->getValue());
            Line = linecol.first;
            Col = linecol.second;
            break;
        }

        case OPT_line:
            if (StringRef(InputArg->getValue()).getAsInteger(10, Line)) {
                llvm::errs() << "error: expected integer for 'line'\n";
                return true;
            }
            Col = 1;
            break;

        case OPT_replace:
            ReplaceText = InputArg->getValue();
            break;

        case OPT_module:
            ModuleName = InputArg->getValue();
            break;

        case OPT_group_name:
            ModuleGroupName = InputArg->getValue();
            break;

        case OPT_header:
            HeaderPath = InputArg->getValue();
            break;

        case OPT_text_input:
            TextInputFile = InputArg->getValue();
            break;

        case OPT_usr:
            USR = InputArg->getValue();
            break;

        case OPT_pass_as_sourcetext:
            PassAsSourceText = true;
            break;

        case OPT_cache_path:
            CachePath = InputArg->getValue();
            break;

        case OPT_req_opts:
            for (auto item : InputArg->getValues())
                RequestOptions.push_back(item);
            break;

        case OPT_check_interface_is_ascii:
            CheckInterfaceIsASCII = true;
            break;

        case OPT_print_response_as_json:
            PrintResponseAsJSON = true;
            break;

        case OPT_INPUT:
            SourceFile = InputArg->getValue();
            SourceText = llvm::None;
            Inputs.push_back(InputArg->getValue());
            break;

        case OPT_json_request_path:
            JsonRequestPath = InputArg->getValue();
            break;

        case OPT_simplified_demangling:
            SimplifiedDemangling = true;
            break;

        case OPT_synthesized_extension:
            SynthesizedExtensions = true;
            break;

        case OPT_UNKNOWN:
            llvm::errs() << "error: unknown argument: "
                         << InputArg->getAsString(ParsedArgs) << '\n';
            return true;
        }
    }

    return false;
}
Exemplo n.º 13
0
bool TestOptions::parseArgs(llvm::ArrayRef<const char *> Args) {
  if (Args.empty())
    return false;

  // Parse command line options using Options.td
  TestOptTable Table;
  unsigned MissingIndex;
  unsigned MissingCount;
  llvm::opt::InputArgList ParsedArgs =
      Table.ParseArgs(Args, MissingIndex, MissingCount);
  if (MissingCount) {
    llvm::errs() << "error: missing argument value for '"
        << ParsedArgs.getArgString(MissingIndex) << "', expected "
        << MissingCount << " argument(s)\n";
    return true;
  }

  for (auto InputArg : ParsedArgs) {
    switch (InputArg->getOption().getID()) {
    case OPT_req:
      Request = llvm::StringSwitch<SourceKitRequest>(InputArg->getValue())
        .Case("version", SourceKitRequest::ProtocolVersion)
        .Case("demangle", SourceKitRequest::DemangleNames)
        .Case("mangle", SourceKitRequest::MangleSimpleClasses)
        .Case("index", SourceKitRequest::Index)
        .Case("complete", SourceKitRequest::CodeComplete)
        .Case("complete.open", SourceKitRequest::CodeCompleteOpen)
        .Case("complete.close", SourceKitRequest::CodeCompleteClose)
        .Case("complete.update", SourceKitRequest::CodeCompleteUpdate)
        .Case("complete.cache.ondisk", SourceKitRequest::CodeCompleteCacheOnDisk)
        .Case("complete.setpopularapi", SourceKitRequest::CodeCompleteSetPopularAPI)
        .Case("cursor", SourceKitRequest::CursorInfo)
        .Case("related-idents", SourceKitRequest::RelatedIdents)
        .Case("syntax-map", SourceKitRequest::SyntaxMap)
        .Case("syntax-tree", SourceKitRequest::SyntaxTree)
        .Case("structure", SourceKitRequest::Structure)
        .Case("format", SourceKitRequest::Format)
        .Case("expand-placeholder", SourceKitRequest::ExpandPlaceholder)
        .Case("doc-info", SourceKitRequest::DocInfo)
        .Case("sema", SourceKitRequest::SemanticInfo)
        .Case("interface-gen", SourceKitRequest::InterfaceGen)
        .Case("interface-gen-open", SourceKitRequest::InterfaceGenOpen)
        .Case("find-usr", SourceKitRequest::FindUSR)
        .Case("find-interface", SourceKitRequest::FindInterfaceDoc)
        .Case("open", SourceKitRequest::Open)
        .Case("close", SourceKitRequest::Close)
        .Case("edit", SourceKitRequest::Edit)
        .Case("print-annotations", SourceKitRequest::PrintAnnotations)
        .Case("print-diags", SourceKitRequest::PrintDiags)
        .Case("extract-comment", SourceKitRequest::ExtractComment)
        .Case("module-groups", SourceKitRequest::ModuleGroups)
        .Case("range", SourceKitRequest::RangeInfo)
        .Case("syntactic-rename", SourceKitRequest::SyntacticRename)
        .Case("find-rename-ranges", SourceKitRequest::FindRenameRanges)
        .Case("find-local-rename-ranges", SourceKitRequest::FindLocalRenameRanges)
        .Case("translate", SourceKitRequest::NameTranslation)
        .Case("local-rename", SourceKitRequest::LocalRename)
        .Case("extract-expr", SourceKitRequest::ExtractExpr)
        .Case("extract-repeated", SourceKitRequest::ExtractRepeatedExpr)
        .Case("extract-func", SourceKitRequest::ExtractFunction)
        .Case("fill-stub", SourceKitRequest::FillProtocolStub)
        .Case("expand-default", SourceKitRequest::ExpandDefault)
        .Case("localize-string", SourceKitRequest::LocalizeString)
        .Case("markup-xml", SourceKitRequest::MarkupToXML)
        .Case("stats", SourceKitRequest::Statistics)
        .Case("track-compiles", SourceKitRequest::EnableCompileNotifications)
        .Default(SourceKitRequest::None);

      if (Request == SourceKitRequest::None) {
        llvm::errs() << "error: invalid request '" << InputArg->getValue()
            << "'\nexpected one of "
            << "version/demangle/mangle/index/complete/complete.open/complete.cursor/"
               "complete.update/complete.cache.ondisk/complete.cache.setpopularapi/"
               "cursor/related-idents/syntax-map/structure/format/expand-placeholder/"
               "doc-info/sema/interface-gen/interface-gen-openfind-usr/find-interface/"
               "open/close/edit/print-annotations/print-diags/extract-comment/module-groups/"
               "range/syntactic-rename/find-rename-ranges/translate/markup-xml/stats/"
               "track-compiles\n";
        return true;
      }
      break;

    case OPT_help: {
      printHelp(false);
      return true;
    }

    case OPT_offset:
      if (StringRef(InputArg->getValue()).getAsInteger(10, Offset)) {
        llvm::errs() << "error: expected integer for 'offset'\n";
        return true;
      }
      break;

    case OPT_length:
      if (StringRef(InputArg->getValue()).getAsInteger(10, Length)) {
        llvm::errs() << "error: expected integer for 'length'\n";
        return true;
      }
      break;

    case OPT_pos: {
      auto linecol = parseLineCol(InputArg->getValue());
      Line = linecol.first;
      Col = linecol.second;
      break;
    }

    case OPT_end_pos: {
      auto linecol = parseLineCol(InputArg->getValue());
      EndLine = linecol.first;
      EndCol = linecol.second;
      break;
    }

    case OPT_using_swift_args: {
      UsingSwiftArgs = true;
      break;
    }

    case OPT_swift_version:
      SwiftVersion = InputArg->getValue();
      break;

    case OPT_pass_version_as_string:
      PassVersionAsString = true;
      break;

    case OPT_line:
      if (StringRef(InputArg->getValue()).getAsInteger(10, Line)) {
        llvm::errs() << "error: expected integer for 'line'\n";
        return true;
      }
      Col = 1;
      break;

    case OPT_replace:
      ReplaceText = InputArg->getValue();
      break;

    case OPT_module:
      ModuleName = InputArg->getValue();
      break;

    case OPT_group_name:
      ModuleGroupName = InputArg->getValue();
      break;

    case OPT_interested_usr:
      InterestedUSR = InputArg->getValue();
      break;

    case OPT_header:
      HeaderPath = InputArg->getValue();
      break;

    case OPT_text_input:
      TextInputFile = InputArg->getValue();
      break;

    case OPT_usr:
      USR = InputArg->getValue();
      break;

    case OPT_pass_as_sourcetext:
      PassAsSourceText = true;
      break;

    case OPT_cache_path:
      CachePath = InputArg->getValue();
      break;

    case OPT_req_opts:
      for (auto item : InputArg->getValues())
        RequestOptions.push_back(item);
      break;

    case OPT_check_interface_is_ascii:
      CheckInterfaceIsASCII = true;
      break;

    case OPT_dont_print_request:
      PrintRequest = false;
      break;

    case OPT_print_response_as_json:
      PrintResponseAsJSON = true;
      break;

    case OPT_print_raw_response:
      PrintRawResponse = true;
      break;

    case OPT_dont_print_response:
      PrintResponse = false;
      break;

    case OPT_INPUT:
      SourceFile = InputArg->getValue();
      SourceText = llvm::None;
      Inputs.push_back(InputArg->getValue());
      break;

    case OPT_rename_spec:
      RenameSpecPath = InputArg->getValue();
      break;

    case OPT_json_request_path:
      JsonRequestPath = InputArg->getValue();
      break;

    case OPT_simplified_demangling:
      SimplifiedDemangling = true;
      break;

    case OPT_synthesized_extension:
      SynthesizedExtensions = true;
      break;

    case OPT_async:
      isAsyncRequest = true;
      break;

    case OPT_cursor_action:
      CollectActionables = true;
      break;

    case OPT_swift_name:
      SwiftName = InputArg->getValue();
      break;

    case OPT_objc_name:
      ObjCName = InputArg->getValue();
      break;

    case OPT_objc_selector:
      ObjCSelector = InputArg->getValue();
      break;

    case OPT_name:
      Name = InputArg->getValue();
      break;

    case OPT_cancel_on_subsequent_request:
      unsigned Cancel;
      if (StringRef(InputArg->getValue()).getAsInteger(10, Cancel)) {
        llvm::errs() << "error: expected integer for 'cancel-on-subsequent-request'\n";
        return true;
      }
      CancelOnSubsequentRequest = Cancel;
      break;

    case OPT_time_request:
      timeRequest = true;
      break;

    case OPT_repeat_request:
      if (StringRef(InputArg->getValue()).getAsInteger(10, repeatRequest)) {
        llvm::errs() << "error: expected integer for 'cancel-on-subsequent-request'\n";
        return true;
      } else if (repeatRequest < 1) {
        llvm::errs() << "error: repeat-request must be >= 1\n";
        return true;
      }
      break;

    case OPT_UNKNOWN:
      llvm::errs() << "error: unknown argument: "
                   << InputArg->getAsString(ParsedArgs) << '\n'
                   << "Use -h or -help for assistance" << '\n';
      return true;
    }
  }

  if (Request == SourceKitRequest::InterfaceGenOpen && isAsyncRequest) {
    llvm::errs()
        << "error: cannot use -async with interface-gen-open request\n";
    return true;
  }

  return false;
}