Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 41dcc4ea authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Only keep methods with correct signature for more types"

parents 9c512f1c 98100c38
Loading
Loading
Loading
Loading
+39 −27
Original line number Original line Diff line number Diff line
@@ -50,11 +50,11 @@ class BaseVisitor : public xml::Visitor {
        // This is a custom view, let's figure out the class name from this.
        // This is a custom view, let's figure out the class name from this.
        std::string package = maybe_package.value().package + "." + node->name;
        std::string package = maybe_package.value().package + "." + node->name;
        if (util::IsJavaClassName(package)) {
        if (util::IsJavaClassName(package)) {
          AddClass(node->line_number, package);
          AddClass(node->line_number, package, "...");
        }
        }
      }
      }
    } else if (util::IsJavaClassName(node->name)) {
    } else if (util::IsJavaClassName(node->name)) {
      AddClass(node->line_number, node->name);
      AddClass(node->line_number, node->name, "...");
    }
    }


    for (const auto& child : node->children) {
    for (const auto& child : node->children) {
@@ -75,8 +75,10 @@ class BaseVisitor : public xml::Visitor {
  ResourceFile file_;
  ResourceFile file_;
  KeepSet* keep_set_;
  KeepSet* keep_set_;


  virtual void AddClass(size_t line_number, const std::string& class_name) {
  virtual void AddClass(size_t line_number, const std::string& class_name,
    keep_set_->AddConditionalClass({file_.name, file_.source.WithLine(line_number)}, class_name);
                        const std::string& ctor_signature) {
    keep_set_->AddConditionalClass({file_.name, file_.source.WithLine(line_number)},
        {class_name, ctor_signature});
  }
  }


  void AddMethod(size_t line_number, const std::string& method_name,
  void AddMethod(size_t line_number, const std::string& method_name,
@@ -106,27 +108,33 @@ class LayoutVisitor : public BaseVisitor {
  }
  }


  void Visit(xml::Element* node) override {
  void Visit(xml::Element* node) override {
    bool check_class = false;
    bool is_view = false;
    bool check_name = false;
    bool is_fragment = false;
    if (node->namespace_uri.empty()) {
    if (node->namespace_uri.empty()) {
      if (node->name == "view") {
      if (node->name == "view") {
        check_class = true;
        is_view = true;
      } else if (node->name == "fragment") {
      } else if (node->name == "fragment") {
        check_class = check_name = true;
        is_fragment = true;
      }
      }
    } else if (node->namespace_uri == xml::kSchemaAndroid) {
    } else if (node->namespace_uri == xml::kSchemaAndroid) {
      check_name = node->name == "fragment";
      is_fragment = node->name == "fragment";
    }
    }


    for (const auto& attr : node->attributes) {
    for (const auto& attr : node->attributes) {
      if (check_class && attr.namespace_uri.empty() && attr.name == "class" &&
      if (attr.namespace_uri.empty() && attr.name == "class") {
          util::IsJavaClassName(attr.value)) {
        if (util::IsJavaClassName(attr.value)) {
        AddClass(node->line_number, attr.value);
          if (is_view) {
      } else if (check_name && attr.namespace_uri == xml::kSchemaAndroid &&
            AddClass(node->line_number, attr.value,
                 attr.name == "name" && util::IsJavaClassName(attr.value)) {
                "android.content.Context, android.util.AttributeSet");
        AddClass(node->line_number, attr.value);
          } else if (is_fragment) {
      } else if (attr.namespace_uri == xml::kSchemaAndroid &&
            AddClass(node->line_number, attr.value, "");
                 attr.name == "onClick") {
          }
        }
      } else if (attr.namespace_uri == xml::kSchemaAndroid && attr.name == "name") {
        if (is_fragment && util::IsJavaClassName(attr.value)) {
          AddClass(node->line_number, attr.value, "");
        }
      } else if (attr.namespace_uri == xml::kSchemaAndroid && attr.name == "onClick") {
        AddMethod(node->line_number, attr.value, "android.view.View");
        AddMethod(node->line_number, attr.value, "android.view.View");
      }
      }
    }
    }
@@ -149,7 +157,7 @@ class MenuVisitor : public BaseVisitor {
        if (attr.namespace_uri == xml::kSchemaAndroid) {
        if (attr.namespace_uri == xml::kSchemaAndroid) {
          if ((attr.name == "actionViewClass" || attr.name == "actionProviderClass") &&
          if ((attr.name == "actionViewClass" || attr.name == "actionProviderClass") &&
              util::IsJavaClassName(attr.value)) {
              util::IsJavaClassName(attr.value)) {
            AddClass(node->line_number, attr.value);
            AddClass(node->line_number, attr.value, "android.content.Context");
          } else if (attr.name == "onClick") {
          } else if (attr.name == "onClick") {
            AddMethod(node->line_number, attr.value, "android.view.MenuItem");
            AddMethod(node->line_number, attr.value, "android.view.MenuItem");
          }
          }
@@ -180,7 +188,7 @@ class XmlResourceVisitor : public BaseVisitor {
      xml::Attribute* attr =
      xml::Attribute* attr =
          node->FindAttribute(xml::kSchemaAndroid, "fragment");
          node->FindAttribute(xml::kSchemaAndroid, "fragment");
      if (attr && util::IsJavaClassName(attr->value)) {
      if (attr && util::IsJavaClassName(attr->value)) {
        AddClass(node->line_number, attr->value);
        AddClass(node->line_number, attr->value, "");
      }
      }
    }
    }


@@ -202,7 +210,7 @@ class NavigationVisitor : public BaseVisitor {
    if (attr != nullptr && !attr->value.empty()) {
    if (attr != nullptr && !attr->value.empty()) {
      std::string name = (attr->value[0] == '.') ? package_ + attr->value : attr->value;
      std::string name = (attr->value[0] == '.') ? package_ + attr->value : attr->value;
      if (util::IsJavaClassName(name)) {
      if (util::IsJavaClassName(name)) {
        AddClass(node->line_number, name);
        AddClass(node->line_number, name, "...");
      }
      }
    }
    }


@@ -225,7 +233,8 @@ class TransitionVisitor : public BaseVisitor {
    if (check_class) {
    if (check_class) {
      xml::Attribute* attr = node->FindAttribute({}, "class");
      xml::Attribute* attr = node->FindAttribute({}, "class");
      if (attr && util::IsJavaClassName(attr->value)) {
      if (attr && util::IsJavaClassName(attr->value)) {
        AddClass(node->line_number, attr->value);
        AddClass(node->line_number, attr->value,
            "android.content.Context, android.util.AttributeSet");
      }
      }
    }
    }


@@ -256,14 +265,14 @@ class ManifestVisitor : public BaseVisitor {
        if (attr) {
        if (attr) {
          Maybe<std::string> result = util::GetFullyQualifiedClassName(package_, attr->value);
          Maybe<std::string> result = util::GetFullyQualifiedClassName(package_, attr->value);
          if (result) {
          if (result) {
            AddClass(node->line_number, result.value());
            AddClass(node->line_number, result.value(), "");
          }
          }
        }
        }
        attr = node->FindAttribute(xml::kSchemaAndroid, "appComponentFactory");
        attr = node->FindAttribute(xml::kSchemaAndroid, "appComponentFactory");
        if (attr) {
        if (attr) {
          Maybe<std::string> result = util::GetFullyQualifiedClassName(package_, attr->value);
          Maybe<std::string> result = util::GetFullyQualifiedClassName(package_, attr->value);
          if (result) {
          if (result) {
            AddClass(node->line_number, result.value());
            AddClass(node->line_number, result.value(), "");
          }
          }
        }
        }
        if (main_dex_only_) {
        if (main_dex_only_) {
@@ -294,7 +303,7 @@ class ManifestVisitor : public BaseVisitor {
        if (get_name) {
        if (get_name) {
          Maybe<std::string> result = util::GetFullyQualifiedClassName(package_, attr->value);
          Maybe<std::string> result = util::GetFullyQualifiedClassName(package_, attr->value);
          if (result) {
          if (result) {
            AddClass(node->line_number, result.value());
            AddClass(node->line_number, result.value(), "");
          }
          }
        }
        }
      }
      }
@@ -302,7 +311,8 @@ class ManifestVisitor : public BaseVisitor {
    BaseVisitor::Visit(node);
    BaseVisitor::Visit(node);
  }
  }


  virtual void AddClass(size_t line_number, const std::string& class_name) override {
  virtual void AddClass(size_t line_number, const std::string& class_name,
                        const std::string& ctor_signature) override {
    keep_set_->AddManifestClass({file_.name, file_.source.WithLine(line_number)}, class_name);
    keep_set_->AddManifestClass({file_.name, file_.source.WithLine(line_number)}, class_name);
  }
  }


@@ -390,13 +400,15 @@ void WriteKeepSet(const KeepSet& keep_set, OutputStream* out) {
        printer.Print("-if class **.R$layout { int ")
        printer.Print("-if class **.R$layout { int ")
            .Print(JavaClassGenerator::TransformToFieldName(location.name.entry))
            .Print(JavaClassGenerator::TransformToFieldName(location.name.entry))
            .Println("; }");
            .Println("; }");
        printer.Print("-keep class ").Print(entry.first).Println(" { <init>(...); }");
        printer.Print("-keep class ").Print(entry.first.name).Print(" { <init>(")
            .Print(entry.first.signature).Println("); }");
      }
      }
    } else {
    } else {
      for (const UsageLocation& location : entry.second) {
      for (const UsageLocation& location : entry.second) {
        printer.Print("# Referenced at ").Println(location.source.to_string());
        printer.Print("# Referenced at ").Println(location.source.to_string());
      }
      }
      printer.Print("-keep class ").Print(entry.first).Println(" { <init>(...); }");
      printer.Print("-keep class ").Print(entry.first.name).Print(" { <init>(")
          .Print(entry.first.signature).Println("); }");
    }
    }
    printer.Println();
    printer.Println();
  }
  }
+4 −3
Original line number Original line Diff line number Diff line
@@ -56,8 +56,9 @@ class KeepSet {
    manifest_class_set_[class_name].insert(file);
    manifest_class_set_[class_name].insert(file);
  }
  }


  inline void AddConditionalClass(const UsageLocation& file, const std::string& class_name) {
  inline void AddConditionalClass(const UsageLocation& file,
    conditional_class_set_[class_name].insert(file);
                                  const NameAndSignature& class_and_signature) {
    conditional_class_set_[class_and_signature].insert(file);
  }
  }


  inline void AddMethod(const UsageLocation& file, const NameAndSignature& name_and_signature) {
  inline void AddMethod(const UsageLocation& file, const NameAndSignature& name_and_signature) {
@@ -77,7 +78,7 @@ class KeepSet {
  bool conditional_keep_rules_ = false;
  bool conditional_keep_rules_ = false;
  std::map<std::string, std::set<UsageLocation>> manifest_class_set_;
  std::map<std::string, std::set<UsageLocation>> manifest_class_set_;
  std::map<NameAndSignature, std::set<UsageLocation>> method_set_;
  std::map<NameAndSignature, std::set<UsageLocation>> method_set_;
  std::map<std::string, std::set<UsageLocation>> conditional_class_set_;
  std::map<NameAndSignature, std::set<UsageLocation>> conditional_class_set_;
  std::map<ResourceName, std::set<UsageLocation>> reference_set_;
  std::map<ResourceName, std::set<UsageLocation>> reference_set_;
};
};


+10 −8
Original line number Original line Diff line number Diff line
@@ -77,7 +77,7 @@ TEST(ProguardRulesTest, FragmentNameRuleIsEmitted) {


  std::string actual = GetKeepSetString(set);
  std::string actual = GetKeepSetString(set);


  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }"));
}
}


TEST(ProguardRulesTest, FragmentClassRuleIsEmitted) {
TEST(ProguardRulesTest, FragmentClassRuleIsEmitted) {
@@ -91,7 +91,7 @@ TEST(ProguardRulesTest, FragmentClassRuleIsEmitted) {


  std::string actual = GetKeepSetString(set);
  std::string actual = GetKeepSetString(set);


  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }"));
}
}


TEST(ProguardRulesTest, FragmentNameAndClassRulesAreEmitted) {
TEST(ProguardRulesTest, FragmentNameAndClassRulesAreEmitted) {
@@ -107,8 +107,8 @@ TEST(ProguardRulesTest, FragmentNameAndClassRulesAreEmitted) {


  std::string actual = GetKeepSetString(set);
  std::string actual = GetKeepSetString(set);


  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }"));
  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(...); }"));
  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(); }"));
}
}


TEST(ProguardRulesTest, NavigationFragmentNameAndClassRulesAreEmitted) {
TEST(ProguardRulesTest, NavigationFragmentNameAndClassRulesAreEmitted) {
@@ -267,8 +267,8 @@ TEST(ProguardRulesTest, MenuRulesAreEmitted) {


  EXPECT_THAT(actual, HasSubstr(
  EXPECT_THAT(actual, HasSubstr(
      "-keepclassmembers class * { *** on_click(android.view.MenuItem); }"));
      "-keepclassmembers class * { *** on_click(android.view.MenuItem); }"));
  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(android.content.Context); }"));
  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(...); }"));
  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(android.content.Context); }"));
  EXPECT_THAT(actual, Not(HasSubstr("com.foo.Bat")));
  EXPECT_THAT(actual, Not(HasSubstr("com.foo.Bat")));
}
}


@@ -285,7 +285,8 @@ TEST(ProguardRulesTest, TransitionPathMotionRulesAreEmitted) {


  std::string actual = GetKeepSetString(set);
  std::string actual = GetKeepSetString(set);


  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
  EXPECT_THAT(actual, HasSubstr(
      "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }"));
}
}


TEST(ProguardRulesTest, TransitionRulesAreEmitted) {
TEST(ProguardRulesTest, TransitionRulesAreEmitted) {
@@ -301,7 +302,8 @@ TEST(ProguardRulesTest, TransitionRulesAreEmitted) {


  std::string actual = GetKeepSetString(set);
  std::string actual = GetKeepSetString(set);


  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
  EXPECT_THAT(actual, HasSubstr(
      "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }"));
}
}


}  // namespace aapt
}  // namespace aapt