xref: /aosp_15_r20/art/test/970-iface-super-resolution-gen/util-src/generate_smali.py (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker#!/usr/bin/python3
2*795d594fSAndroid Build Coastguard Worker#
3*795d594fSAndroid Build Coastguard Worker# Copyright (C) 2015 The Android Open Source Project
4*795d594fSAndroid Build Coastguard Worker#
5*795d594fSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
6*795d594fSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
7*795d594fSAndroid Build Coastguard Worker# You may obtain a copy of the License at
8*795d594fSAndroid Build Coastguard Worker#
9*795d594fSAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
10*795d594fSAndroid Build Coastguard Worker#
11*795d594fSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
12*795d594fSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
13*795d594fSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*795d594fSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
15*795d594fSAndroid Build Coastguard Worker# limitations under the License.
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker"""
18*795d594fSAndroid Build Coastguard WorkerGenerate Smali test files for test 966.
19*795d594fSAndroid Build Coastguard Worker"""
20*795d594fSAndroid Build Coastguard Worker
21*795d594fSAndroid Build Coastguard Workerimport os
22*795d594fSAndroid Build Coastguard Workerimport sys
23*795d594fSAndroid Build Coastguard Workerfrom pathlib import Path
24*795d594fSAndroid Build Coastguard Worker
25*795d594fSAndroid Build Coastguard WorkerBUILD_TOP = os.getenv("ANDROID_BUILD_TOP")
26*795d594fSAndroid Build Coastguard Workerif BUILD_TOP is None:
27*795d594fSAndroid Build Coastguard Worker  print("ANDROID_BUILD_TOP not set. Please run build/envsetup.sh", file=sys.stderr)
28*795d594fSAndroid Build Coastguard Worker  sys.exit(1)
29*795d594fSAndroid Build Coastguard Worker
30*795d594fSAndroid Build Coastguard Worker# Allow us to import utils and mixins.
31*795d594fSAndroid Build Coastguard Workersys.path.append(str(Path(BUILD_TOP)/"art"/"test"/"utils"/"python"))
32*795d594fSAndroid Build Coastguard Worker
33*795d594fSAndroid Build Coastguard Workerfrom testgen.utils import get_copyright, subtree_sizes, gensym, filter_blanks
34*795d594fSAndroid Build Coastguard Workerimport testgen.mixins as mixins
35*795d594fSAndroid Build Coastguard Worker
36*795d594fSAndroid Build Coastguard Workerfrom functools import total_ordering
37*795d594fSAndroid Build Coastguard Workerimport itertools
38*795d594fSAndroid Build Coastguard Workerimport string
39*795d594fSAndroid Build Coastguard Worker
40*795d594fSAndroid Build Coastguard Worker# The max depth the tree can have.
41*795d594fSAndroid Build Coastguard WorkerMAX_IFACE_DEPTH = 3
42*795d594fSAndroid Build Coastguard Worker
43*795d594fSAndroid Build Coastguard Workerclass MainClass(mixins.DumpMixin, mixins.Named, mixins.SmaliFileMixin):
44*795d594fSAndroid Build Coastguard Worker  """
45*795d594fSAndroid Build Coastguard Worker  A Main.smali file containing the Main class and the main function. It will run
46*795d594fSAndroid Build Coastguard Worker  all the test functions we have.
47*795d594fSAndroid Build Coastguard Worker  """
48*795d594fSAndroid Build Coastguard Worker
49*795d594fSAndroid Build Coastguard Worker  MAIN_CLASS_TEMPLATE = """{copyright}
50*795d594fSAndroid Build Coastguard Worker
51*795d594fSAndroid Build Coastguard Worker.class public LMain;
52*795d594fSAndroid Build Coastguard Worker.super Ljava/lang/Object;
53*795d594fSAndroid Build Coastguard Worker
54*795d594fSAndroid Build Coastguard Worker# class Main {{
55*795d594fSAndroid Build Coastguard Worker
56*795d594fSAndroid Build Coastguard Worker.method public constructor <init>()V
57*795d594fSAndroid Build Coastguard Worker    .registers 1
58*795d594fSAndroid Build Coastguard Worker    invoke-direct {{p0}}, Ljava/lang/Object;-><init>()V
59*795d594fSAndroid Build Coastguard Worker    return-void
60*795d594fSAndroid Build Coastguard Worker.end method
61*795d594fSAndroid Build Coastguard Worker
62*795d594fSAndroid Build Coastguard Worker{test_groups}
63*795d594fSAndroid Build Coastguard Worker
64*795d594fSAndroid Build Coastguard Worker{main_func}
65*795d594fSAndroid Build Coastguard Worker
66*795d594fSAndroid Build Coastguard Worker# }}
67*795d594fSAndroid Build Coastguard Worker"""
68*795d594fSAndroid Build Coastguard Worker
69*795d594fSAndroid Build Coastguard Worker  MAIN_FUNCTION_TEMPLATE = """
70*795d594fSAndroid Build Coastguard Worker#   public static void main(String[] args) {{
71*795d594fSAndroid Build Coastguard Worker.method public static main([Ljava/lang/String;)V
72*795d594fSAndroid Build Coastguard Worker    .locals 2
73*795d594fSAndroid Build Coastguard Worker
74*795d594fSAndroid Build Coastguard Worker    {test_group_invoke}
75*795d594fSAndroid Build Coastguard Worker
76*795d594fSAndroid Build Coastguard Worker    return-void
77*795d594fSAndroid Build Coastguard Worker.end method
78*795d594fSAndroid Build Coastguard Worker#   }}
79*795d594fSAndroid Build Coastguard Worker"""
80*795d594fSAndroid Build Coastguard Worker
81*795d594fSAndroid Build Coastguard Worker  TEST_GROUP_INVOKE_TEMPLATE = """
82*795d594fSAndroid Build Coastguard Worker#     {test_name}();
83*795d594fSAndroid Build Coastguard Worker    invoke-static {{}}, {test_name}()V
84*795d594fSAndroid Build Coastguard Worker"""
85*795d594fSAndroid Build Coastguard Worker
86*795d594fSAndroid Build Coastguard Worker  def __init__(self):
87*795d594fSAndroid Build Coastguard Worker    """
88*795d594fSAndroid Build Coastguard Worker    Initialize this MainClass. We start out with no tests.
89*795d594fSAndroid Build Coastguard Worker    """
90*795d594fSAndroid Build Coastguard Worker    self.tests = set()
91*795d594fSAndroid Build Coastguard Worker
92*795d594fSAndroid Build Coastguard Worker  def add_test(self, ty):
93*795d594fSAndroid Build Coastguard Worker    """
94*795d594fSAndroid Build Coastguard Worker    Add a test for the concrete type 'ty'
95*795d594fSAndroid Build Coastguard Worker    """
96*795d594fSAndroid Build Coastguard Worker    self.tests.add(Func(ty))
97*795d594fSAndroid Build Coastguard Worker
98*795d594fSAndroid Build Coastguard Worker  def get_expected(self):
99*795d594fSAndroid Build Coastguard Worker    """
100*795d594fSAndroid Build Coastguard Worker    Get the expected output of this test.
101*795d594fSAndroid Build Coastguard Worker    """
102*795d594fSAndroid Build Coastguard Worker    all_tests = sorted(self.tests)
103*795d594fSAndroid Build Coastguard Worker    return filter_blanks("\n".join(a.get_expected() for a in all_tests))
104*795d594fSAndroid Build Coastguard Worker
105*795d594fSAndroid Build Coastguard Worker  def initial_build_different(self):
106*795d594fSAndroid Build Coastguard Worker    return False
107*795d594fSAndroid Build Coastguard Worker
108*795d594fSAndroid Build Coastguard Worker  def get_name(self):
109*795d594fSAndroid Build Coastguard Worker    """
110*795d594fSAndroid Build Coastguard Worker    Gets the name of this class
111*795d594fSAndroid Build Coastguard Worker    """
112*795d594fSAndroid Build Coastguard Worker    return "Main"
113*795d594fSAndroid Build Coastguard Worker
114*795d594fSAndroid Build Coastguard Worker  def __str__(self):
115*795d594fSAndroid Build Coastguard Worker    """
116*795d594fSAndroid Build Coastguard Worker    Print the smali code for this test.
117*795d594fSAndroid Build Coastguard Worker    """
118*795d594fSAndroid Build Coastguard Worker    all_tests = sorted(self.tests)
119*795d594fSAndroid Build Coastguard Worker    test_invoke = ""
120*795d594fSAndroid Build Coastguard Worker    test_groups = ""
121*795d594fSAndroid Build Coastguard Worker    for t in all_tests:
122*795d594fSAndroid Build Coastguard Worker      test_groups += str(t)
123*795d594fSAndroid Build Coastguard Worker    for t in all_tests:
124*795d594fSAndroid Build Coastguard Worker      test_invoke += self.TEST_GROUP_INVOKE_TEMPLATE.format(test_name=t.get_name())
125*795d594fSAndroid Build Coastguard Worker    main_func = self.MAIN_FUNCTION_TEMPLATE.format(test_group_invoke=test_invoke)
126*795d594fSAndroid Build Coastguard Worker
127*795d594fSAndroid Build Coastguard Worker    return self.MAIN_CLASS_TEMPLATE.format(copyright = get_copyright('smali'),
128*795d594fSAndroid Build Coastguard Worker                                           test_groups = test_groups,
129*795d594fSAndroid Build Coastguard Worker                                           main_func = main_func)
130*795d594fSAndroid Build Coastguard Worker
131*795d594fSAndroid Build Coastguard Workerclass Func(mixins.Named, mixins.NameComparableMixin):
132*795d594fSAndroid Build Coastguard Worker  """
133*795d594fSAndroid Build Coastguard Worker  A function that tests the functionality of a concrete type. Should only be
134*795d594fSAndroid Build Coastguard Worker  constructed by MainClass.add_test.
135*795d594fSAndroid Build Coastguard Worker  """
136*795d594fSAndroid Build Coastguard Worker
137*795d594fSAndroid Build Coastguard Worker  TEST_FUNCTION_TEMPLATE = """
138*795d594fSAndroid Build Coastguard Worker#   public static void {fname}() {{
139*795d594fSAndroid Build Coastguard Worker#     try {{
140*795d594fSAndroid Build Coastguard Worker#       {farg} v = new {farg}();
141*795d594fSAndroid Build Coastguard Worker#       System.out.println("Testing {tree}");
142*795d594fSAndroid Build Coastguard Worker#       v.testAll();
143*795d594fSAndroid Build Coastguard Worker#       System.out.println("Success: testing {tree}");
144*795d594fSAndroid Build Coastguard Worker#       return;
145*795d594fSAndroid Build Coastguard Worker#     }} catch (Exception e) {{
146*795d594fSAndroid Build Coastguard Worker#       System.out.println("Failure: testing {tree}");
147*795d594fSAndroid Build Coastguard Worker#       e.printStackTrace(System.out);
148*795d594fSAndroid Build Coastguard Worker#       return;
149*795d594fSAndroid Build Coastguard Worker#     }}
150*795d594fSAndroid Build Coastguard Worker#   }}
151*795d594fSAndroid Build Coastguard Worker.method public static {fname}()V
152*795d594fSAndroid Build Coastguard Worker    .locals 7
153*795d594fSAndroid Build Coastguard Worker    :call_{fname}_try_start
154*795d594fSAndroid Build Coastguard Worker      sget-object v2, Ljava/lang/System;->out:Ljava/io/PrintStream;
155*795d594fSAndroid Build Coastguard Worker
156*795d594fSAndroid Build Coastguard Worker      new-instance v6, L{farg};
157*795d594fSAndroid Build Coastguard Worker      invoke-direct {{v6}}, L{farg};-><init>()V
158*795d594fSAndroid Build Coastguard Worker
159*795d594fSAndroid Build Coastguard Worker      const-string v3, "Testing {tree}"
160*795d594fSAndroid Build Coastguard Worker      invoke-virtual {{v2, v3}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
161*795d594fSAndroid Build Coastguard Worker
162*795d594fSAndroid Build Coastguard Worker      invoke-virtual {{v6}}, L{farg};->testAll()V
163*795d594fSAndroid Build Coastguard Worker
164*795d594fSAndroid Build Coastguard Worker      const-string v3, "Success: testing {tree}"
165*795d594fSAndroid Build Coastguard Worker      invoke-virtual {{v2, v3}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
166*795d594fSAndroid Build Coastguard Worker
167*795d594fSAndroid Build Coastguard Worker      return-void
168*795d594fSAndroid Build Coastguard Worker    :call_{fname}_try_end
169*795d594fSAndroid Build Coastguard Worker    .catch Ljava/lang/Exception; {{:call_{fname}_try_start .. :call_{fname}_try_end}} :error_{fname}_start
170*795d594fSAndroid Build Coastguard Worker    :error_{fname}_start
171*795d594fSAndroid Build Coastguard Worker      move-exception v3
172*795d594fSAndroid Build Coastguard Worker      sget-object v2, Ljava/lang/System;->out:Ljava/io/PrintStream;
173*795d594fSAndroid Build Coastguard Worker      const-string v4, "Failure: testing {tree}"
174*795d594fSAndroid Build Coastguard Worker      invoke-virtual {{v2, v3}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
175*795d594fSAndroid Build Coastguard Worker      invoke-virtual {{v3,v2}}, Ljava/lang/Error;->printStackTrace(Ljava/io/PrintStream;)V
176*795d594fSAndroid Build Coastguard Worker      return-void
177*795d594fSAndroid Build Coastguard Worker.end method
178*795d594fSAndroid Build Coastguard Worker"""
179*795d594fSAndroid Build Coastguard Worker
180*795d594fSAndroid Build Coastguard Worker  OUTPUT_FORMAT = """
181*795d594fSAndroid Build Coastguard WorkerTesting {tree}
182*795d594fSAndroid Build Coastguard Worker{test_output}
183*795d594fSAndroid Build Coastguard WorkerSuccess: testing {tree}
184*795d594fSAndroid Build Coastguard Worker""".strip()
185*795d594fSAndroid Build Coastguard Worker
186*795d594fSAndroid Build Coastguard Worker  def __init__(self, farg):
187*795d594fSAndroid Build Coastguard Worker    """
188*795d594fSAndroid Build Coastguard Worker    Initialize a test function for the given argument
189*795d594fSAndroid Build Coastguard Worker    """
190*795d594fSAndroid Build Coastguard Worker    self.farg = farg
191*795d594fSAndroid Build Coastguard Worker
192*795d594fSAndroid Build Coastguard Worker  def __str__(self):
193*795d594fSAndroid Build Coastguard Worker    """
194*795d594fSAndroid Build Coastguard Worker    Print the smali code for this test function.
195*795d594fSAndroid Build Coastguard Worker    """
196*795d594fSAndroid Build Coastguard Worker    return self.TEST_FUNCTION_TEMPLATE.format(fname = self.get_name(),
197*795d594fSAndroid Build Coastguard Worker                                              farg  = self.farg.get_name(),
198*795d594fSAndroid Build Coastguard Worker                                              tree  = self.farg.get_tree())
199*795d594fSAndroid Build Coastguard Worker
200*795d594fSAndroid Build Coastguard Worker  def get_name(self):
201*795d594fSAndroid Build Coastguard Worker    """
202*795d594fSAndroid Build Coastguard Worker    Gets the name of this test function
203*795d594fSAndroid Build Coastguard Worker    """
204*795d594fSAndroid Build Coastguard Worker    return "TEST_FUNC_{}".format(self.farg.get_name())
205*795d594fSAndroid Build Coastguard Worker
206*795d594fSAndroid Build Coastguard Worker  def get_expected(self):
207*795d594fSAndroid Build Coastguard Worker    """
208*795d594fSAndroid Build Coastguard Worker    Get the expected output of this function.
209*795d594fSAndroid Build Coastguard Worker    """
210*795d594fSAndroid Build Coastguard Worker    return self.OUTPUT_FORMAT.format(
211*795d594fSAndroid Build Coastguard Worker        tree = self.farg.get_tree(),
212*795d594fSAndroid Build Coastguard Worker        test_output = self.farg.get_test_output().strip())
213*795d594fSAndroid Build Coastguard Worker
214*795d594fSAndroid Build Coastguard Workerclass TestClass(mixins.DumpMixin, mixins.Named, mixins.NameComparableMixin, mixins.SmaliFileMixin):
215*795d594fSAndroid Build Coastguard Worker  """
216*795d594fSAndroid Build Coastguard Worker  A class that will be instantiated to test interface initialization order.
217*795d594fSAndroid Build Coastguard Worker  """
218*795d594fSAndroid Build Coastguard Worker
219*795d594fSAndroid Build Coastguard Worker  TEST_CLASS_TEMPLATE = """{copyright}
220*795d594fSAndroid Build Coastguard Worker
221*795d594fSAndroid Build Coastguard Worker.class public L{class_name};
222*795d594fSAndroid Build Coastguard Worker.super Ljava/lang/Object;
223*795d594fSAndroid Build Coastguard Worker{implements_spec}
224*795d594fSAndroid Build Coastguard Worker
225*795d594fSAndroid Build Coastguard Worker# public class {class_name} implements {ifaces} {{
226*795d594fSAndroid Build Coastguard Worker#
227*795d594fSAndroid Build Coastguard Worker#   public {class_name}() {{
228*795d594fSAndroid Build Coastguard Worker#   }}
229*795d594fSAndroid Build Coastguard Worker.method public constructor <init>()V
230*795d594fSAndroid Build Coastguard Worker  .locals 2
231*795d594fSAndroid Build Coastguard Worker  invoke-direct {{p0}}, Ljava/lang/Object;-><init>()V
232*795d594fSAndroid Build Coastguard Worker  return-void
233*795d594fSAndroid Build Coastguard Worker.end method
234*795d594fSAndroid Build Coastguard Worker
235*795d594fSAndroid Build Coastguard Worker#   public String getCalledInterface() {{
236*795d594fSAndroid Build Coastguard Worker#     throw new Error("Should not be called");
237*795d594fSAndroid Build Coastguard Worker#   }}
238*795d594fSAndroid Build Coastguard Worker.method public getCalledInterface()V
239*795d594fSAndroid Build Coastguard Worker  .locals 2
240*795d594fSAndroid Build Coastguard Worker  const-string v0, "Should not be called"
241*795d594fSAndroid Build Coastguard Worker  new-instance v1, Ljava/lang/Error;
242*795d594fSAndroid Build Coastguard Worker  invoke-direct {{v1, v0}}, Ljava/lang/Error;-><init>(Ljava/lang/String;)V
243*795d594fSAndroid Build Coastguard Worker  throw v1
244*795d594fSAndroid Build Coastguard Worker.end method
245*795d594fSAndroid Build Coastguard Worker
246*795d594fSAndroid Build Coastguard Worker#   public void testAll() {{
247*795d594fSAndroid Build Coastguard Worker#     boolean failed = false;
248*795d594fSAndroid Build Coastguard Worker#     Error exceptions = new Error("Test failures");
249*795d594fSAndroid Build Coastguard Worker.method public testAll()V
250*795d594fSAndroid Build Coastguard Worker  .locals 5
251*795d594fSAndroid Build Coastguard Worker  const/4 v0, 0
252*795d594fSAndroid Build Coastguard Worker  const-string v1, "Test failures"
253*795d594fSAndroid Build Coastguard Worker  new-instance v2, Ljava/lang/Error;
254*795d594fSAndroid Build Coastguard Worker  invoke-direct {{v2, v1}}, Ljava/lang/Error;-><init>(Ljava/lang/String;)V
255*795d594fSAndroid Build Coastguard Worker
256*795d594fSAndroid Build Coastguard Worker  {test_calls}
257*795d594fSAndroid Build Coastguard Worker
258*795d594fSAndroid Build Coastguard Worker#     if (failed) {{
259*795d594fSAndroid Build Coastguard Worker  if-eqz v0, :end
260*795d594fSAndroid Build Coastguard Worker#       throw exceptions;
261*795d594fSAndroid Build Coastguard Worker    throw v2
262*795d594fSAndroid Build Coastguard Worker  :end
263*795d594fSAndroid Build Coastguard Worker#     }}
264*795d594fSAndroid Build Coastguard Worker  return-void
265*795d594fSAndroid Build Coastguard Worker#   }}
266*795d594fSAndroid Build Coastguard Worker.end method
267*795d594fSAndroid Build Coastguard Worker
268*795d594fSAndroid Build Coastguard Worker{test_funcs}
269*795d594fSAndroid Build Coastguard Worker
270*795d594fSAndroid Build Coastguard Worker# }}
271*795d594fSAndroid Build Coastguard Worker"""
272*795d594fSAndroid Build Coastguard Worker
273*795d594fSAndroid Build Coastguard Worker  IMPLEMENTS_TEMPLATE = """
274*795d594fSAndroid Build Coastguard Worker.implements L{iface_name};
275*795d594fSAndroid Build Coastguard Worker"""
276*795d594fSAndroid Build Coastguard Worker
277*795d594fSAndroid Build Coastguard Worker  TEST_CALL_TEMPLATE = """
278*795d594fSAndroid Build Coastguard Worker#     try {{
279*795d594fSAndroid Build Coastguard Worker#       test_{iface}_super();
280*795d594fSAndroid Build Coastguard Worker#     }} catch (Throwable t) {{
281*795d594fSAndroid Build Coastguard Worker#       exceptions.addSuppressed(t);
282*795d594fSAndroid Build Coastguard Worker#       failed = true;
283*795d594fSAndroid Build Coastguard Worker#     }}
284*795d594fSAndroid Build Coastguard Worker  :try_{iface}_start
285*795d594fSAndroid Build Coastguard Worker    invoke-virtual {{p0}}, L{class_name};->test_{iface}_super()V
286*795d594fSAndroid Build Coastguard Worker    goto :error_{iface}_end
287*795d594fSAndroid Build Coastguard Worker  :try_{iface}_end
288*795d594fSAndroid Build Coastguard Worker  .catch Ljava/lang/Throwable; {{:try_{iface}_start .. :try_{iface}_end}} :error_{iface}_start
289*795d594fSAndroid Build Coastguard Worker  :error_{iface}_start
290*795d594fSAndroid Build Coastguard Worker    move-exception v3
291*795d594fSAndroid Build Coastguard Worker    invoke-virtual {{v2, v3}}, Ljava/lang/Throwable;->addSuppressed(Ljava/lang/Throwable;)V
292*795d594fSAndroid Build Coastguard Worker    const/4 v0, 1
293*795d594fSAndroid Build Coastguard Worker  :error_{iface}_end
294*795d594fSAndroid Build Coastguard Worker"""
295*795d594fSAndroid Build Coastguard Worker
296*795d594fSAndroid Build Coastguard Worker  TEST_FUNC_TEMPLATE = """
297*795d594fSAndroid Build Coastguard Worker#   public void test_{iface}_super() {{
298*795d594fSAndroid Build Coastguard Worker#     try {{
299*795d594fSAndroid Build Coastguard Worker#       System.out.println("{class_name} -> {iface}.super.getCalledInterface(): " +
300*795d594fSAndroid Build Coastguard Worker#                          {iface}.super.getCalledInterface());
301*795d594fSAndroid Build Coastguard Worker#     }} catch (NoSuchMethodError e) {{
302*795d594fSAndroid Build Coastguard Worker#       System.out.println("{class_name} -> {iface}.super.getCalledInterface(): NoSuchMethodError");
303*795d594fSAndroid Build Coastguard Worker#     }} catch (IncompatibleClassChangeError e) {{
304*795d594fSAndroid Build Coastguard Worker#       System.out.println("{class_name} -> {iface}.super.getCalledInterface(): IncompatibleClassChangeError");
305*795d594fSAndroid Build Coastguard Worker#     }} catch (Throwable t) {{
306*795d594fSAndroid Build Coastguard Worker#       System.out.println("{class_name} -> {iface}.super.getCalledInterface(): Unknown error occurred");
307*795d594fSAndroid Build Coastguard Worker#       throw t;
308*795d594fSAndroid Build Coastguard Worker#     }}
309*795d594fSAndroid Build Coastguard Worker#   }}
310*795d594fSAndroid Build Coastguard Worker.method public test_{iface}_super()V
311*795d594fSAndroid Build Coastguard Worker  .locals 3
312*795d594fSAndroid Build Coastguard Worker  sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
313*795d594fSAndroid Build Coastguard Worker  :try_start
314*795d594fSAndroid Build Coastguard Worker    const-string v1, "{class_name} -> {iface}.super.getCalledInterface(): "
315*795d594fSAndroid Build Coastguard Worker    invoke-super {{p0}}, L{iface};->getCalledInterface()Ljava/lang/String;
316*795d594fSAndroid Build Coastguard Worker    move-result-object v2
317*795d594fSAndroid Build Coastguard Worker
318*795d594fSAndroid Build Coastguard Worker    invoke-virtual {{v1, v2}}, Ljava/lang/String;->concat(Ljava/lang/String;)Ljava/lang/String;
319*795d594fSAndroid Build Coastguard Worker    move-result-object v1
320*795d594fSAndroid Build Coastguard Worker
321*795d594fSAndroid Build Coastguard Worker    invoke-virtual {{v0, v1}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
322*795d594fSAndroid Build Coastguard Worker
323*795d594fSAndroid Build Coastguard Worker    return-void
324*795d594fSAndroid Build Coastguard Worker  :try_end
325*795d594fSAndroid Build Coastguard Worker  .catch Ljava/lang/NoSuchMethodError; {{:try_start .. :try_end}} :AME_catch
326*795d594fSAndroid Build Coastguard Worker  .catch Ljava/lang/IncompatibleClassChangeError; {{:try_start .. :try_end}} :ICCE_catch
327*795d594fSAndroid Build Coastguard Worker  .catch Ljava/lang/Throwable; {{:try_start .. :try_end}} :throwable_catch
328*795d594fSAndroid Build Coastguard Worker  :AME_catch
329*795d594fSAndroid Build Coastguard Worker    const-string v1, "{class_name} -> {iface}.super.getCalledInterface(): NoSuchMethodError"
330*795d594fSAndroid Build Coastguard Worker    invoke-virtual {{v0, v1}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
331*795d594fSAndroid Build Coastguard Worker    return-void
332*795d594fSAndroid Build Coastguard Worker  :ICCE_catch
333*795d594fSAndroid Build Coastguard Worker    const-string v1, "{class_name} -> {iface}.super.getCalledInterface(): IncompatibleClassChangeError"
334*795d594fSAndroid Build Coastguard Worker    invoke-virtual {{v0, v1}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
335*795d594fSAndroid Build Coastguard Worker    return-void
336*795d594fSAndroid Build Coastguard Worker  :throwable_catch
337*795d594fSAndroid Build Coastguard Worker    move-exception v2
338*795d594fSAndroid Build Coastguard Worker    const-string v1, "{class_name} -> {iface}.super.getCalledInterface(): Unknown error occurred"
339*795d594fSAndroid Build Coastguard Worker    invoke-virtual {{v0, v1}}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
340*795d594fSAndroid Build Coastguard Worker    throw v2
341*795d594fSAndroid Build Coastguard Worker.end method
342*795d594fSAndroid Build Coastguard Worker""".strip()
343*795d594fSAndroid Build Coastguard Worker
344*795d594fSAndroid Build Coastguard Worker  OUTPUT_TEMPLATE = "{class_name} -> {iface}.super.getCalledInterface(): {result}"
345*795d594fSAndroid Build Coastguard Worker
346*795d594fSAndroid Build Coastguard Worker  def __init__(self, ifaces, name = None):
347*795d594fSAndroid Build Coastguard Worker    """
348*795d594fSAndroid Build Coastguard Worker    Initialize this test class which implements the given interfaces
349*795d594fSAndroid Build Coastguard Worker    """
350*795d594fSAndroid Build Coastguard Worker    self.ifaces = ifaces
351*795d594fSAndroid Build Coastguard Worker    if name is None:
352*795d594fSAndroid Build Coastguard Worker      self.class_name = "CLASS_"+gensym()
353*795d594fSAndroid Build Coastguard Worker    else:
354*795d594fSAndroid Build Coastguard Worker      self.class_name = name
355*795d594fSAndroid Build Coastguard Worker
356*795d594fSAndroid Build Coastguard Worker  def get_initial_build_version(self):
357*795d594fSAndroid Build Coastguard Worker    """
358*795d594fSAndroid Build Coastguard Worker    Returns a version of this class that can be used for the initial build (meaning no compiler
359*795d594fSAndroid Build Coastguard Worker    checks will be triggered).
360*795d594fSAndroid Build Coastguard Worker    """
361*795d594fSAndroid Build Coastguard Worker    return TestClass([i.get_initial_build_version() for i in self.ifaces], self.class_name)
362*795d594fSAndroid Build Coastguard Worker
363*795d594fSAndroid Build Coastguard Worker  def initial_build_different(self):
364*795d594fSAndroid Build Coastguard Worker    return False
365*795d594fSAndroid Build Coastguard Worker
366*795d594fSAndroid Build Coastguard Worker  def get_name(self):
367*795d594fSAndroid Build Coastguard Worker    """
368*795d594fSAndroid Build Coastguard Worker    Gets the name of this interface
369*795d594fSAndroid Build Coastguard Worker    """
370*795d594fSAndroid Build Coastguard Worker    return self.class_name
371*795d594fSAndroid Build Coastguard Worker
372*795d594fSAndroid Build Coastguard Worker  def get_tree(self):
373*795d594fSAndroid Build Coastguard Worker    """
374*795d594fSAndroid Build Coastguard Worker    Print out a representation of the type tree of this class
375*795d594fSAndroid Build Coastguard Worker    """
376*795d594fSAndroid Build Coastguard Worker    return "[{fname} {iftree}]".format(fname = self.get_name(), iftree = print_tree(self.ifaces))
377*795d594fSAndroid Build Coastguard Worker
378*795d594fSAndroid Build Coastguard Worker  def get_test_output(self):
379*795d594fSAndroid Build Coastguard Worker    return '\n'.join(map(lambda a: self.OUTPUT_TEMPLATE.format(class_name = self.get_name(),
380*795d594fSAndroid Build Coastguard Worker                                                               iface = a.get_name(),
381*795d594fSAndroid Build Coastguard Worker                                                               result = a.get_output()),
382*795d594fSAndroid Build Coastguard Worker                         self.ifaces))
383*795d594fSAndroid Build Coastguard Worker
384*795d594fSAndroid Build Coastguard Worker  def __str__(self):
385*795d594fSAndroid Build Coastguard Worker    """
386*795d594fSAndroid Build Coastguard Worker    Print the smali code for this class.
387*795d594fSAndroid Build Coastguard Worker    """
388*795d594fSAndroid Build Coastguard Worker    funcs = '\n'.join(map(lambda a: self.TEST_FUNC_TEMPLATE.format(iface = a.get_name(),
389*795d594fSAndroid Build Coastguard Worker                                                                   class_name = self.get_name()),
390*795d594fSAndroid Build Coastguard Worker                          self.ifaces))
391*795d594fSAndroid Build Coastguard Worker    calls = '\n'.join(map(lambda a: self.TEST_CALL_TEMPLATE.format(iface = a.get_name(),
392*795d594fSAndroid Build Coastguard Worker                                                                   class_name = self.get_name()),
393*795d594fSAndroid Build Coastguard Worker                          self.ifaces))
394*795d594fSAndroid Build Coastguard Worker    s_ifaces = '\n'.join(map(lambda a: self.IMPLEMENTS_TEMPLATE.format(iface_name = a.get_name()),
395*795d594fSAndroid Build Coastguard Worker                             self.ifaces))
396*795d594fSAndroid Build Coastguard Worker    j_ifaces = ', '.join(map(lambda a: a.get_name(), self.ifaces))
397*795d594fSAndroid Build Coastguard Worker    return self.TEST_CLASS_TEMPLATE.format(copyright = get_copyright('smali'),
398*795d594fSAndroid Build Coastguard Worker                                           implements_spec = s_ifaces,
399*795d594fSAndroid Build Coastguard Worker                                           ifaces = j_ifaces,
400*795d594fSAndroid Build Coastguard Worker                                           class_name = self.class_name,
401*795d594fSAndroid Build Coastguard Worker                                           test_funcs = funcs,
402*795d594fSAndroid Build Coastguard Worker                                           test_calls = calls)
403*795d594fSAndroid Build Coastguard Worker
404*795d594fSAndroid Build Coastguard Workerclass IncompatibleClassChangeErrorResult(mixins.Named):
405*795d594fSAndroid Build Coastguard Worker  def get_name(self):
406*795d594fSAndroid Build Coastguard Worker    return "IncompatibleClassChangeError"
407*795d594fSAndroid Build Coastguard Worker
408*795d594fSAndroid Build Coastguard WorkerICCE = IncompatibleClassChangeErrorResult()
409*795d594fSAndroid Build Coastguard Worker
410*795d594fSAndroid Build Coastguard Workerclass NoSuchMethodErrorResult(mixins.Named):
411*795d594fSAndroid Build Coastguard Worker  def get_name(self):
412*795d594fSAndroid Build Coastguard Worker    return "NoSuchMethodError"
413*795d594fSAndroid Build Coastguard Worker
414*795d594fSAndroid Build Coastguard WorkerNSME = NoSuchMethodErrorResult()
415*795d594fSAndroid Build Coastguard Worker
416*795d594fSAndroid Build Coastguard Workerclass TestInterface(mixins.DumpMixin, mixins.Named, mixins.NameComparableMixin, mixins.SmaliFileMixin):
417*795d594fSAndroid Build Coastguard Worker  """
418*795d594fSAndroid Build Coastguard Worker  An interface that will be used to test default method resolution order.
419*795d594fSAndroid Build Coastguard Worker  """
420*795d594fSAndroid Build Coastguard Worker
421*795d594fSAndroid Build Coastguard Worker  TEST_INTERFACE_TEMPLATE = """{copyright}
422*795d594fSAndroid Build Coastguard Worker.class public abstract interface L{class_name};
423*795d594fSAndroid Build Coastguard Worker.super Ljava/lang/Object;
424*795d594fSAndroid Build Coastguard Worker{implements_spec}
425*795d594fSAndroid Build Coastguard Worker
426*795d594fSAndroid Build Coastguard Worker# public interface {class_name} {extends} {ifaces} {{
427*795d594fSAndroid Build Coastguard Worker
428*795d594fSAndroid Build Coastguard Worker{funcs}
429*795d594fSAndroid Build Coastguard Worker
430*795d594fSAndroid Build Coastguard Worker# }}
431*795d594fSAndroid Build Coastguard Worker"""
432*795d594fSAndroid Build Coastguard Worker
433*795d594fSAndroid Build Coastguard Worker  ABSTRACT_FUNC_TEMPLATE = """
434*795d594fSAndroid Build Coastguard Worker"""
435*795d594fSAndroid Build Coastguard Worker
436*795d594fSAndroid Build Coastguard Worker  DEFAULT_FUNC_TEMPLATE = """
437*795d594fSAndroid Build Coastguard Worker#   public default String getCalledInterface() {{
438*795d594fSAndroid Build Coastguard Worker#     return "{class_name}";
439*795d594fSAndroid Build Coastguard Worker#   }}
440*795d594fSAndroid Build Coastguard Worker.method public getCalledInterface()Ljava/lang/String;
441*795d594fSAndroid Build Coastguard Worker  .locals 1
442*795d594fSAndroid Build Coastguard Worker  const-string v0, "{class_name}"
443*795d594fSAndroid Build Coastguard Worker  return-object v0
444*795d594fSAndroid Build Coastguard Worker.end method
445*795d594fSAndroid Build Coastguard Worker"""
446*795d594fSAndroid Build Coastguard Worker
447*795d594fSAndroid Build Coastguard Worker  IMPLEMENTS_TEMPLATE = """
448*795d594fSAndroid Build Coastguard Worker.implements L{iface_name};
449*795d594fSAndroid Build Coastguard Worker"""
450*795d594fSAndroid Build Coastguard Worker
451*795d594fSAndroid Build Coastguard Worker  def __init__(self, ifaces, default, name = None):
452*795d594fSAndroid Build Coastguard Worker    """
453*795d594fSAndroid Build Coastguard Worker    Initialize interface with the given super-interfaces
454*795d594fSAndroid Build Coastguard Worker    """
455*795d594fSAndroid Build Coastguard Worker    self.ifaces = ifaces
456*795d594fSAndroid Build Coastguard Worker    self.default = default
457*795d594fSAndroid Build Coastguard Worker    if name is None:
458*795d594fSAndroid Build Coastguard Worker      end = "_DEFAULT" if default else ""
459*795d594fSAndroid Build Coastguard Worker      self.class_name = "INTERFACE_"+gensym()+end
460*795d594fSAndroid Build Coastguard Worker    else:
461*795d594fSAndroid Build Coastguard Worker      self.class_name = name
462*795d594fSAndroid Build Coastguard Worker
463*795d594fSAndroid Build Coastguard Worker  def get_initial_build_version(self):
464*795d594fSAndroid Build Coastguard Worker    """
465*795d594fSAndroid Build Coastguard Worker    Returns a version of this class that can be used for the initial build (meaning no compiler
466*795d594fSAndroid Build Coastguard Worker    checks will be triggered).
467*795d594fSAndroid Build Coastguard Worker    """
468*795d594fSAndroid Build Coastguard Worker    return TestInterface([i.get_initial_build_version() for i in self.ifaces],
469*795d594fSAndroid Build Coastguard Worker                         True,
470*795d594fSAndroid Build Coastguard Worker                         self.class_name)
471*795d594fSAndroid Build Coastguard Worker
472*795d594fSAndroid Build Coastguard Worker  def initial_build_different(self):
473*795d594fSAndroid Build Coastguard Worker    return not self.default
474*795d594fSAndroid Build Coastguard Worker
475*795d594fSAndroid Build Coastguard Worker  def get_name(self):
476*795d594fSAndroid Build Coastguard Worker    """
477*795d594fSAndroid Build Coastguard Worker    Gets the name of this interface
478*795d594fSAndroid Build Coastguard Worker    """
479*795d594fSAndroid Build Coastguard Worker    return self.class_name
480*795d594fSAndroid Build Coastguard Worker
481*795d594fSAndroid Build Coastguard Worker  def __iter__(self):
482*795d594fSAndroid Build Coastguard Worker    """
483*795d594fSAndroid Build Coastguard Worker    Performs depth-first traversal of the interface tree this interface is the
484*795d594fSAndroid Build Coastguard Worker    root of. Does not filter out repeats.
485*795d594fSAndroid Build Coastguard Worker    """
486*795d594fSAndroid Build Coastguard Worker    for i in self.ifaces:
487*795d594fSAndroid Build Coastguard Worker      yield i
488*795d594fSAndroid Build Coastguard Worker      yield from i
489*795d594fSAndroid Build Coastguard Worker
490*795d594fSAndroid Build Coastguard Worker  def get_called(self):
491*795d594fSAndroid Build Coastguard Worker    """
492*795d594fSAndroid Build Coastguard Worker    Get the interface whose default method would be called when calling the
493*795d594fSAndroid Build Coastguard Worker    CalledInterfaceName function.
494*795d594fSAndroid Build Coastguard Worker    """
495*795d594fSAndroid Build Coastguard Worker    all_ifaces = set(iface for iface in self if iface.default)
496*795d594fSAndroid Build Coastguard Worker    for i in all_ifaces:
497*795d594fSAndroid Build Coastguard Worker      if all(map(lambda j: i not in j.get_super_types(), all_ifaces)):
498*795d594fSAndroid Build Coastguard Worker        return i
499*795d594fSAndroid Build Coastguard Worker    return ICCE if any(map(lambda i: i.default, all_ifaces)) else NSME
500*795d594fSAndroid Build Coastguard Worker
501*795d594fSAndroid Build Coastguard Worker  def get_super_types(self):
502*795d594fSAndroid Build Coastguard Worker    """
503*795d594fSAndroid Build Coastguard Worker    Returns a set of all the supertypes of this interface
504*795d594fSAndroid Build Coastguard Worker    """
505*795d594fSAndroid Build Coastguard Worker    return set(i2 for i2 in self)
506*795d594fSAndroid Build Coastguard Worker
507*795d594fSAndroid Build Coastguard Worker  def get_output(self):
508*795d594fSAndroid Build Coastguard Worker    if self.default:
509*795d594fSAndroid Build Coastguard Worker      return self.get_name()
510*795d594fSAndroid Build Coastguard Worker    else:
511*795d594fSAndroid Build Coastguard Worker      return self.get_called().get_name()
512*795d594fSAndroid Build Coastguard Worker
513*795d594fSAndroid Build Coastguard Worker  def get_tree(self):
514*795d594fSAndroid Build Coastguard Worker    """
515*795d594fSAndroid Build Coastguard Worker    Print out a representation of the type tree of this class
516*795d594fSAndroid Build Coastguard Worker    """
517*795d594fSAndroid Build Coastguard Worker    return "[{class_name} {iftree}]".format(class_name = self.get_name(),
518*795d594fSAndroid Build Coastguard Worker                                            iftree = print_tree(self.ifaces))
519*795d594fSAndroid Build Coastguard Worker  def __str__(self):
520*795d594fSAndroid Build Coastguard Worker    """
521*795d594fSAndroid Build Coastguard Worker    Print the smali code for this interface.
522*795d594fSAndroid Build Coastguard Worker    """
523*795d594fSAndroid Build Coastguard Worker    s_ifaces = '\n'.join(map(lambda a: self.IMPLEMENTS_TEMPLATE.format(iface_name = a.get_name()),
524*795d594fSAndroid Build Coastguard Worker                             self.ifaces))
525*795d594fSAndroid Build Coastguard Worker    j_ifaces = ', '.join(map(lambda a: a.get_name(), self.ifaces))
526*795d594fSAndroid Build Coastguard Worker    if self.default:
527*795d594fSAndroid Build Coastguard Worker      funcs = self.DEFAULT_FUNC_TEMPLATE.format(class_name = self.class_name)
528*795d594fSAndroid Build Coastguard Worker    else:
529*795d594fSAndroid Build Coastguard Worker      funcs = self.ABSTRACT_FUNC_TEMPLATE
530*795d594fSAndroid Build Coastguard Worker    return self.TEST_INTERFACE_TEMPLATE.format(copyright = get_copyright('smali'),
531*795d594fSAndroid Build Coastguard Worker                                               implements_spec = s_ifaces,
532*795d594fSAndroid Build Coastguard Worker                                               extends = "extends" if len(self.ifaces) else "",
533*795d594fSAndroid Build Coastguard Worker                                               ifaces = j_ifaces,
534*795d594fSAndroid Build Coastguard Worker                                               funcs = funcs,
535*795d594fSAndroid Build Coastguard Worker                                               class_name = self.class_name)
536*795d594fSAndroid Build Coastguard Worker
537*795d594fSAndroid Build Coastguard Workerdef dump_tree(ifaces):
538*795d594fSAndroid Build Coastguard Worker  """
539*795d594fSAndroid Build Coastguard Worker  Yields all the interfaces transitively implemented by the set in
540*795d594fSAndroid Build Coastguard Worker  reverse-depth-first order
541*795d594fSAndroid Build Coastguard Worker  """
542*795d594fSAndroid Build Coastguard Worker  for i in ifaces:
543*795d594fSAndroid Build Coastguard Worker    yield from dump_tree(i.ifaces)
544*795d594fSAndroid Build Coastguard Worker    yield i
545*795d594fSAndroid Build Coastguard Worker
546*795d594fSAndroid Build Coastguard Workerdef print_tree(ifaces):
547*795d594fSAndroid Build Coastguard Worker  """
548*795d594fSAndroid Build Coastguard Worker  Prints the tree for the given ifaces.
549*795d594fSAndroid Build Coastguard Worker  """
550*795d594fSAndroid Build Coastguard Worker  return " ".join(i.get_tree() for i in  ifaces)
551*795d594fSAndroid Build Coastguard Worker
552*795d594fSAndroid Build Coastguard Worker# Cached output of subtree_sizes for speed of access.
553*795d594fSAndroid Build Coastguard WorkerSUBTREES = [set(tuple(sorted(l)) for l in subtree_sizes(i)) for i in range(MAX_IFACE_DEPTH + 1)]
554*795d594fSAndroid Build Coastguard Worker
555*795d594fSAndroid Build Coastguard Workerdef create_test_classes():
556*795d594fSAndroid Build Coastguard Worker  """
557*795d594fSAndroid Build Coastguard Worker  Yield all the test classes with the different interface trees
558*795d594fSAndroid Build Coastguard Worker  """
559*795d594fSAndroid Build Coastguard Worker  for num in range(1, MAX_IFACE_DEPTH + 1):
560*795d594fSAndroid Build Coastguard Worker    for split in SUBTREES[num]:
561*795d594fSAndroid Build Coastguard Worker      ifaces = []
562*795d594fSAndroid Build Coastguard Worker      for sub in split:
563*795d594fSAndroid Build Coastguard Worker        ifaces.append(list(create_interface_trees(sub)))
564*795d594fSAndroid Build Coastguard Worker    for supers in itertools.product(*ifaces):
565*795d594fSAndroid Build Coastguard Worker      yield TestClass(supers)
566*795d594fSAndroid Build Coastguard Worker
567*795d594fSAndroid Build Coastguard Workerdef create_interface_trees(num):
568*795d594fSAndroid Build Coastguard Worker  """
569*795d594fSAndroid Build Coastguard Worker  Yield all the interface trees up to 'num' depth.
570*795d594fSAndroid Build Coastguard Worker  """
571*795d594fSAndroid Build Coastguard Worker  if num == 0:
572*795d594fSAndroid Build Coastguard Worker    yield TestInterface(tuple(), False)
573*795d594fSAndroid Build Coastguard Worker    yield TestInterface(tuple(), True)
574*795d594fSAndroid Build Coastguard Worker    return
575*795d594fSAndroid Build Coastguard Worker  for split in SUBTREES[num]:
576*795d594fSAndroid Build Coastguard Worker    ifaces = []
577*795d594fSAndroid Build Coastguard Worker    for sub in split:
578*795d594fSAndroid Build Coastguard Worker      ifaces.append(list(create_interface_trees(sub)))
579*795d594fSAndroid Build Coastguard Worker    for supers in itertools.product(*ifaces):
580*795d594fSAndroid Build Coastguard Worker      yield TestInterface(supers, False)
581*795d594fSAndroid Build Coastguard Worker      yield TestInterface(supers, True)
582*795d594fSAndroid Build Coastguard Worker      for selected in (set(dump_tree(supers)) - set(supers)):
583*795d594fSAndroid Build Coastguard Worker         yield TestInterface(tuple([selected] + list(supers)), True)
584*795d594fSAndroid Build Coastguard Worker         yield TestInterface(tuple([selected] + list(supers)), False)
585*795d594fSAndroid Build Coastguard Worker      # TODO Should add on some from higher up the tree.
586*795d594fSAndroid Build Coastguard Worker
587*795d594fSAndroid Build Coastguard Workerdef create_all_test_files():
588*795d594fSAndroid Build Coastguard Worker  """
589*795d594fSAndroid Build Coastguard Worker  Creates all the objects representing the files in this test. They just need to
590*795d594fSAndroid Build Coastguard Worker  be dumped.
591*795d594fSAndroid Build Coastguard Worker  """
592*795d594fSAndroid Build Coastguard Worker  mc = MainClass()
593*795d594fSAndroid Build Coastguard Worker  classes = {mc}
594*795d594fSAndroid Build Coastguard Worker  for clazz in create_test_classes():
595*795d594fSAndroid Build Coastguard Worker    classes.add(clazz)
596*795d594fSAndroid Build Coastguard Worker    for i in dump_tree(clazz.ifaces):
597*795d594fSAndroid Build Coastguard Worker      classes.add(i)
598*795d594fSAndroid Build Coastguard Worker    mc.add_test(clazz)
599*795d594fSAndroid Build Coastguard Worker  return mc, classes
600*795d594fSAndroid Build Coastguard Worker
601*795d594fSAndroid Build Coastguard Workerdef main(argv):
602*795d594fSAndroid Build Coastguard Worker  smali_dir = Path(argv[1])
603*795d594fSAndroid Build Coastguard Worker  if not smali_dir.exists() or not smali_dir.is_dir():
604*795d594fSAndroid Build Coastguard Worker    print("{} is not a valid smali dir".format(smali_dir), file=sys.stderr)
605*795d594fSAndroid Build Coastguard Worker    sys.exit(1)
606*795d594fSAndroid Build Coastguard Worker  expected_txt = Path(argv[2])
607*795d594fSAndroid Build Coastguard Worker  mainclass, all_files = create_all_test_files()
608*795d594fSAndroid Build Coastguard Worker  with expected_txt.open('w') as out:
609*795d594fSAndroid Build Coastguard Worker    print(mainclass.get_expected(), file=out)
610*795d594fSAndroid Build Coastguard Worker  for f in all_files:
611*795d594fSAndroid Build Coastguard Worker    f.dump(smali_dir)
612*795d594fSAndroid Build Coastguard Worker
613*795d594fSAndroid Build Coastguard Workerif __name__ == '__main__':
614*795d594fSAndroid Build Coastguard Worker  main(sys.argv)
615