1# Copyright 2018 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5"""Helpers for processing conditionally enabled features in a mojom.""" 6 7from . import ast 8from ..error import Error 9 10class EnableIfError(Error): 11 """ Class for errors from .""" 12 13 def __init__(self, filename, message, lineno=None): 14 Error.__init__(self, filename, message, lineno=lineno, addenda=None) 15 16def _IsEnabled(definition, enabled_features): 17 """Returns true if a definition is enabled. 18 19 A definition is enabled if it has no EnableIf attribute, or if the value of 20 the EnableIf attribute is in enabled_features. 21 """ 22 if not hasattr(definition, "attribute_list"): 23 return True 24 if not definition.attribute_list: 25 return True 26 27 already_defined = False 28 for a in definition.attribute_list: 29 if a.key == 'EnableIf': 30 if already_defined: 31 raise EnableIfError(definition.filename, 32 "EnableIf attribute may only be defined once per field.", 33 definition.lineno) 34 already_defined = True 35 36 for attribute in definition.attribute_list: 37 if attribute.key == 'EnableIf' and attribute.value not in enabled_features: 38 return False 39 return True 40 41 42def _FilterDisabledFromNodeList(node_list, enabled_features): 43 if not node_list: 44 return 45 assert isinstance(node_list, ast.NodeListBase) 46 node_list.items = [ 47 item for item in node_list.items if _IsEnabled(item, enabled_features) 48 ] 49 for item in node_list.items: 50 _FilterDefinition(item, enabled_features) 51 52 53def _FilterDefinition(definition, enabled_features): 54 """Filters definitions with a body.""" 55 if isinstance(definition, ast.Enum): 56 _FilterDisabledFromNodeList(definition.enum_value_list, enabled_features) 57 elif isinstance(definition, ast.Interface): 58 _FilterDisabledFromNodeList(definition.body, enabled_features) 59 elif isinstance(definition, ast.Method): 60 _FilterDisabledFromNodeList(definition.parameter_list, enabled_features) 61 _FilterDisabledFromNodeList(definition.response_parameter_list, 62 enabled_features) 63 elif isinstance(definition, ast.Struct): 64 _FilterDisabledFromNodeList(definition.body, enabled_features) 65 elif isinstance(definition, ast.Union): 66 _FilterDisabledFromNodeList(definition.body, enabled_features) 67 68 69def RemoveDisabledDefinitions(mojom, enabled_features): 70 """Removes conditionally disabled definitions from a Mojom node.""" 71 mojom.import_list = ast.ImportList([ 72 imported_file for imported_file in mojom.import_list 73 if _IsEnabled(imported_file, enabled_features) 74 ]) 75 mojom.definition_list = [ 76 definition for definition in mojom.definition_list 77 if _IsEnabled(definition, enabled_features) 78 ] 79 for definition in mojom.definition_list: 80 _FilterDefinition(definition, enabled_features) 81