# Copyright 2019 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import sys # TODO(crbug.com/1174969): Remove this once Python2 is obsoleted. if sys.version_info.major != 2: long = int basestring = str def make_copy(obj, memo=None): """ Creates a copy of the given object, which should be an IR or part of IR. The copy is created basically as a deep copy of the object, but |make_copy| method is used to create a (part of) copy if the object (or part of it) has the method. |memo| argument behaves as the same as |deepcopy|. """ if memo is None: memo = dict() if (obj is None or isinstance(obj, (bool, int, long, float, complex, basestring))): # Do not make a copy if the object is of an immutable primitive type # (or its subclass). # # Memoization is tricky in case that both of Identifier('x') and # Component('x') exist. We could memoize them as # |memo[(type(obj), obj)] = copy|, though. return obj if hasattr(obj, 'make_copy'): return obj.make_copy(memo=memo) memoizable = obj.__hash__ is not None if memoizable: copy = memo.get(obj, None) if copy is not None: return copy def memoize(copy): if memoizable: memo[obj] = copy return copy cls = type(obj) if isinstance(obj, (list, tuple, set, frozenset)): return memoize(cls(map(lambda x: make_copy(x, memo), obj))) if isinstance(obj, dict): return memoize( cls([(make_copy(key, memo), make_copy(value, memo)) for key, value in obj.items()])) if hasattr(obj, '__dict__'): copy = memoize(cls.__new__(cls)) for name, value in obj.__dict__.items(): setattr(copy, name, make_copy(value, memo)) return copy assert False, 'Unsupported type of object: {}'.format(cls)