Merge multiple APIs using the precedence order specified in apiNames. Also deletes elements. tree - Element at the root of the hierarchy to merge. apiNames - list of strings of API names.
(tree, fromApiNames, toApiName)
| 91 | |
| 92 | |
| 93 | def mergeAPIs(tree, fromApiNames, toApiName): |
| 94 | """Merge multiple APIs using the precedence order specified in apiNames. |
| 95 | Also deletes <remove> elements. |
| 96 | |
| 97 | tree - Element at the root of the hierarchy to merge. |
| 98 | apiNames - list of strings of API names.""" |
| 99 | |
| 100 | stack = deque() |
| 101 | stack.append(tree) |
| 102 | |
| 103 | while len(stack) > 0: |
| 104 | parent = stack.pop() |
| 105 | |
| 106 | for child in parent.findall('*'): |
| 107 | if child.tag == 'remove': |
| 108 | # Remove <remove> elements |
| 109 | parent.remove(child) |
| 110 | else: |
| 111 | stack.append(child) |
| 112 | |
| 113 | supportedList = child.get('supported') |
| 114 | if supportedList: |
| 115 | supportedList = supportedList.split(',') |
| 116 | for apiName in [toApiName] + fromApiNames: |
| 117 | if apiName in supportedList: |
| 118 | child.set('supported', toApiName) |
| 119 | |
| 120 | if child.get('api'): |
| 121 | definitionName = None |
| 122 | definitionVariants = [] |
| 123 | |
| 124 | # Keep only one definition with the same name if there are multiple definitions |
| 125 | if child.tag in ['type']: |
| 126 | if child.get('name') is not None: |
| 127 | definitionName = child.get('name') |
| 128 | definitionVariants = parent.findall(f"{child.tag}[@name='{definitionName}']") |
| 129 | else: |
| 130 | definitionName = child.find('name').text |
| 131 | definitionVariants = parent.findall(f"{child.tag}/name[.='{definitionName}']/..") |
| 132 | elif child.tag in ['member', 'param']: |
| 133 | definitionName = child.find('name').text |
| 134 | definitionVariants = parent.findall(f"{child.tag}/name[.='{definitionName}']/..") |
| 135 | elif child.tag in ['enum', 'feature']: |
| 136 | definitionName = child.get('name') |
| 137 | definitionVariants = parent.findall(f"{child.tag}[@name='{definitionName}']") |
| 138 | elif child.tag in ['require']: |
| 139 | # No way to correlate require tags because they do not have a definite identifier in the way they |
| 140 | # are used in the latest forms of the XML so the best we can do is simply enable all of them |
| 141 | if child.get('api') in fromApiNames: |
| 142 | child.set('api', toApiName) |
| 143 | elif child.tag in ['command']: |
| 144 | definitionName = child.find('proto/name').text |
| 145 | definitionVariants = parent.findall(f"{child.tag}/proto/name[.='{definitionName}']/../..") |
| 146 | |
| 147 | if definitionName: |
| 148 | bestMatchApi = None |
| 149 | requires = None |
| 150 | for apiName in [toApiName] + fromApiNames: |