void parse()

in libredex/ProguardParser.cpp [883:1162]


void parse(const std::vector<Token>& vec,
           ProguardConfiguration* pg_config,
           size_t& parse_errors,
           size_t& unimplemented,
           const std::string& filename) {
  bool ok;
  TokenIndex idx{vec, vec.begin()};
  while (idx.it != idx.vec.end()) {
    // Break out if we are at the end of the TokenType stream.
    if (idx.type() == TokenType::eof_token) {
      break;
    }
    if (idx.type() == TokenType::comment) {
      idx.next();
      continue;
    }
    uint32_t line = idx.line();
    if (!idx.it->is_command()) {
      std::cerr << "Expecting command but found " << idx.show() << " at line "
                << idx.line() << std::endl
                << idx.show_context(2) << std::endl;
      idx.next();
      skip_to_next_command(idx);
      continue;
    }

    // Input/Output Options
    if (parse_filepath_command(idx,
                               TokenType::include,
                               pg_config->basedirectory,
                               &pg_config->includes)) {
      continue;
    }
    if (parse_single_filepath_command(
            idx, TokenType::basedirectory, &pg_config->basedirectory)) {
      continue;
    }
    if (parse_jars(idx,
                   TokenType::injars,
                   pg_config->basedirectory,
                   &pg_config->injars)) {
      continue;
    }
    if (parse_jars(idx,
                   TokenType::outjars,
                   pg_config->basedirectory,
                   &pg_config->outjars)) {
      continue;
    }
    if (parse_jars(idx,
                   TokenType::libraryjars,
                   pg_config->basedirectory,
                   &pg_config->libraryjars)) {
      continue;
    }
    // -skipnonpubliclibraryclasses not supported
    if (idx.type() == TokenType::dontskipnonpubliclibraryclasses) {
      // Silenty ignore the dontskipnonpubliclibraryclasses option.
      idx.next();
      continue;
    }
    // -dontskipnonpubliclibraryclassmembers not supported
    if (parse_filepath_command(idx,
                               TokenType::keepdirectories,
                               pg_config->basedirectory,
                               &pg_config->keepdirectories)) {
      continue;
    }
    if (parse_target(idx, &pg_config->target_version)) {
      continue;
    }
    // -forceprocessing not supported

    // Keep Options
    if (parse_keep(idx,
                   TokenType::keep,
                   &pg_config->keep_rules,
                   true, // mark_classes
                   false, // mark_conditionally
                   false, // allowshrinking
                   filename,
                   line,
                   &ok)) {
      if (!ok) {
        ++parse_errors;
      }
      continue;
    }
    if (parse_keep(idx,
                   TokenType::keepclassmembers,
                   &pg_config->keep_rules,
                   false, // mark_classes
                   false, // mark_conditionally
                   false, // allowshrinking
                   filename,
                   line,
                   &ok)) {
      if (!ok) {
        ++parse_errors;
      }
      continue;
    }
    if (parse_keep(idx,
                   TokenType::keepclasseswithmembers,
                   &pg_config->keep_rules,
                   false, // mark_classes
                   true, // mark_conditionally
                   false, // allowshrinking
                   filename,
                   line,
                   &ok)) {
      if (!ok) {
        ++parse_errors;
      }
      continue;
    }
    if (parse_keep(idx,
                   TokenType::keepnames,
                   &pg_config->keep_rules,
                   true, // mark_classes
                   false, // mark_conditionally
                   true, // allowshrinking
                   filename,
                   line,
                   &ok)) {
      if (!ok) {
        ++parse_errors;
      }
      continue;
    }
    if (parse_keep(idx,
                   TokenType::keepclassmembernames,
                   &pg_config->keep_rules,
                   false, // mark_classes
                   false, // mark_conditionally
                   true, // allowshrinking
                   filename,
                   line,
                   &ok)) {
      if (!ok) {
        ++parse_errors;
      }
      continue;
    }
    if (parse_keep(idx,
                   TokenType::keepclasseswithmembernames,
                   &pg_config->keep_rules,
                   false, // mark_classes
                   true, // mark_conditionally
                   true, // allowshrinking
                   filename,
                   line,
                   &ok)) {
      if (!ok) {
        ++parse_errors;
      }
      continue;
    }
    if (parse_optional_filepath_command(
            idx, TokenType::printseeds, &pg_config->printseeds)) {
      continue;
    }

    // Shrinking Options
    if (parse_bool_command(
            idx, TokenType::dontshrink, false, &pg_config->shrink)) {
      continue;
    }
    if (parse_optional_filepath_command(
            idx, TokenType::printusage, &pg_config->printusage)) {
      continue;
    }

    // Optimization Options
    if (parse_boolean_command(
            idx, TokenType::dontoptimize, &pg_config->optimize, false)) {
      continue;
    }
    if (parse_filter_list_command(
            idx, TokenType::optimizations, &pg_config->optimization_filters)) {
      continue;
    }
    if (parse_optimizationpasses_command(idx)) {
      continue;
    }
    if (parse_keep(idx,
                   TokenType::assumenosideeffects,
                   &pg_config->assumenosideeffects_rules,
                   false, // mark_classes
                   false, // mark_conditionally
                   false, // allowshrinking
                   filename,
                   line,
                   &ok)) {
      continue;
    }
    if (parse_keep(idx,
                   TokenType::whyareyoukeeping,
                   &pg_config->whyareyoukeeping_rules,
                   false, // mark_classes
                   false, // mark_conditionally
                   false, // allowshrinking
                   filename,
                   line,
                   &ok)) {
      continue;
    }

    // Obfuscation Options
    if (idx.type() == TokenType::dontobfuscate) {
      pg_config->dontobfuscate = true;
      idx.next();
      continue;
    }
    // Redex ignores -dontskipnonpubliclibraryclasses
    if (idx.type() == TokenType::dontskipnonpubliclibraryclasses) {
      idx.next();
      continue;
    }
    if (parse_optional_filepath_command(
            idx, TokenType::printmapping, &pg_config->printmapping)) {
      continue;
    }
    if (parse_optional_filepath_command(idx,
                                        TokenType::printconfiguration,
                                        &pg_config->printconfiguration)) {
      continue;
    }

    if (parse_allowaccessmodification(idx,
                                      &pg_config->allowaccessmodification)) {
      continue;
    }
    if (parse_dontusemixedcaseclassnames(
            idx, &pg_config->dontusemixedcaseclassnames)) {
      continue;
    }
    if (parse_filter_list_command(
            idx, TokenType::keeppackagenames, &pg_config->keeppackagenames)) {
      continue;
    }
    if (parse_dontpreverify(idx, &pg_config->dontpreverify)) {
      continue;
    }
    if (parse_verbose(idx, &pg_config->verbose)) {
      continue;
    }
    if (parse_repackageclasses(idx)) {
      continue;
    }

    if (parse_filter_list_command(
            idx, TokenType::dontwarn, &pg_config->dontwarn)) {
      continue;
    }
    if (parse_filter_list_command(
            idx, TokenType::keepattributes, &pg_config->keepattributes)) {
      continue;
    }

    // Skip unknown token.
    if (idx.it->is_command()) {
      const auto& name = idx.data();
      // It is benign to drop -dontnote
      if (name != "dontnote") {
        std::cerr << "Unimplemented command (skipping): " << idx.show()
                  << " at line " << idx.line() << std::endl
                  << idx.show_context(2) << std::endl;
        ++unimplemented;
      }
    } else {
      std::cerr << "Unexpected TokenType " << idx.show() << " at line "
                << idx.line() << std::endl
                << idx.show_context(2) << std::endl;
      ++parse_errors;
    }
    idx.next();
    skip_to_next_command(idx);
  }
}