Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(331)

Side by Side Diff: Source/core/scripts/make_runtime_features.py

Issue 15018018: Autogenerate lists of "stable", "experimental" and "test" features from RuntimeEnabledFeatures.in (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Ready for review Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/scripts/in_generator.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (C) 2013 Google Inc. All rights reserved. 2 # Copyright (C) 2013 Google Inc. All rights reserved.
3 # 3 #
4 # Redistribution and use in source and binary forms, with or without 4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are 5 # modification, are permitted provided that the following conditions are
6 # met: 6 # met:
7 # 7 #
8 # * Redistributions of source code must retain the above copyright 8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer. 9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above 10 # * Redistributions in binary form must reproduce the above
(...skipping 27 matching lines...) Expand all
38 HEADER_TEMPLATE = """%(license)s 38 HEADER_TEMPLATE = """%(license)s
39 #ifndef %(class_name)s_h 39 #ifndef %(class_name)s_h
40 #define %(class_name)s_h 40 #define %(class_name)s_h
41 41
42 namespace WebCore { 42 namespace WebCore {
43 43
44 // A class that stores static enablers for all experimental features. 44 // A class that stores static enablers for all experimental features.
45 45
46 class %(class_name)s { 46 class %(class_name)s {
47 public: 47 public:
48 %(method_declarations)s 48 %(set_toggle_declarations)s
49
50 %(accessor_declarations)s
49 private: 51 private:
50 %(class_name)s() { } 52 %(class_name)s() { }
51 53
52 %(storage_declarations)s 54 %(storage_declarations)s
53 }; 55 };
54 56
55 } // namespace WebCore 57 } // namespace WebCore
56 58
57 #endif // %(class_name)s_h 59 #endif // %(class_name)s_h
58 """ 60 """
59 61
60 IMPLEMENTATION_TEMPLATE = """%(license)s 62 IMPLEMENTATION_TEMPLATE = """%(license)s
61 #include "config.h" 63 #include "config.h"
62 #include "%(class_name)s.h" 64 #include "%(class_name)s.h"
63 65
64 namespace WebCore { 66 namespace WebCore {
65 67
68 %(set_toggle_definitions)s
66 %(storage_definitions)s 69 %(storage_definitions)s
67 70
68 } // namespace WebCore 71 } // namespace WebCore
69 """ 72 """
70 73
71 class RuntimeFeatureWriter(in_generator.Writer): 74 class RuntimeFeatureWriter(in_generator.Writer):
72 class_name = "RuntimeEnabledFeatures" 75 class_name = 'RuntimeEnabledFeatures'
76
77 # FIXME: valid_values and defaults should probably roll into one object.
78 valid_values = {
79 'status': ['stable', 'experimental', 'test'],
80 }
73 defaults = { 81 defaults = {
74 'condition' : None, 82 'condition' : None,
75 'depends_on' : [], 83 'depends_on' : [],
76 'custom': False, 84 'custom': False,
85 'status': None,
77 } 86 }
78 87
79 def __init__(self, in_file_path): 88 def __init__(self, in_file_path):
80 super(RuntimeFeatureWriter, self).__init__(in_file_path) 89 super(RuntimeFeatureWriter, self).__init__(in_file_path)
81 self._all_features = self.in_file.name_dictionaries 90 self._all_features = self.in_file.name_dictionaries
82 # Make sure the resulting dictionaries have all the keys we expect. 91 # Make sure the resulting dictionaries have all the keys we expect.
83 for feature in self._all_features: 92 for feature in self._all_features:
84 feature['first_lowered_name'] = self._lower_first(feature['name']) 93 feature['first_lowered_name'] = self._lower_first(feature['name'])
85 # Most features just check their isFooEnabled bool 94 # Most features just check their isFooEnabled bool
86 # but some depend on more than one bool. 95 # but some depend on more than one bool.
87 enabled_condition = "is%sEnabled" % feature['name'] 96 enabled_condition = "is%sEnabled" % feature['name']
88 for dependant_name in feature['depends_on']: 97 for dependant_name in feature['depends_on']:
89 enabled_condition += " && is%sEnabled" % dependant_name 98 enabled_condition += " && is%sEnabled" % dependant_name
90 feature['enabled_condition'] = enabled_condition 99 feature['enabled_condition'] = enabled_condition
91 self._non_custom_features = filter(lambda feature: not feature['custom'] , self._all_features) 100 self._non_custom_features = filter(lambda feature: not feature['custom'] , self._all_features)
92 101
93 def _lower_first(self, string): 102 def _lower_first(self, string):
94 lowered = string[0].lower() + string[1:] 103 lowered = string[0].lower() + string[1:]
95 lowered = lowered.replace("cSS", "css") 104 lowered = lowered.replace("cSS", "css")
96 lowered = lowered.replace("iME", "ime") 105 lowered = lowered.replace("iME", "ime")
97 return lowered 106 return lowered
98 107
99 def _method_declaration(self, feature): 108 def _feature_set_declaration(self, feature_set):
109 return " static void set%sFeaturesEnabled(bool);" % feature_set.capit alize()
110
111 def _feature_accessor_declaration(self, feature):
100 if feature['custom']: 112 if feature['custom']:
101 return " static bool %(first_lowered_name)sEnabled();\n" % featur e 113 return " static bool %(first_lowered_name)sEnabled();\n" % featur e
102 unconditional = """ static void set%(name)sEnabled(bool isEnabled) { is%(name)sEnabled = isEnabled; } 114 unconditional = """ static void set%(name)sEnabled(bool isEnabled) { is%(name)sEnabled = isEnabled; }
103 static bool %(first_lowered_name)sEnabled() { return %(enabled_condition)s; } 115 static bool %(first_lowered_name)sEnabled() { return %(enabled_condition)s; }
104 """ 116 """
105 conditional = "#if ENABLE(%(condition)s)\n" + unconditional + """#else 117 conditional = "#if ENABLE(%(condition)s)\n" + unconditional + """#else
106 static void set%(name)sEnabled(bool) { } 118 static void set%(name)sEnabled(bool) { }
107 static bool %(first_lowered_name)sEnabled() { return false; } 119 static bool %(first_lowered_name)sEnabled() { return false; }
108 #endif 120 #endif
109 """ 121 """
110 template = conditional if feature['condition'] else unconditional 122 template = conditional if feature['condition'] else unconditional
111 return template % feature 123 return template % feature
112 124
113 def _storage_declarations(self, feature): 125 def _storage_declarations(self, feature):
114 declaration = " static bool is%(name)sEnabled;" % feature 126 declaration = " static bool is%(name)sEnabled;" % feature
115 return self.wrap_with_condition(declaration, feature['condition']) 127 return self.wrap_with_condition(declaration, feature['condition'])
116 128
117 def generate_header(self): 129 def generate_header(self):
118 return HEADER_TEMPLATE % { 130 return HEADER_TEMPLATE % {
119 'class_name' : self.class_name, 131 'class_name' : self.class_name,
120 'license' : license.license_for_generated_cpp(), 132 'license' : license.license_for_generated_cpp(),
121 'method_declarations' : "\n".join(map(self._method_declaration, self ._all_features)), 133 'set_toggle_declarations' : "\n".join(map(self._feature_set_declarat ion, self._feature_sets())),
134 'accessor_declarations' : "\n".join(map(self._feature_accessor_decla ration, self._all_features)),
122 'storage_declarations' : "\n".join(map(self._storage_declarations, s elf._non_custom_features)), 135 'storage_declarations' : "\n".join(map(self._storage_declarations, s elf._non_custom_features)),
123 } 136 }
124 137
138 def _feature_sets(self):
139 # Another way to think of the status levels is as "sets of features"
140 # which is how we're referring to them in this generator.
141 return self.valid_values['status']
142
143 def _feature_toggle(self, feature):
144 return " set%(name)sEnabled(enable);" % feature
145
146 def _feature_set_definition(self, feature_set):
147 features_in_set = filter(lambda feature: feature['status'] == feature_se t, self._all_features)
148 template = """void %(class_name)s::set%(feature_set)sFeaturesEnabled(boo l enable)
149 {
150 %(feature_toggles)s
151 }
152 """
153 return template % {
154 'class_name': self.class_name,
155 'feature_set': feature_set.capitalize(),
156 'feature_toggles': "\n".join(map(self._feature_toggle, features_in_s et)),
157 }
158
125 def _storage_definition(self, feature): 159 def _storage_definition(self, feature):
126 definition = "bool RuntimeEnabledFeatures::is%(name)sEnabled = false;" % feature 160 definition = "bool RuntimeEnabledFeatures::is%(name)sEnabled = false;" % feature
127 return self.wrap_with_condition(definition, feature['condition']) 161 return self.wrap_with_condition(definition, feature['condition'])
128 162
129 def generate_implementation(self): 163 def generate_implementation(self):
130 return IMPLEMENTATION_TEMPLATE % { 164 return IMPLEMENTATION_TEMPLATE % {
131 'class_name' : self.class_name, 165 'class_name' : self.class_name,
132 'license' : license.license_for_generated_cpp(), 166 'license' : license.license_for_generated_cpp(),
133 'storage_definitions' : "\n".join(map(self._storage_definition, self ._non_custom_features)), 167 'set_toggle_definitions' : '\n'.join(map(self._feature_set_definitio n, self._feature_sets())),
168 'storage_definitions' : '\n'.join(map(self._storage_definition, self ._non_custom_features)),
134 } 169 }
135 170
136 171
137 if __name__ == "__main__": 172 if __name__ == "__main__":
138 in_generator.Maker(RuntimeFeatureWriter).main(sys.argv) 173 in_generator.Maker(RuntimeFeatureWriter).main(sys.argv)
OLDNEW
« no previous file with comments | « Source/core/scripts/in_generator.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698