19139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#!/usr/bin/python3
29139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#
39139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# Copyright (C) 2015 The Android Open Source Project
49139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#
59139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# Licensed under the Apache License, Version 2.0 (the "License");
69139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# you may not use this file except in compliance with the License.
79139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# You may obtain a copy of the License at
89139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#
99139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#     http://www.apache.org/licenses/LICENSE-2.0
109139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#
119139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# Unless required by applicable law or agreed to in writing, software
129139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# distributed under the License is distributed on an "AS IS" BASIS,
139139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# See the License for the specific language governing permissions and
159139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# limitations under the License.
169139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
179139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light"""
189139e008abe30b7beaf4afd6533228a1dd9b202cAlex LightGenerate Smali test files for test 967.
199139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light"""
209139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
219139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightimport os
229139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightimport sys
239139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightfrom pathlib import Path
249139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
259139e008abe30b7beaf4afd6533228a1dd9b202cAlex LightBUILD_TOP = os.getenv("ANDROID_BUILD_TOP")
269139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightif BUILD_TOP is None:
279139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  print("ANDROID_BUILD_TOP not set. Please run build/envsetup.sh", file=sys.stderr)
289139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  sys.exit(1)
299139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
309139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# Allow us to import utils and mixins.
319139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightsys.path.append(str(Path(BUILD_TOP)/"art"/"test"/"utils"/"python"))
329139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
339139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightfrom testgen.utils import get_copyright, subtree_sizes, gensym, filter_blanks
349139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightimport testgen.mixins as mixins
359139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
369139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightfrom enum import Enum
379139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightfrom functools import total_ordering
389139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightimport itertools
399139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightimport string
409139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
419139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# The max depth the type tree can have.
429139e008abe30b7beaf4afd6533228a1dd9b202cAlex LightMAX_IFACE_DEPTH = 3
439139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
449139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightclass MainClass(mixins.DumpMixin, mixins.Named, mixins.SmaliFileMixin):
459139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
469139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  A Main.smali file containing the Main class and the main function. It will run
479139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  all the test functions we have.
489139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
499139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
509139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  MAIN_CLASS_TEMPLATE = """{copyright}
519139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
529139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.class public LMain;
539139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.super Ljava/lang/Object;
549139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
559139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# class Main {{
569139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
579139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.method public constructor <init>()V
589139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    .registers 1
599139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    invoke-direct {{p0}}, Ljava/lang/Object;-><init>()V
609139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return-void
619139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.end method
629139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
639139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light{test_funcs}
649139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
659139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light{main_func}
669139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
679139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# }}
689139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light"""
699139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
709139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  MAIN_FUNCTION_TEMPLATE = """
719139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#   public static void main(String[] args) {{
729139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.method public static main([Ljava/lang/String;)V
739139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    .locals 0
749139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
759139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    {test_group_invoke}
769139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
779139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return-void
789139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.end method
799139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#   }}
809139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light"""
819139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
829139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  TEST_GROUP_INVOKE_TEMPLATE = """
839139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#     {test_name}();
849139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    invoke-static {{}}, {test_name}()V
859139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light"""
869139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
879139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def __init__(self):
889139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
899139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Initialize this MainClass. We start out with no tests.
909139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
919139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    self.tests = set()
929139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
939139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def get_expected(self):
949139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
959139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Get the expected output of this test.
969139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
979139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    all_tests = sorted(self.tests)
989139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return filter_blanks("\n".join(a.get_expected() for a in all_tests))
999139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
1009139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def add_test(self, ty):
1019139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
1029139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Add a test for the concrete type 'ty'
1039139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
1049139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    self.tests.add(Func(ty))
1059139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
1069139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def get_name(self):
1079139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
1089139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Get the name of this class
1099139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
1109139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return "Main"
1119139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
1129139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def __str__(self):
1139139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
1149139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Print the MainClass smali code.
1159139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
1169139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    all_tests = sorted(self.tests)
1179139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    test_invoke = ""
1189139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    test_funcs = ""
1199139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    for t in all_tests:
1209139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      test_funcs += str(t)
1219139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    for t in all_tests:
1229139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      test_invoke += self.TEST_GROUP_INVOKE_TEMPLATE.format(test_name=t.get_name())
1239139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    main_func = self.MAIN_FUNCTION_TEMPLATE.format(test_group_invoke=test_invoke)
1249139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
1259139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return self.MAIN_CLASS_TEMPLATE.format(copyright = get_copyright("smali"),
1269139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light                                           test_funcs = test_funcs,
1279139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light                                           main_func = main_func)
1289139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
1299139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightclass Func(mixins.Named, mixins.NameComparableMixin):
1309139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
1319139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  A function that tests the functionality of a concrete type. Should only be
1329139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  constructed by MainClass.add_test.
1339139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
1349139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
1359139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  TEST_FUNCTION_TEMPLATE = """
1369139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#   public static void {fname}() {{
1379139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#     {farg} v = null;
1389139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#     try {{
1399139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#       v = new {farg}();
1409139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#     }} catch (Throwable e) {{
1419139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#       System.out.println("Unexpected error occurred which creating {farg} instance");
1429139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#       e.printStackTrace(System.out);
1439139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#       return;
1449139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#     }}
1459139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#     try {{
1469139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#       System.out.printf("{tree} calls %s\\n", v.getName());
1479139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#       return;
1489139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#     }} catch (AbstractMethodError e) {{
1499139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#       System.out.println("{tree} threw AbstractMethodError");
1509139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#     }} catch (NoSuchMethodError e) {{
1519139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#       System.out.println("{tree} threw NoSuchMethodError");
1529139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#     }} catch (IncompatibleClassChangeError e) {{
1539139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#       System.out.println("{tree} threw IncompatibleClassChangeError");
1549139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#     }} catch (Throwable e) {{
1559139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#       e.printStackTrace(System.out);
1569139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#       return;
1579139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#     }}
1589139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#   }}
1599139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.method public static {fname}()V
1609139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    .locals 7
1619139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    sget-object v4, Ljava/lang/System;->out:Ljava/io/PrintStream;
1629139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
1639139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    :new_{fname}_try_start
1649139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      new-instance v0, L{farg};
1659139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      invoke-direct {{v0}}, L{farg};-><init>()V
1669139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      goto :call_{fname}_try_start
1679139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    :new_{fname}_try_end
1689139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    .catch Ljava/lang/Throwable; {{:new_{fname}_try_start .. :new_{fname}_try_end}} :new_error_{fname}_start
1699139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    :new_error_{fname}_start
1709139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      move-exception v6
1719139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      const-string v5, "Unexpected error occurred which creating {farg} instance"
1729139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      invoke-virtual {{v4,v5}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
1739139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      invoke-virtual {{v6,v4}}, Ljava/lang/Throwable;->printStackTrace(Ljava/io/PrintStream;)V
1749139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      return-void
1759139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    :call_{fname}_try_start
1769139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      const/4 v1, 1
1779139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      new-array v2,v1, [Ljava/lang/Object;
1789139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      const/4 v1, 0
1799139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      invoke-virtual {{v0}}, L{farg};->getName()Ljava/lang/String;
1809139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      move-result-object v3
1819139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      aput-object v3,v2,v1
1829139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
1839139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      const-string v5, "{tree} calls %s\\n"
1849139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
1859139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      invoke-virtual {{v4,v5,v2}}, Ljava/io/PrintStream;->printf(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;
1869139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      return-void
1879139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    :call_{fname}_try_end
1889139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    .catch Ljava/lang/AbstractMethodError; {{:call_{fname}_try_start .. :call_{fname}_try_end}} :AME_{fname}_start
1899139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    .catch Ljava/lang/NoSuchMethodError; {{:call_{fname}_try_start .. :call_{fname}_try_end}} :NSME_{fname}_start
1909139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    .catch Ljava/lang/IncompatibleClassChangeError; {{:call_{fname}_try_start .. :call_{fname}_try_end}} :ICCE_{fname}_start
1919139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    .catch Ljava/lang/Throwable; {{:call_{fname}_try_start .. :call_{fname}_try_end}} :error_{fname}_start
1929139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    :AME_{fname}_start
1939139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      const-string v5, "{tree} threw AbstractMethodError"
1949139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      invoke-virtual {{v4,v5}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
1959139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      return-void
1969139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    :NSME_{fname}_start
1979139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      const-string v5, "{tree} threw NoSuchMethodError"
1989139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      invoke-virtual {{v4,v5}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
1999139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      return-void
2009139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    :ICCE_{fname}_start
2019139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      const-string v5, "{tree} threw IncompatibleClassChangeError"
2029139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      invoke-virtual {{v4,v5}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
2039139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      return-void
2049139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    :error_{fname}_start
2059139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      move-exception v6
2069139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      invoke-virtual {{v6,v4}}, Ljava/lang/Throwable;->printStackTrace(Ljava/io/PrintStream;)V
2079139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      return-void
2089139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.end method
2099139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light"""
2109139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
2119139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  NSME_RESULT_TEMPLATE = "{tree} threw NoSuchMethodError"
2129139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  ICCE_RESULT_TEMPLATE = "{tree} threw IncompatibleClassChangeError"
2139139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  AME_RESULT_TEMPLATE = "{tree} threw AbstractMethodError"
2149139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  NORMAL_RESULT_TEMPLATE = "{tree} calls {result}"
2159139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
2169139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def __init__(self, farg):
2179139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
2189139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Initialize a test function for the given argument
2199139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
2209139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    self.farg = farg
2219139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
2229139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def get_expected(self):
2239139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
2249139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Get the expected output calling this function.
2259139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
2269139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    exp = self.farg.get_called()
2279139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    if exp.is_empty():
2289139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      return self.NSME_RESULT_TEMPLATE.format(tree = self.farg.get_tree())
2299139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    elif exp.is_abstract():
2309139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      return self.AME_RESULT_TEMPLATE.format(tree = self.farg.get_tree())
2319139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    elif exp.is_conflict():
2329139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      return self.ICCE_RESULT_TEMPLATE.format(tree = self.farg.get_tree())
2339139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    else:
2349139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      assert exp.is_default()
2359139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      return self.NORMAL_RESULT_TEMPLATE.format(tree = self.farg.get_tree(),
2369139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light                                                result = exp.get_tree())
2379139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
2389139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def get_name(self):
2399139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
2409139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Get the name of this function
2419139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
2429139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return "TEST_FUNC_{}".format(self.farg.get_name())
2439139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
2449139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def __str__(self):
2459139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
2469139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Print the smali code of this function.
2479139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
2489139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return self.TEST_FUNCTION_TEMPLATE.format(tree = self.farg.get_tree(),
2499139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light                                              fname = self.get_name(),
2509139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light                                              farg = self.farg.get_name())
2519139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
2529139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightclass TestClass(mixins.DumpMixin, mixins.Named, mixins.NameComparableMixin, mixins.SmaliFileMixin):
2539139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
2549139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  A class that will be instantiated to test default method resolution order.
2559139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
2569139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
2579139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  TEST_CLASS_TEMPLATE = """{copyright}
2589139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
2599139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.class public L{class_name};
2609139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.super Ljava/lang/Object;
2619139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.implements L{iface_name};
2629139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
2639139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# public class {class_name} implements {iface_name} {{
2649139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
2659139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.method public constructor <init>()V
2669139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  .registers 1
2679139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  invoke-direct {{p0}}, Ljava/lang/Object;-><init>()V
2689139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  return-void
2699139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.end method
2709139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
2719139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light{funcs}
2729139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
2739139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# }}
2749139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light"""
2759139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
2769139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def __init__(self, iface):
2779139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
2789139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Initialize this test class which implements the given interface
2799139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
2809139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    self.iface = iface
2819139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    self.class_name = "CLASS_"+gensym()
2829139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
2839139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def get_name(self):
2849139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
2859139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Get the name of this class
2869139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
2879139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return self.class_name
2889139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
2899139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def get_tree(self):
2909139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
2919139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Print out a representation of the type tree of this class
2929139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
2939139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return "[{class_name} {iface_tree}]".format(class_name = self.class_name,
2949139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light                                                iface_tree = self.iface.get_tree())
2959139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
2969139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def __iter__(self):
2979139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
2989139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Step through all interfaces implemented transitively by this class
2999139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
3009139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    yield self.iface
3019139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    yield from self.iface
3029139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
3039139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def get_called(self):
3049139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
3059139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Returns the interface that will be called when the method on this class is invoked or
3069139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    CONFLICT_TYPE if there is no interface that will be called.
3079139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
3089139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return self.iface.get_called()
3099139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
3109139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def __str__(self):
3119139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
3129139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Print the smali code of this class.
3139139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
3149139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return self.TEST_CLASS_TEMPLATE.format(copyright = get_copyright('smali'),
3159139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light                                           iface_name = self.iface.get_name(),
3169139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light                                           tree = self.get_tree(),
3179139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light                                           class_name = self.class_name,
3189139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light                                           funcs = "")
3199139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
3209139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightclass InterfaceType(Enum):
3219139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
3229139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  An enumeration of all the different types of interfaces we can have.
3239139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
3249139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  default: It has a default method
3259139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  abstract: It has a method declared but not defined
3269139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  empty: It does not have the method
3279139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
3289139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  default = 0
3299139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  abstract = 1
3309139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  empty = 2
3319139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
3329139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def get_suffix(self):
3339139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    if self == InterfaceType.default:
3349139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      return "_DEFAULT"
3359139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    elif self == InterfaceType.abstract:
3369139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      return "_ABSTRACT"
3379139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    elif self == InterfaceType.empty:
3389139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      return "_EMPTY"
3399139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    else:
3409139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      raise TypeError("Interface type had illegal value.")
3419139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
3429139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightclass ConflictInterface:
3439139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
3449139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  A singleton representing a conflict of default methods.
3459139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
3469139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
3479139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def is_conflict(self):
3489139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
3499139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Returns true if this is a conflict interface and calling the method on this interface will
3509139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    result in an IncompatibleClassChangeError.
3519139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
3529139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return True
3539139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
3549139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def is_abstract(self):
3559139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
3569139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Returns true if this is an abstract interface and calling the method on this interface will
3579139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    result in an AbstractMethodError.
3589139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
3599139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return False
3609139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
3619139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def is_empty(self):
3629139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
3639139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Returns true if this is an abstract interface and calling the method on this interface will
3649139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    result in a NoSuchMethodError.
3659139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
3669139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return False
3679139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
3689139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def is_default(self):
3699139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
3709139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Returns true if this is a default interface and calling the method on this interface will
3719139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    result in a method actually being called.
3729139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
3739139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return False
3749139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
3759139e008abe30b7beaf4afd6533228a1dd9b202cAlex LightCONFLICT_TYPE = ConflictInterface()
3769139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
3779139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightclass TestInterface(mixins.DumpMixin, mixins.Named, mixins.NameComparableMixin, mixins.SmaliFileMixin):
3789139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
3799139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  An interface that will be used to test default method resolution order.
3809139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
3819139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
3829139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  TEST_INTERFACE_TEMPLATE = """{copyright}
3839139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.class public abstract interface L{class_name};
3849139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.super Ljava/lang/Object;
3859139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light{implements_spec}
3869139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
3879139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# public interface {class_name} {extends} {ifaces} {{
3889139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
3899139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light{funcs}
3909139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
3919139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# }}
3929139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light"""
3939139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
3949139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  DEFAULT_FUNC_TEMPLATE = """
3959139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#   public default String getName() {{
3969139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#     return "{tree}";
3979139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#   }}
3989139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.method public getName()Ljava/lang/String;
3999139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  .locals 1
4009139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  const-string v0, "{tree}"
4019139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  return-object v0
4029139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.end method
4039139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light"""
4049139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
4059139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  ABSTRACT_FUNC_TEMPLATE = """
4069139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light#   public String getName();
4079139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.method public abstract getName()Ljava/lang/String;
4089139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.end method
4099139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light"""
4109139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
4119139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  EMPTY_FUNC_TEMPLATE = """"""
4129139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
4139139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  IMPLEMENTS_TEMPLATE = """
4149139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light.implements L{iface_name};
4159139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light"""
4169139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
4179139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def __init__(self, ifaces, iface_type, full_name = None):
4189139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4199139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Initialize interface with the given super-interfaces
4209139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4219139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    self.ifaces = sorted(ifaces)
4229139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    self.iface_type = iface_type
4239139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    if full_name is None:
4249139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      end = self.iface_type.get_suffix()
4259139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      self.class_name = "INTERFACE_"+gensym()+end
4269139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    else:
4279139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      self.class_name = full_name
4289139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
4299139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def get_specific_version(self, v):
4309139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4319139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Returns a copy of this interface of the given type for use in partial compilation.
4329139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4339139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return TestInterface(self.ifaces, v, full_name = self.class_name)
4349139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
4359139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def get_super_types(self):
4369139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4379139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Returns a set of all the supertypes of this interface
4389139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4399139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return set(i2 for i2 in self)
4409139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
4419139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def is_conflict(self):
4429139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4439139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Returns true if this is a conflict interface and calling the method on this interface will
4449139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    result in an IncompatibleClassChangeError.
4459139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4469139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return False
4479139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
4489139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def is_abstract(self):
4499139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4509139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Returns true if this is an abstract interface and calling the method on this interface will
4519139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    result in an AbstractMethodError.
4529139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4539139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return self.iface_type == InterfaceType.abstract
4549139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
4559139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def is_empty(self):
4569139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4579139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Returns true if this is an abstract interface and calling the method on this interface will
4589139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    result in a NoSuchMethodError.
4599139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4609139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return self.iface_type == InterfaceType.empty
4619139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
4629139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def is_default(self):
4639139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4649139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Returns true if this is a default interface and calling the method on this interface will
4659139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    result in a method actually being called.
4669139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4679139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return self.iface_type == InterfaceType.default
4689139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
4699139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def get_called(self):
4709139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4719139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Returns the interface that will be called when the method on this class is invoked or
4729139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    CONFLICT_TYPE if there is no interface that will be called.
4739139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4749139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    if not self.is_empty() or len(self.ifaces) == 0:
4759139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      return self
4769139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    else:
4779139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      best = self
4789139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      for super_iface in self.ifaces:
4799139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light        super_best = super_iface.get_called()
4809139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light        if super_best.is_conflict():
4819139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light          return CONFLICT_TYPE
4829139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light        elif best.is_default():
4839139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light          if super_best.is_default():
4849139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light            return CONFLICT_TYPE
4859139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light        elif best.is_abstract():
4869139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light          if super_best.is_default():
4879139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light            best = super_best
4889139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light        else:
4899139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light          assert best.is_empty()
4909139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light          best = super_best
4919139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      return best
4929139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
4939139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def get_name(self):
4949139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4959139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Get the name of this class
4969139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
4979139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return self.class_name
4989139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
4999139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def get_tree(self):
5009139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
5019139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Print out a representation of the type tree of this class
5029139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
5039139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return "[{class_name} {iftree}]".format(class_name = self.get_name(),
5049139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light                                            iftree = print_tree(self.ifaces))
5059139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
5069139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def __iter__(self):
5079139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
5089139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Performs depth-first traversal of the interface tree this interface is the
5099139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    root of. Does not filter out repeats.
5109139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
5119139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    for i in self.ifaces:
5129139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      yield i
5139139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      yield from i
5149139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
5159139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  def __str__(self):
5169139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
5179139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    Print the smali code of this interface.
5189139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    """
5199139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    s_ifaces = " "
5209139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    j_ifaces = " "
5219139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    for i in self.ifaces:
5229139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      s_ifaces += self.IMPLEMENTS_TEMPLATE.format(iface_name = i.get_name())
5239139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      j_ifaces += " {},".format(i.get_name())
5249139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    j_ifaces = j_ifaces[0:-1]
5259139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    if self.is_default():
5269139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      funcs = self.DEFAULT_FUNC_TEMPLATE.format(tree = self.get_tree())
5279139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    elif self.is_abstract():
5289139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      funcs = self.ABSTRACT_FUNC_TEMPLATE.format()
5299139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    else:
5309139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      funcs = ""
5319139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return self.TEST_INTERFACE_TEMPLATE.format(copyright = get_copyright('smali'),
5329139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light                                               implements_spec = s_ifaces,
5339139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light                                               extends = "extends" if len(self.ifaces) else "",
5349139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light                                               ifaces = j_ifaces,
5359139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light                                               funcs = funcs,
5369139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light                                               tree = self.get_tree(),
5379139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light                                               class_name = self.class_name)
5389139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
5399139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightdef print_tree(ifaces):
5409139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
5419139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  Prints a list of iface trees
5429139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
5439139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  return " ".join(i.get_tree() for i in ifaces)
5449139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
5459139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# The deduplicated output of subtree_sizes for each size up to
5469139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light# MAX_LEAF_IFACE_PER_OBJECT.
5479139e008abe30b7beaf4afd6533228a1dd9b202cAlex LightSUBTREES = [set(tuple(sorted(l)) for l in subtree_sizes(i))
5489139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light            for i in range(MAX_IFACE_DEPTH + 1)]
5499139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
5509139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightdef create_test_classes():
5519139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
5529139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  Yield all the test classes with the different interface trees
5539139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
5549139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  for num in range(1, MAX_IFACE_DEPTH + 1):
5559139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    for iface in create_interface_trees(num):
5569139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      yield TestClass(iface)
5579139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
5589139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightdef create_interface_trees(num):
5599139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
5609139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  Yield all the interface trees up to 'num' depth.
5619139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
5629139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  if num == 0:
5639139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    for iftype in InterfaceType:
5649139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      yield TestInterface(tuple(), iftype)
5659139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    return
5669139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  for split in SUBTREES[num]:
5679139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    ifaces = []
5689139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    for sub in split:
5699139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      ifaces.append(list(create_interface_trees(sub)))
5709139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    yield TestInterface(tuple(), InterfaceType.default)
5719139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    for supers in itertools.product(*ifaces):
5729139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      for iftype in InterfaceType:
5739139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light        if iftype == InterfaceType.default:
5749139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light          # We can just stop at defaults. We have other tests that a default can override an
5759139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light          # abstract and this cuts down on the number of cases significantly, improving speed of
5769139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light          # this test.
5779139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light          continue
5789139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light        yield TestInterface(supers, iftype)
5799139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
5809139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightdef create_all_test_files():
5819139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
5829139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  Creates all the objects representing the files in this test. They just need to
5839139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  be dumped.
5849139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  """
5859139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  mc = MainClass()
5869139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  classes = {mc}
5879139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  for clazz in create_test_classes():
5889139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    classes.add(clazz)
5899139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    for i in clazz:
5909139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light      classes.add(i)
5919139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    mc.add_test(clazz)
5929139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  return mc, classes
5939139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
5949139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightdef main(argv):
5959139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  smali_dir = Path(argv[1])
5969139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  if not smali_dir.exists() or not smali_dir.is_dir():
5979139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    print("{} is not a valid smali dir".format(smali_dir), file=sys.stderr)
5989139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    sys.exit(1)
5999139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  expected_txt = Path(argv[2])
6009139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  mainclass, all_files = create_all_test_files()
6019139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  with expected_txt.open('w') as out:
6029139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    print(mainclass.get_expected(), file=out)
6039139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  for f in all_files:
6049139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    f.dump(smali_dir)
6059139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light
6069139e008abe30b7beaf4afd6533228a1dd9b202cAlex Lightif __name__ == '__main__':
6079139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  main(sys.argv)
608