1eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light#!/usr/bin/python3 2eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light# 3eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light# Copyright (C) 2015 The Android Open Source Project 4eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light# 5eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light# Licensed under the Apache License, Version 2.0 (the "License"); 6eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light# you may not use this file except in compliance with the License. 7eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light# You may obtain a copy of the License at 8eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light# 9eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light# http://www.apache.org/licenses/LICENSE-2.0 10eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light# 11eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light# Unless required by applicable law or agreed to in writing, software 12eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light# distributed under the License is distributed on an "AS IS" BASIS, 13eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light# See the License for the specific language governing permissions and 15eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light# limitations under the License. 16eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 17eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light""" 18d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex LightGenerate Java Main file from a classes.xml file. 19eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light""" 20eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 21eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightimport os 22eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightimport sys 23eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightfrom pathlib import Path 24eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 25eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex LightBUILD_TOP = os.getenv("ANDROID_BUILD_TOP") 26eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightif BUILD_TOP is None: 27eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light print("ANDROID_BUILD_TOP not set. Please run build/envsetup.sh", file=sys.stderr) 28eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light sys.exit(1) 29eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 30eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light# Allow us to import utils and mixins. 31eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightsys.path.append(str(Path(BUILD_TOP)/"art"/"test"/"utils"/"python")) 32eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 33eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightfrom testgen.utils import get_copyright 34eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightimport testgen.mixins as mixins 35eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 36eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightfrom collections import namedtuple 37eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightimport itertools 38eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightimport functools 39eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightimport xml.etree.ElementTree as ET 40eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 41d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Lightclass MainClass(mixins.DumpMixin, mixins.Named, mixins.JavaFileMixin): 42eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 43eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light A mainclass and main method for this test. 44eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 45eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 46eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light MAIN_CLASS_TEMPLATE = """{copyright} 47d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Lightclass Main {{ 48eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light{test_groups} 49eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light{test_funcs} 50eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light{main_func} 51d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light}} 52eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light""" 53eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 54eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light MAIN_FUNCTION_TEMPLATE = """ 55d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light public static void main(String[] args) {{ 56eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light {test_group_invoke} 57d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light }} 58eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light""" 59eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 60eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light TEST_GROUP_INVOKE_TEMPLATE = """ 61d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light {test_name}(); 62eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light""" 63eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 64eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light def __init__(self): 65eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 66eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light Initialize this MainClass 67eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 68eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light self.tests = set() 69eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light self.global_funcs = set() 70eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 71eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light def add_instance(self, it): 72eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 73eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light Add an instance test for the given class 74eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 75eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light self.tests.add(it) 76eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 77eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light def add_func(self, f): 78eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 79eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light Add a function to the class 80eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 81eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light self.global_funcs.add(f) 82eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 83eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light def get_name(self): 84eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 85eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light Get the name of this class 86eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 87eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light return "Main" 88eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 89eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light def __str__(self): 90eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 91eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light Print this class 92eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 93eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light all_tests = sorted(self.tests) 94eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light test_invoke = "" 95eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light test_groups = "" 96eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light for t in all_tests: 97eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light test_groups += str(t) 98eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light for t in sorted(all_tests): 99eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light test_invoke += self.TEST_GROUP_INVOKE_TEMPLATE.format(test_name=t.get_name()) 100eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light main_func = self.MAIN_FUNCTION_TEMPLATE.format(test_group_invoke=test_invoke) 101eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 102eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light funcs = "" 103eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light for f in self.global_funcs: 104eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light funcs += str(f) 105d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light return self.MAIN_CLASS_TEMPLATE.format(copyright = get_copyright('java'), 106eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light test_groups=test_groups, 107eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light main_func=main_func, test_funcs=funcs) 108eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 109eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 110eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightclass InstanceTest(mixins.Named, mixins.NameComparableMixin): 111eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 112eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light A method that runs tests for a particular concrete type, It calls the test 113eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light cases for running it in all possible ways. 114eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 115eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 116eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light INSTANCE_TEST_TEMPLATE = """ 117d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light public static void {test_name}() {{ 118d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light System.out.println("Testing for type {ty}"); 119d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light String s = "{ty}"; 120d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light {ty} v = new {ty}(); 121eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 122eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light {invokes} 123eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 124d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light System.out.println("End testing for type {ty}"); 125d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light }} 126eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light""" 127eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 128eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light TEST_INVOKE_TEMPLATE = """ 129d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light {fname}(s, v); 130eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light""" 131eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 132eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light def __init__(self, main, ty): 133eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 134eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light Initialize this test group for the given type 135eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 136eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light self.ty = ty 137eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light self.main = main 138eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light self.funcs = set() 139eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light self.main.add_instance(self) 140eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 141eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light def get_name(self): 142eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 143eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light Get the name of this test group 144eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 145eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light return "TEST_NAME_"+self.ty 146eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 147eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light def add_func(self, f): 148eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 149eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light Add a test function to this test group 150eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 151eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light self.main.add_func(f) 152eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light self.funcs.add(f) 153eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 154eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light def __str__(self): 155eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 156d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light Returns the java code for this function 157eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 158eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light func_invokes = "" 159eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light for f in sorted(self.funcs, key=lambda a: (a.func, a.farg)): 160eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light func_invokes += self.TEST_INVOKE_TEMPLATE.format(fname=f.get_name(), 161eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light farg=f.farg) 162eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 163eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light return self.INSTANCE_TEST_TEMPLATE.format(test_name=self.get_name(), ty=self.ty, 164eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light invokes=func_invokes) 165eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 166eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightclass Func(mixins.Named, mixins.NameComparableMixin): 167eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 168eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light A single test case that attempts to invoke a function on receiver of a given type. 169eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 170eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 171eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light TEST_FUNCTION_TEMPLATE = """ 172d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light public static void {fname}(String s, {farg} v) {{ 173d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light try {{ 174d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light System.out.printf("%s-{invoke_type:<9} {farg:>9}.{callfunc}()='%s'\\n", s, v.{callfunc}()); 175d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light return; 176d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light }} catch (Error e) {{ 177d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light System.out.printf("%s-{invoke_type} on {farg}: {callfunc}() threw exception!\\n", s); 178b47a1cc17f53951b900e56bb68c58c972517cb07Alex Light if (e instanceof IncompatibleClassChangeError) {{ 179b47a1cc17f53951b900e56bb68c58c972517cb07Alex Light System.out.printf("Exception is of type %s\\n", e.getClass().getName()); 180b47a1cc17f53951b900e56bb68c58c972517cb07Alex Light }} else {{ 181b47a1cc17f53951b900e56bb68c58c972517cb07Alex Light e.printStackTrace(System.out); 182b47a1cc17f53951b900e56bb68c58c972517cb07Alex Light }} 183d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light }} 184d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light }} 185eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light""" 186eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 187eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light def __init__(self, func, farg, invoke): 188eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 189eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light Initialize this test function for the given invoke type and argument 190eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 191eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light self.func = func 192eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light self.farg = farg 193eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light self.invoke = invoke 194eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 195eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light def get_name(self): 196eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 197eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light Get the name of this test 198eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 199eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light return "Test_Func_{}_{}_{}".format(self.func, self.farg, self.invoke) 200eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 201eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light def __str__(self): 202eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 203d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light Get the java code for this test function 204eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 205eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light return self.TEST_FUNCTION_TEMPLATE.format(fname=self.get_name(), 206eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light farg=self.farg, 207eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light invoke_type=self.invoke, 208eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light callfunc=self.func) 209eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 210eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightdef flatten_classes(classes, c): 211eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 212eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light Iterate over all the classes 'c' can be used as 213eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 214eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light while c: 215eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light yield c 216eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light c = classes.get(c.super_class) 217eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 218eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightdef flatten_class_methods(classes, c): 219eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 220eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light Iterate over all the methods 'c' can call 221eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 222eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light for c1 in flatten_classes(classes, c): 223eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light yield from c1.methods 224eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 225eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightdef flatten_interfaces(dat, c): 226eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 227eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light Iterate over all the interfaces 'c' transitively implements 228eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 229eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light def get_ifaces(cl): 230eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light for i2 in cl.implements: 231eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light yield dat.interfaces[i2] 232eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light yield from get_ifaces(dat.interfaces[i2]) 233eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 234eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light for cl in flatten_classes(dat.classes, c): 235eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light yield from get_ifaces(cl) 236eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 237eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightdef flatten_interface_methods(dat, i): 238eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 239eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light Iterate over all the interface methods 'c' can call 240eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 241eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light yield from i.methods 242eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light for i2 in flatten_interfaces(dat, i): 243eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light yield from i2.methods 244eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 245eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightdef make_main_class(dat): 246eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 247d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light Creates a Main.java file that runs all the tests 248eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 249eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light m = MainClass() 250eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light for c in dat.classes.values(): 251eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light i = InstanceTest(m, c.name) 252eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light for clazz in flatten_classes(dat.classes, c): 253eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light for meth in flatten_class_methods(dat.classes, clazz): 254eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light i.add_func(Func(meth, clazz.name, 'virtual')) 255eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light for iface in flatten_interfaces(dat, clazz): 256eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light for meth in flatten_interface_methods(dat, iface): 257eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light i.add_func(Func(meth, clazz.name, 'virtual')) 258eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light i.add_func(Func(meth, iface.name, 'interface')) 259eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light return m 260eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 261eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightclass TestData(namedtuple("TestData", ['classes', 'interfaces'])): 262eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 263eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light A class representing the classes.xml document. 264eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 265eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light pass 266eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 267eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightclass Clazz(namedtuple("Clazz", ["name", "methods", "super_class", "implements"])): 268eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 269eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light A class representing a class element in the classes.xml document. 270eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 271eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light pass 272eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 273eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightclass IFace(namedtuple("IFace", ["name", "methods", "super_class", "implements"])): 274eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 275eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light A class representing an interface element in the classes.xml document. 276eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 277eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light pass 278eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 279eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightdef parse_xml(xml): 280eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 281eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light Parse the xml description of this test. 282eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light """ 283eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light classes = dict() 284eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light ifaces = dict() 285eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light root = ET.fromstring(xml) 286eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light for iface in root.find("interfaces"): 287eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light name = iface.attrib['name'] 288eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light implements = [a.text for a in iface.find("implements")] 289eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light methods = [a.text for a in iface.find("methods")] 290eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light ifaces[name] = IFace(name = name, 291eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light super_class = iface.attrib['super'], 292eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light methods = methods, 293eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light implements = implements) 294eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light for clazz in root.find('classes'): 295eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light name = clazz.attrib['name'] 296eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light implements = [a.text for a in clazz.find("implements")] 297eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light methods = [a.text for a in clazz.find("methods")] 298eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light classes[name] = Clazz(name = name, 299eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light super_class = clazz.attrib['super'], 300eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light methods = methods, 301eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light implements = implements) 302eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light return TestData(classes, ifaces) 303eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 304eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightdef main(argv): 305d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light java_dir = Path(argv[1]) 306d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light if not java_dir.exists() or not java_dir.is_dir(): 307d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light print("{} is not a valid java dir".format(java_dir), file=sys.stderr) 308eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light sys.exit(1) 309d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light class_data = parse_xml((java_dir / "classes.xml").open().read()) 310d204ba5ac9c5488880d85dc198e7b6aefea2f0bbAlex Light make_main_class(class_data).dump(java_dir) 311eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 312eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightif __name__ == '__main__': 313eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light main(sys.argv) 314