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 WorkerCommon mixins and abstract base classes (ABCs) useful for writing test generators in python 19*795d594fSAndroid Build Coastguard Worker""" 20*795d594fSAndroid Build Coastguard Worker 21*795d594fSAndroid Build Coastguard Workerimport abc 22*795d594fSAndroid Build Coastguard Workerimport collections.abc 23*795d594fSAndroid Build Coastguard Workerimport functools 24*795d594fSAndroid Build Coastguard Worker 25*795d594fSAndroid Build Coastguard Workerclass Named(metaclass=abc.ABCMeta): 26*795d594fSAndroid Build Coastguard Worker """ 27*795d594fSAndroid Build Coastguard Worker An abc that defines a get_name method. 28*795d594fSAndroid Build Coastguard Worker """ 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker @abc.abstractmethod 31*795d594fSAndroid Build Coastguard Worker def get_name(self): 32*795d594fSAndroid Build Coastguard Worker """ 33*795d594fSAndroid Build Coastguard Worker Returns a unique name to use as the identity for implementing comparisons. 34*795d594fSAndroid Build Coastguard Worker """ 35*795d594fSAndroid Build Coastguard Worker pass 36*795d594fSAndroid Build Coastguard Worker 37*795d594fSAndroid Build Coastguard Workerclass FileLike(metaclass=abc.ABCMeta): 38*795d594fSAndroid Build Coastguard Worker """ 39*795d594fSAndroid Build Coastguard Worker An abc that defines get_file_name and get_file_extension methods. 40*795d594fSAndroid Build Coastguard Worker """ 41*795d594fSAndroid Build Coastguard Worker 42*795d594fSAndroid Build Coastguard Worker @abc.abstractmethod 43*795d594fSAndroid Build Coastguard Worker def get_file_name(self): 44*795d594fSAndroid Build Coastguard Worker """Returns the filename this object represents""" 45*795d594fSAndroid Build Coastguard Worker pass 46*795d594fSAndroid Build Coastguard Worker 47*795d594fSAndroid Build Coastguard Worker @abc.abstractmethod 48*795d594fSAndroid Build Coastguard Worker def get_file_extension(self): 49*795d594fSAndroid Build Coastguard Worker """Returns the file extension of the file this object represents""" 50*795d594fSAndroid Build Coastguard Worker pass 51*795d594fSAndroid Build Coastguard Worker 52*795d594fSAndroid Build Coastguard Worker@functools.lru_cache(maxsize=None) 53*795d594fSAndroid Build Coastguard Workerdef get_file_extension_mixin(ext): 54*795d594fSAndroid Build Coastguard Worker """ 55*795d594fSAndroid Build Coastguard Worker Gets a mixin that defines get_file_name(self) in terms of get_name(self) with the 56*795d594fSAndroid Build Coastguard Worker given file extension. 57*795d594fSAndroid Build Coastguard Worker """ 58*795d594fSAndroid Build Coastguard Worker 59*795d594fSAndroid Build Coastguard Worker class FExt(object): 60*795d594fSAndroid Build Coastguard Worker """ 61*795d594fSAndroid Build Coastguard Worker A mixin defining get_file_name(self) in terms of get_name(self) 62*795d594fSAndroid Build Coastguard Worker """ 63*795d594fSAndroid Build Coastguard Worker 64*795d594fSAndroid Build Coastguard Worker def get_file_name(self): 65*795d594fSAndroid Build Coastguard Worker return self.get_name() + ext 66*795d594fSAndroid Build Coastguard Worker 67*795d594fSAndroid Build Coastguard Worker def get_file_extension(self): 68*795d594fSAndroid Build Coastguard Worker return ext 69*795d594fSAndroid Build Coastguard Worker 70*795d594fSAndroid Build Coastguard Worker # Register the ABCs 71*795d594fSAndroid Build Coastguard Worker Named.register(FExt) 72*795d594fSAndroid Build Coastguard Worker FileLike.register(FExt) 73*795d594fSAndroid Build Coastguard Worker 74*795d594fSAndroid Build Coastguard Worker return FExt 75*795d594fSAndroid Build Coastguard Worker 76*795d594fSAndroid Build Coastguard Workerclass SmaliFileMixin(get_file_extension_mixin(".smali")): 77*795d594fSAndroid Build Coastguard Worker """ 78*795d594fSAndroid Build Coastguard Worker A mixin that defines that the file this class belongs to is get_name() + ".smali". 79*795d594fSAndroid Build Coastguard Worker """ 80*795d594fSAndroid Build Coastguard Worker pass 81*795d594fSAndroid Build Coastguard Worker 82*795d594fSAndroid Build Coastguard Workerclass JavaFileMixin(get_file_extension_mixin(".java")): 83*795d594fSAndroid Build Coastguard Worker """ 84*795d594fSAndroid Build Coastguard Worker A mixin that defines that the file this class belongs to is get_name() + ".java". 85*795d594fSAndroid Build Coastguard Worker """ 86*795d594fSAndroid Build Coastguard Worker pass 87*795d594fSAndroid Build Coastguard Worker 88*795d594fSAndroid Build Coastguard Workerclass NameComparableMixin(object): 89*795d594fSAndroid Build Coastguard Worker """ 90*795d594fSAndroid Build Coastguard Worker A mixin that defines the object comparison and related functionality in terms 91*795d594fSAndroid Build Coastguard Worker of a get_name(self) function. 92*795d594fSAndroid Build Coastguard Worker """ 93*795d594fSAndroid Build Coastguard Worker 94*795d594fSAndroid Build Coastguard Worker def __lt__(self, other): 95*795d594fSAndroid Build Coastguard Worker return self.get_name() < other.get_name() 96*795d594fSAndroid Build Coastguard Worker 97*795d594fSAndroid Build Coastguard Worker def __gt__(self, other): 98*795d594fSAndroid Build Coastguard Worker return self.get_name() > other.get_name() 99*795d594fSAndroid Build Coastguard Worker 100*795d594fSAndroid Build Coastguard Worker def __eq__(self, other): 101*795d594fSAndroid Build Coastguard Worker return self.get_name() == other.get_name() 102*795d594fSAndroid Build Coastguard Worker 103*795d594fSAndroid Build Coastguard Worker def __le__(self, other): 104*795d594fSAndroid Build Coastguard Worker return self.get_name() <= other.get_name() 105*795d594fSAndroid Build Coastguard Worker 106*795d594fSAndroid Build Coastguard Worker def __ge__(self, other): 107*795d594fSAndroid Build Coastguard Worker return self.get_name() >= other.get_name() 108*795d594fSAndroid Build Coastguard Worker 109*795d594fSAndroid Build Coastguard Worker def __ne__(self, other): 110*795d594fSAndroid Build Coastguard Worker return self.get_name() != other.get_name() 111*795d594fSAndroid Build Coastguard Worker 112*795d594fSAndroid Build Coastguard Worker def __hash__(self): 113*795d594fSAndroid Build Coastguard Worker return hash(self.get_name()) 114*795d594fSAndroid Build Coastguard Worker 115*795d594fSAndroid Build Coastguard WorkerNamed.register(NameComparableMixin) 116*795d594fSAndroid Build Coastguard Workercollections.abc.Hashable.register(NameComparableMixin) 117*795d594fSAndroid Build Coastguard Worker 118*795d594fSAndroid Build Coastguard Workerclass DumpMixin(metaclass=abc.ABCMeta): 119*795d594fSAndroid Build Coastguard Worker """ 120*795d594fSAndroid Build Coastguard Worker A mixin to add support for dumping the string representation of an object to a 121*795d594fSAndroid Build Coastguard Worker file. Requires the get_file_name(self) method be defined. 122*795d594fSAndroid Build Coastguard Worker """ 123*795d594fSAndroid Build Coastguard Worker 124*795d594fSAndroid Build Coastguard Worker @abc.abstractmethod 125*795d594fSAndroid Build Coastguard Worker def __str__(self): 126*795d594fSAndroid Build Coastguard Worker """ 127*795d594fSAndroid Build Coastguard Worker Returns the data to be printed to a file by dump. 128*795d594fSAndroid Build Coastguard Worker """ 129*795d594fSAndroid Build Coastguard Worker pass 130*795d594fSAndroid Build Coastguard Worker 131*795d594fSAndroid Build Coastguard Worker def dump(self, directory): 132*795d594fSAndroid Build Coastguard Worker """ 133*795d594fSAndroid Build Coastguard Worker Dump this object to a file in the given directory 134*795d594fSAndroid Build Coastguard Worker """ 135*795d594fSAndroid Build Coastguard Worker out_file = directory / self.get_file_name() 136*795d594fSAndroid Build Coastguard Worker if out_file.exists(): 137*795d594fSAndroid Build Coastguard Worker out_file.unlink() 138*795d594fSAndroid Build Coastguard Worker with out_file.open('w') as out: 139*795d594fSAndroid Build Coastguard Worker print(str(self), file=out) 140*795d594fSAndroid Build Coastguard Worker 141*795d594fSAndroid Build Coastguard WorkerFileLike.register(DumpMixin) 142