1705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#!/usr/bin/python3
2705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#
3705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# Copyright (C) 2015 The Android Open Source Project
4705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#
5705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# Licensed under the Apache License, Version 2.0 (the "License");
6705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# you may not use this file except in compliance with the License.
7705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# You may obtain a copy of the License at
8705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#
9705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#     http://www.apache.org/licenses/LICENSE-2.0
10705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#
11705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# Unless required by applicable law or agreed to in writing, software
12705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# distributed under the License is distributed on an "AS IS" BASIS,
13705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# See the License for the specific language governing permissions and
15705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# limitations under the License.
16705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
17705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light"""
18705ad49f353d3f90d8b63625aca2c2035bacdbefAlex LightGenerate Smali test files for test 967.
19705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light"""
20705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
21705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightimport os
22705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightimport sys
23705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightfrom pathlib import Path
24705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
25705ad49f353d3f90d8b63625aca2c2035bacdbefAlex LightBUILD_TOP = os.getenv("ANDROID_BUILD_TOP")
26705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightif BUILD_TOP is None:
27705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  print("ANDROID_BUILD_TOP not set. Please run build/envsetup.sh", file=sys.stderr)
28705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  sys.exit(1)
29705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
30705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# Allow us to import utils and mixins.
31705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightsys.path.append(str(Path(BUILD_TOP)/"art"/"test"/"utils"/"python"))
32705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
33705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightfrom testgen.utils import get_copyright, subtree_sizes, gensym, filter_blanks
34705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightimport testgen.mixins as mixins
35705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
36705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightfrom enum import Enum
37705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightfrom functools import total_ordering
38705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightimport itertools
39705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightimport string
40705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
41705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# The max depth the type tree can have.
426157a5d56d310d781ea61d2fd686dfe2ea2d301cAlex LightMAX_IFACE_DEPTH = 2
43705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
44705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightclass MainClass(mixins.DumpMixin, mixins.Named, mixins.SmaliFileMixin):
45705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
46705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  A Main.smali file containing the Main class and the main function. It will run
47705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  all the test functions we have.
48705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
49705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
50705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  MAIN_CLASS_TEMPLATE = """{copyright}
51705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
52705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.class public LMain;
53705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.super Ljava/lang/Object;
54705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
55705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# class Main {{
56705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
57705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.method public constructor <init>()V
58705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    .registers 1
59705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    invoke-direct {{p0}}, Ljava/lang/Object;-><init>()V
60705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return-void
61705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.end method
62705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
63705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light{test_funcs}
64705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
65705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light{main_func}
66705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
67705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# }}
68705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light"""
69705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
70705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  MAIN_FUNCTION_TEMPLATE = """
71705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#   public static void main(String[] args) {{
72705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.method public static main([Ljava/lang/String;)V
73705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    .locals 0
74705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
75705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    {test_group_invoke}
76705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
77705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return-void
78705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.end method
79705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#   }}
80705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light"""
81705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
82705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  TEST_GROUP_INVOKE_TEMPLATE = """
83705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#     {test_name}();
84705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    invoke-static {{}}, {test_name}()V
85705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light"""
86705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
87705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def __init__(self):
88705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
89705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Initialize this MainClass. We start out with no tests.
90705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
91705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    self.tests = set()
92705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
93705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def get_expected(self):
94705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
95705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Get the expected output of this test.
96705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
97705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    all_tests = sorted(self.tests)
98705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return filter_blanks("\n".join(a.get_expected() for a in all_tests))
99705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
100705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def add_test(self, ty):
101705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
102705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Add a test for the concrete type 'ty'
103705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
104705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    self.tests.add(Func(ty))
105705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
106705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def get_name(self):
107705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
108705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Get the name of this class
109705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
110705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return "Main"
111705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
112705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def __str__(self):
113705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
114705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Print the MainClass smali code.
115705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
116705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    all_tests = sorted(self.tests)
117705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    test_invoke = ""
118705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    test_funcs = ""
119705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    for t in all_tests:
120705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      test_funcs += str(t)
121705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    for t in all_tests:
122705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      test_invoke += self.TEST_GROUP_INVOKE_TEMPLATE.format(test_name=t.get_name())
123705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    main_func = self.MAIN_FUNCTION_TEMPLATE.format(test_group_invoke=test_invoke)
124705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
125705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return self.MAIN_CLASS_TEMPLATE.format(copyright = get_copyright("smali"),
126705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                           test_funcs = test_funcs,
127705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                           main_func = main_func)
128705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
129705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightclass Func(mixins.Named, mixins.NameComparableMixin):
130705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
131705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  A function that tests the functionality of a concrete type. Should only be
132705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  constructed by MainClass.add_test.
133705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
134705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
135705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  TEST_FUNCTION_TEMPLATE = """
136705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#   public static void {fname}() {{
137705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#     {farg} v = null;
138705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#     try {{
139705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#       v = new {farg}();
140705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#     }} catch (Throwable e) {{
141705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#       System.out.println("Unexpected error occurred which creating {farg} instance");
142705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#       e.printStackTrace(System.out);
143705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#       return;
144705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#     }}
145705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#     try {{
146705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#       v.callSupers();
147705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#       return;
148705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#     }} catch (Throwable e) {{
149705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#       e.printStackTrace(System.out);
150705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#       return;
151705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#     }}
152705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#   }}
153705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.method public static {fname}()V
154705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    .locals 7
155705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    sget-object v4, Ljava/lang/System;->out:Ljava/io/PrintStream;
156705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
157705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    :new_{fname}_try_start
158705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      new-instance v0, L{farg};
159705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      invoke-direct {{v0}}, L{farg};-><init>()V
160705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      goto :call_{fname}_try_start
161705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    :new_{fname}_try_end
162705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    .catch Ljava/lang/Throwable; {{:new_{fname}_try_start .. :new_{fname}_try_end}} :new_error_{fname}_start
163705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    :new_error_{fname}_start
164705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      move-exception v6
165705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      const-string v5, "Unexpected error occurred which creating {farg} instance"
166705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      invoke-virtual {{v4,v5}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
167705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      invoke-virtual {{v6,v4}}, Ljava/lang/Throwable;->printStackTrace(Ljava/io/PrintStream;)V
168705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      return-void
169705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    :call_{fname}_try_start
170705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      invoke-virtual {{v0}}, L{farg};->callSupers()V
171705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      return-void
172705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    :call_{fname}_try_end
173705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    .catch Ljava/lang/Throwable; {{:call_{fname}_try_start .. :call_{fname}_try_end}} :error_{fname}_start
174705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    :error_{fname}_start
175705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      move-exception v6
176705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      invoke-virtual {{v6,v4}}, Ljava/lang/Throwable;->printStackTrace(Ljava/io/PrintStream;)V
177705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      return-void
178705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.end method
179705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light"""
180705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
181705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def __init__(self, farg):
182705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
183705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Initialize a test function for the given argument
184705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
185705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    self.farg = farg
186705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
187705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def get_expected(self):
188705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
189705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Get the expected output calling this function.
190705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
191705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return "\n".join(self.farg.get_expected())
192705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
193705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def get_name(self):
194705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
195705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Get the name of this function
196705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
197705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return "TEST_FUNC_{}".format(self.farg.get_name())
198705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
199705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def __str__(self):
200705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
201705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Print the smali code of this function.
202705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
203705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return self.TEST_FUNCTION_TEMPLATE.format(fname = self.get_name(),
204705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                              farg = self.farg.get_name())
205705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
206705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightclass InterfaceCallResponse(Enum):
207705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
208705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  An enumeration of all the different types of responses to an interface call we can have
209705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
210705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  NoError = 0
211705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  NoSuchMethodError = 1
212705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  AbstractMethodError = 2
213705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  IncompatibleClassChangeError = 3
214705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
215705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def get_output_format(self):
216705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    if self == InterfaceCallResponse.NoError:
217705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      return "No exception thrown for {iface_name}.super.call() on {tree}\n"
218705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    elif self == InterfaceCallResponse.AbstractMethodError:
219705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      return "AbstractMethodError thrown for {iface_name}.super.call() on {tree}\n"
220705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    elif self == InterfaceCallResponse.NoSuchMethodError:
221705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      return "NoSuchMethodError thrown for {iface_name}.super.call() on {tree}\n"
222705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    else:
223705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      return "IncompatibleClassChangeError thrown for {iface_name}.super.call() on {tree}\n"
224705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
225705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightclass TestClass(mixins.DumpMixin, mixins.Named, mixins.NameComparableMixin, mixins.SmaliFileMixin):
226705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
227705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  A class that will be instantiated to test interface super behavior.
228705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
229705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
230705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  TEST_CLASS_TEMPLATE = """{copyright}
231705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
232705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.class public L{class_name};
233705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.super Ljava/lang/Object;
234705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light{implements_spec}
235705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
236705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# public class {class_name} implements {ifaces} {{
237705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
238705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.method public constructor <init>()V
239705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  .registers 1
240705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  invoke-direct {{p0}}, Ljava/lang/Object;-><init>()V
241705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  return-void
242705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.end method
243705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
244705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#   public void call() {{
245705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#     throw new Error("{class_name}.call(v) should never get called!");
246705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#   }}
247705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.method public call()V
248705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  .locals 2
249705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  new-instance v0, Ljava/lang/Error;
250705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  const-string v1, "{class_name}.call(v) should never get called!"
251705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  invoke-direct {{v0, v1}}, Ljava/lang/Error;-><init>(Ljava/lang/String;)V
252705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  throw v0
253705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.end method
254705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
255705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#   public void callSupers() {{
256705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.method public callSupers()V
257705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  .locals 4
258705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
259705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
260705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  {super_calls}
261705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
262705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  return-void
263705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.end method
264705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#   }}
265705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
266705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# }}
267705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light"""
268705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  SUPER_CALL_TEMPLATE = """
269705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#     try {{
270705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#       System.out.println("Calling {iface_name}.super.call() on {tree}");
271705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#       {iface_name}.super.call();
272705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#       System.out.println("No exception thrown for {iface_name}.super.call() on {tree}");
273705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#     }} catch (AbstractMethodError ame) {{
274705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#       System.out.println("AbstractMethodError thrown for {iface_name}.super.call() on {tree}");
275705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#     }} catch (NoSuchMethodError nsme) {{
276705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#       System.out.println("NoSuchMethodError thrown for {iface_name}.super.call() on {tree}");
277705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#     }} catch (IncompatibleClassChangeError icce) {{
278705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#       System.out.println("IncompatibleClassChangeError thrown for {iface_name}.super.call() on {tree}");
279705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#     }} catch (Throwable t) {{
280705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#       System.out.println("Unknown error thrown for {iface_name}.super.call() on {tree}");
281705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#       throw t;
282705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#     }}
283705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    :call_{class_name}_{iface_name}_try_start
284705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      const-string v1, "Calling {iface_name}.super.call() on {tree}"
285705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      invoke-virtual {{v0, v1}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
286705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      invoke-super {{p0}}, L{iface_name};->call()V
287705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      const-string v1, "No exception thrown for {iface_name}.super.call() on {tree}"
288705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      invoke-virtual {{v0, v1}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
289705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      goto :call_{class_name}_{iface_name}_end
290705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    :call_{class_name}_{iface_name}_try_end
291705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    .catch Ljava/lang/AbstractMethodError; {{:call_{class_name}_{iface_name}_try_start .. :call_{class_name}_{iface_name}_try_end}} :AME_{class_name}_{iface_name}_start
292705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    .catch Ljava/lang/NoSuchMethodError; {{:call_{class_name}_{iface_name}_try_start .. :call_{class_name}_{iface_name}_try_end}} :NSME_{class_name}_{iface_name}_start
293705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    .catch Ljava/lang/IncompatibleClassChangeError; {{:call_{class_name}_{iface_name}_try_start .. :call_{class_name}_{iface_name}_try_end}} :ICCE_{class_name}_{iface_name}_start
294705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    .catch Ljava/lang/Throwable; {{:call_{class_name}_{iface_name}_try_start .. :call_{class_name}_{iface_name}_try_end}} :error_{class_name}_{iface_name}_start
295705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    :AME_{class_name}_{iface_name}_start
296705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      const-string v1, "AbstractMethodError thrown for {iface_name}.super.call() on {tree}"
297705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      invoke-virtual {{v0, v1}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
298705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      goto :call_{class_name}_{iface_name}_end
299705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    :NSME_{class_name}_{iface_name}_start
300705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      const-string v1, "NoSuchMethodError thrown for {iface_name}.super.call() on {tree}"
301705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      invoke-virtual {{v0, v1}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
302705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      goto :call_{class_name}_{iface_name}_end
303705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    :ICCE_{class_name}_{iface_name}_start
304705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      const-string v1, "IncompatibleClassChangeError thrown for {iface_name}.super.call() on {tree}"
305705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      invoke-virtual {{v0, v1}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
306705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      goto :call_{class_name}_{iface_name}_end
307705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    :error_{class_name}_{iface_name}_start
308705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      move-exception v2
309705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      const-string v1, "Unknown error thrown for {iface_name}.super.call() on {tree}"
310705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      invoke-virtual {{v0, v1}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
311705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      throw v2
312705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    :call_{class_name}_{iface_name}_end
313705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light"""
314705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
315705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  IMPLEMENTS_TEMPLATE = """
316705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.implements L{iface_name};
317705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light"""
318705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
319705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  OUTPUT_PREFIX = "Calling {iface_name}.super.call() on {tree}\n"
320705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
321705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def __init__(self, ifaces):
322705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
323705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Initialize this test class which implements the given interfaces
324705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
325705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    self.ifaces = ifaces
326705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    self.class_name = "CLASS_"+gensym()
327705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
328705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def get_name(self):
329705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
330705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Get the name of this class
331705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
332705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return self.class_name
333705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
334705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def get_tree(self):
335705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
336705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Print out a representation of the type tree of this class
337705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
338705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return "[{class_name} {iface_tree}]".format(class_name = self.class_name,
339705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                                iface_tree = print_tree(self.ifaces))
340705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
341705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def __iter__(self):
342705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
343705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Step through all interfaces implemented transitively by this class
344705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
345705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    for i in self.ifaces:
346705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      yield i
347705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      yield from i
348705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
349705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def get_expected(self):
350705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    for iface in self.ifaces:
351705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      yield self.OUTPUT_PREFIX.format(iface_name = iface.get_name(), tree = self.get_tree())
352705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      yield from iface.get_expected()
353705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      yield iface.get_response().get_output_format().format(iface_name = iface.get_name(),
354705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                                            tree = self.get_tree())
355705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
356705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def __str__(self):
357705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
358705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Print the smali code of this class.
359705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
360705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    s_ifaces = '\n'.join(map(lambda a: self.IMPLEMENTS_TEMPLATE.format(iface_name = a.get_name()),
361705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                             self.ifaces))
362705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    j_ifaces = ', '.join(map(lambda a: a.get_name(), self.ifaces))
363705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    super_template = self.SUPER_CALL_TEMPLATE
364705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    super_calls = "\n".join(super_template.format(iface_name = iface.get_name(),
365705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                                  class_name = self.get_name(),
366705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                                  tree = self.get_tree()) for iface in self.ifaces)
367705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return self.TEST_CLASS_TEMPLATE.format(copyright = get_copyright('smali'),
368705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                           ifaces = j_ifaces,
369705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                           implements_spec = s_ifaces,
370705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                           tree = self.get_tree(),
371705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                           class_name = self.class_name,
372705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                           super_calls = super_calls)
373705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
374705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightclass InterfaceType(Enum):
375705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
376705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  An enumeration of all the different types of interfaces we can have.
377705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
378705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  default: It has a default method
379705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  abstract: It has a method declared but not defined
380705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  empty: It does not have the method
381705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
382705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  default = 0
383705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  abstract = 1
384705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  empty = 2
385705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
386705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def get_suffix(self):
387705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    if self == InterfaceType.default:
388705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      return "_DEFAULT"
389705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    elif self == InterfaceType.abstract:
390705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      return "_ABSTRACT"
391705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    elif self == InterfaceType.empty:
392705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      return "_EMPTY"
393705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    else:
394705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      raise TypeError("Interface type had illegal value.")
395705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
396705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightclass ConflictInterface:
397705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
398705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  A singleton representing a conflict of default methods.
399705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
400705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
401705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def is_conflict(self):
402705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
403705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Returns true if this is a conflict interface and calling the method on this interface will
404705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    result in an IncompatibleClassChangeError.
405705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
406705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return True
407705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
408705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def is_abstract(self):
409705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
410705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Returns true if this is an abstract interface and calling the method on this interface will
411705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    result in an AbstractMethodError.
412705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
413705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return False
414705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
415705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def is_empty(self):
416705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
417705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Returns true if this is an abstract interface and calling the method on this interface will
418705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    result in a NoSuchMethodError.
419705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
420705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return False
421705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
422705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def is_default(self):
423705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
424705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Returns true if this is a default interface and calling the method on this interface will
425705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    result in a method actually being called.
426705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
427705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return False
428705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
429705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def get_response(self):
430705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return InterfaceCallResponse.IncompatibleClassChangeError
431705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
432705ad49f353d3f90d8b63625aca2c2035bacdbefAlex LightCONFLICT_TYPE = ConflictInterface()
433705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
434705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightclass TestInterface(mixins.DumpMixin, mixins.Named, mixins.NameComparableMixin, mixins.SmaliFileMixin):
435705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
436705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  An interface that will be used to test default method resolution order.
437705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
438705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
439705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  TEST_INTERFACE_TEMPLATE = """{copyright}
440705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.class public abstract interface L{class_name};
441705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.super Ljava/lang/Object;
442705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light{implements_spec}
443705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
444705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# public interface {class_name} {extends} {ifaces} {{
445705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
446705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light{func}
447705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
448705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# }}
449705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light"""
450705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
451705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  SUPER_CALL_TEMPLATE = TestClass.SUPER_CALL_TEMPLATE
452705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  OUTPUT_PREFIX = TestClass.OUTPUT_PREFIX
453705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
454705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  DEFAULT_FUNC_TEMPLATE = """
455705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#   public default void call() {{
456705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.method public call()V
457705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  .locals 4
458705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
459705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
460705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  {super_calls}
461705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
462705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  return-void
463705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.end method
464705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#   }}
465705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light"""
466705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
467705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  ABSTRACT_FUNC_TEMPLATE = """
468705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light#   public void call();
469705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.method public abstract call()V
470705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.end method
471705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light"""
472705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
473705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  EMPTY_FUNC_TEMPLATE = """"""
474705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
475705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  IMPLEMENTS_TEMPLATE = """
476705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light.implements L{iface_name};
477705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light"""
478705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
479705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def __init__(self, ifaces, iface_type, full_name = None):
480705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
481705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Initialize interface with the given super-interfaces
482705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
483705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    self.ifaces = sorted(ifaces)
484705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    self.iface_type = iface_type
485705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    if full_name is None:
486705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      end = self.iface_type.get_suffix()
487705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      self.class_name = "INTERFACE_"+gensym()+end
488705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    else:
489705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      self.class_name = full_name
490705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
491705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def get_specific_version(self, v):
492705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
493705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Returns a copy of this interface of the given type for use in partial compilation.
494705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
495705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return TestInterface(self.ifaces, v, full_name = self.class_name)
496705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
497705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def get_super_types(self):
498705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
499705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Returns a set of all the supertypes of this interface
500705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
501705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return set(i2 for i2 in self)
502705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
503705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def is_conflict(self):
504705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
505705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Returns true if this is a conflict interface and calling the method on this interface will
506705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    result in an IncompatibleClassChangeError.
507705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
508705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return False
509705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
510705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def is_abstract(self):
511705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
512705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Returns true if this is an abstract interface and calling the method on this interface will
513705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    result in an AbstractMethodError.
514705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
515705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return self.iface_type == InterfaceType.abstract
516705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
517705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def is_empty(self):
518705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
519705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Returns true if this is an abstract interface and calling the method on this interface will
520705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    result in a NoSuchMethodError.
521705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
522705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return self.iface_type == InterfaceType.empty
523705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
524705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def is_default(self):
525705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
526705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Returns true if this is a default interface and calling the method on this interface will
527705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    result in a method actually being called.
528705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
529705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return self.iface_type == InterfaceType.default
530705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
531705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def get_expected(self):
532705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    response = self.get_response()
533705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    if response == InterfaceCallResponse.NoError:
534705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      for iface in self.ifaces:
535705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light        if self.is_default():
536705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light          yield self.OUTPUT_PREFIX.format(iface_name = iface.get_name(), tree = self.get_tree())
537705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light        yield from iface.get_expected()
538705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light        if self.is_default():
539705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light          yield iface.get_response().get_output_format().format(iface_name = iface.get_name(),
540705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                                                tree = self.get_tree())
541705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
542705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def get_response(self):
543705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    if self.is_default():
544705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      return InterfaceCallResponse.NoError
545705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    elif self.is_abstract():
546705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      return InterfaceCallResponse.AbstractMethodError
547705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    elif len(self.ifaces) == 0:
548705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      return InterfaceCallResponse.NoSuchMethodError
549705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    else:
550705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      return self.get_called().get_response()
551705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
552705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def get_called(self):
553705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
554705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Returns the interface that will be called when the method on this class is invoked or
555705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    CONFLICT_TYPE if there is no interface that will be called.
556705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
557705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    if not self.is_empty() or len(self.ifaces) == 0:
558705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      return self
559705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    else:
560705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      best = self
561705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      for super_iface in self.ifaces:
562705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light        super_best = super_iface.get_called()
563705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light        if super_best.is_conflict():
564705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light          return CONFLICT_TYPE
565705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light        elif best.is_default():
566705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light          if super_best.is_default():
567705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light            return CONFLICT_TYPE
568705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light        elif best.is_abstract():
569705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light          if super_best.is_default():
570705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light            best = super_best
571705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light        else:
572705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light          assert best.is_empty()
573705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light          best = super_best
574705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      return best
575705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
576705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def get_name(self):
577705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
578705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Get the name of this class
579705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
580705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return self.class_name
581705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
582705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def get_tree(self):
583705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
584705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Print out a representation of the type tree of this class
585705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
586705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return "[{class_name} {iftree}]".format(class_name = self.get_name(),
587705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                            iftree = print_tree(self.ifaces))
588705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
589705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def __iter__(self):
590705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
591705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Performs depth-first traversal of the interface tree this interface is the
592705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    root of. Does not filter out repeats.
593705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
594705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    for i in self.ifaces:
595705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      yield i
596705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      yield from i
597705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
598705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  def __str__(self):
599705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
600705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    Print the smali code of this interface.
601705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    """
602705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    s_ifaces = '\n'.join(map(lambda a: self.IMPLEMENTS_TEMPLATE.format(iface_name = a.get_name()),
603705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                             self.ifaces))
604705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    j_ifaces = ', '.join(map(lambda a: a.get_name(), self.ifaces))
605705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    if self.is_default():
606705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      super_template = self.SUPER_CALL_TEMPLATE
607705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      super_calls ="\n".join(super_template.format(iface_name = iface.get_name(),
608705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                                   class_name = self.get_name(),
609705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                                   tree = self.get_tree()) for iface in self.ifaces)
610705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      funcs = self.DEFAULT_FUNC_TEMPLATE.format(super_calls = super_calls)
611705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    elif self.is_abstract():
612705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      funcs = self.ABSTRACT_FUNC_TEMPLATE.format()
613705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    else:
614705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      funcs = ""
615705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return self.TEST_INTERFACE_TEMPLATE.format(copyright = get_copyright('smali'),
616705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                               implements_spec = s_ifaces,
617705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                               extends = "extends" if len(self.ifaces) else "",
618705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                               ifaces = j_ifaces,
619705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                               func = funcs,
620705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                               tree = self.get_tree(),
621705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light                                               class_name = self.class_name)
622705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
623705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightdef print_tree(ifaces):
624705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
625705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  Prints a list of iface trees
626705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
627705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  return " ".join(i.get_tree() for i in ifaces)
628705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
629705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# The deduplicated output of subtree_sizes for each size up to
630705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light# MAX_LEAF_IFACE_PER_OBJECT.
631705ad49f353d3f90d8b63625aca2c2035bacdbefAlex LightSUBTREES = [set(tuple(sorted(l)) for l in subtree_sizes(i))
632705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light            for i in range(MAX_IFACE_DEPTH + 1)]
633705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
634705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightdef create_test_classes():
635705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
636705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  Yield all the test classes with the different interface trees
637705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
638705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  for num in range(1, MAX_IFACE_DEPTH + 1):
639705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    for split in SUBTREES[num]:
640705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      ifaces = []
641705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      for sub in split:
642705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light        ifaces.append(list(create_interface_trees(sub)))
643705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      for supers in itertools.product(*ifaces):
644705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light        yield TestClass(supers)
645705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
646705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightdef create_interface_trees(num):
647705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
648705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  Yield all the interface trees up to 'num' depth.
649705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
650705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  if num == 0:
651705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    for iftype in InterfaceType:
652705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      yield TestInterface(tuple(), iftype)
653705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    return
654705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  for split in SUBTREES[num]:
655705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    ifaces = []
656705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    for sub in split:
657705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      ifaces.append(list(create_interface_trees(sub)))
658705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    for supers in itertools.product(*ifaces):
659705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      for iftype in InterfaceType:
660705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light        yield TestInterface(supers, iftype)
661705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
662705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightdef create_all_test_files():
663705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
664705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  Creates all the objects representing the files in this test. They just need to
665705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  be dumped.
666705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  """
667705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  mc = MainClass()
668705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  classes = {mc}
669705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  for clazz in create_test_classes():
670705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    classes.add(clazz)
671705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    for i in clazz:
672705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light      classes.add(i)
673705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    mc.add_test(clazz)
674705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  return mc, classes
675705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
676705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightdef main(argv):
677705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  smali_dir = Path(argv[1])
678705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  if not smali_dir.exists() or not smali_dir.is_dir():
679705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    print("{} is not a valid smali dir".format(smali_dir), file=sys.stderr)
680705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    sys.exit(1)
681705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  expected_txt = Path(argv[2])
682705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  mainclass, all_files = create_all_test_files()
683705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  with expected_txt.open('w') as out:
684705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    print(mainclass.get_expected(), file=out)
685705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  for f in all_files:
686705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light    f.dump(smali_dir)
687705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light
688705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Lightif __name__ == '__main__':
689705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light  main(sys.argv)
690