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

Side by Side Diff: tools/json_schema_compiler/compiler.py

Issue 487533005: Add support for references in different paths in apis (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 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
« no previous file with comments | « tools/json_schema_compiler/cc_generator.py ('k') | tools/json_schema_compiler/cpp_generator.py » ('j') | 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) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 """Generator for C++ structs from api json files. 5 """Generator for C++ structs from api json files.
6 6
7 The purpose of this tool is to remove the need for hand-written code that 7 The purpose of this tool is to remove the need for hand-written code that
8 converts to and from base::Value types when receiving javascript api calls. 8 converts to and from base::Value types when receiving javascript api calls.
9 Originally written for generating code for extension apis. Reference schemas 9 Originally written for generating code for extension apis. Reference schemas
10 are in chrome/common/extensions/api. 10 are in chrome/common/extensions/api.
11 11
12 Usage example: 12 Usage example:
13 compiler.py --root /home/Work/src --namespace extensions windows.json 13 compiler.py --root /home/Work/src --namespace extensions windows.json
14 tabs.json 14 tabs.json
15 compiler.py --destdir gen --root /home/Work/src 15 compiler.py --destdir gen --root /home/Work/src
16 --namespace extensions windows.json tabs.json 16 --namespace extensions windows.json tabs.json
17 """ 17 """
18 18
19 import optparse 19 import optparse
20 import os 20 import os
21 import shlex
21 import sys 22 import sys
22 23
23 from cpp_bundle_generator import CppBundleGenerator 24 from cpp_bundle_generator import CppBundleGenerator
24 from cpp_generator import CppGenerator 25 from cpp_generator import CppGenerator
25 from cpp_type_generator import CppTypeGenerator 26 from cpp_type_generator import CppTypeGenerator
26 from dart_generator import DartGenerator 27 from dart_generator import DartGenerator
27 import json_schema 28 import json_schema
29 from cpp_namespace_environment import CppNamespaceEnvironment
28 from model import Model 30 from model import Model
29 from schema_loader import SchemaLoader 31 from schema_loader import SchemaLoader
30 32
31 # Names of supported code generators, as specified on the command-line. 33 # Names of supported code generators, as specified on the command-line.
32 # First is default. 34 # First is default.
33 GENERATORS = ['cpp', 'cpp-bundle-registration', 'cpp-bundle-schema', 'dart'] 35 GENERATORS = ['cpp', 'cpp-bundle-registration', 'cpp-bundle-schema', 'dart']
34 36
35 def GenerateSchema(generator_name, 37 def GenerateSchema(generator_name,
36 file_paths, 38 file_paths,
37 root, 39 root,
38 destdir, 40 destdir,
39 cpp_namespace_pattern, 41 cpp_namespace_pattern,
40 dart_overrides_dir, 42 dart_overrides_dir,
41 impl_dir): 43 impl_dir,
44 include_rules):
42 # Merge the source files into a single list of schemas. 45 # Merge the source files into a single list of schemas.
43 api_defs = [] 46 api_defs = []
44 for file_path in file_paths: 47 for file_path in file_paths:
45 schema = os.path.normpath(file_path) 48 schema = os.path.relpath(file_path, root)
46 schema_loader = SchemaLoader( 49 schema_loader = SchemaLoader(
47 os.path.dirname(os.path.relpath(schema, root)), 50 root,
48 os.path.dirname(file_path)) 51 os.path.dirname(schema),
49 api_def = schema_loader.LoadSchema(os.path.split(schema)[1]) 52 include_rules,
53 cpp_namespace_pattern)
54 api_def = schema_loader.LoadSchema(schema)
50 55
51 # If compiling the C++ model code, delete 'nocompile' nodes. 56 # If compiling the C++ model code, delete 'nocompile' nodes.
52 if generator_name == 'cpp': 57 if generator_name == 'cpp':
53 api_def = json_schema.DeleteNodes(api_def, 'nocompile') 58 api_def = json_schema.DeleteNodes(api_def, 'nocompile')
54 api_defs.extend(api_def) 59 api_defs.extend(api_def)
55 60
56 api_model = Model() 61 api_model = Model()
57 62
58 # For single-schema compilation make sure that the first (i.e. only) schema 63 # For single-schema compilation make sure that the first (i.e. only) schema
59 # is the default one. 64 # is the default one.
60 default_namespace = None 65 default_namespace = None
61 66
62 # If we have files from multiple source paths, we'll use the common parent 67 # If we have files from multiple source paths, we'll use the common parent
63 # path as the source directory. 68 # path as the source directory.
64 src_path = None 69 src_path = None
65 70
66 # Load the actual namespaces into the model. 71 # Load the actual namespaces into the model.
67 for target_namespace, file_path in zip(api_defs, file_paths): 72 for target_namespace, file_path in zip(api_defs, file_paths):
68 relpath = os.path.relpath(os.path.normpath(file_path), root) 73 relpath = os.path.relpath(os.path.normpath(file_path), root)
69 namespace = api_model.AddNamespace(target_namespace, 74 namespace = api_model.AddNamespace(target_namespace,
70 relpath, 75 relpath,
71 include_compiler_options=True) 76 include_compiler_options=True,
77 environment=CppNamespaceEnvironment(
78 cpp_namespace_pattern))
72 79
73 if default_namespace is None: 80 if default_namespace is None:
74 default_namespace = namespace 81 default_namespace = namespace
75 82
76 if src_path is None: 83 if src_path is None:
77 src_path = namespace.source_file_dir 84 src_path = namespace.source_file_dir
78 else: 85 else:
79 src_path = os.path.commonprefix((src_path, namespace.source_file_dir)) 86 src_path = os.path.commonprefix((src_path, namespace.source_file_dir))
80 87
81 path, filename = os.path.split(file_path) 88 path, filename = os.path.split(file_path)
(...skipping 16 matching lines...) Expand all
98 ('generated_api_registration.cc', 105 ('generated_api_registration.cc',
99 cpp_bundle_generator.api_cc_generator), 106 cpp_bundle_generator.api_cc_generator),
100 ('generated_api_registration.h', cpp_bundle_generator.api_h_generator), 107 ('generated_api_registration.h', cpp_bundle_generator.api_h_generator),
101 ] 108 ]
102 elif generator_name == 'cpp-bundle-schema': 109 elif generator_name == 'cpp-bundle-schema':
103 generators = [ 110 generators = [
104 ('generated_schemas.cc', cpp_bundle_generator.schemas_cc_generator), 111 ('generated_schemas.cc', cpp_bundle_generator.schemas_cc_generator),
105 ('generated_schemas.h', cpp_bundle_generator.schemas_h_generator) 112 ('generated_schemas.h', cpp_bundle_generator.schemas_h_generator)
106 ] 113 ]
107 elif generator_name == 'cpp': 114 elif generator_name == 'cpp':
108 cpp_generator = CppGenerator(type_generator, cpp_namespace_pattern) 115 cpp_generator = CppGenerator(type_generator)
109 generators = [ 116 generators = [
110 ('%s.h' % filename_base, cpp_generator.h_generator), 117 ('%s.h' % filename_base, cpp_generator.h_generator),
111 ('%s.cc' % filename_base, cpp_generator.cc_generator) 118 ('%s.cc' % filename_base, cpp_generator.cc_generator)
112 ] 119 ]
113 elif generator_name == 'dart': 120 elif generator_name == 'dart':
114 generators = [ 121 generators = [
115 ('%s.dart' % namespace.unix_name, DartGenerator( 122 ('%s.dart' % namespace.unix_name, DartGenerator(
116 dart_overrides_dir)) 123 dart_overrides_dir))
117 ] 124 ]
118 else: 125 else:
(...skipping 30 matching lines...) Expand all
149 parser.add_option('-n', '--namespace', default='generated_api_schemas', 156 parser.add_option('-n', '--namespace', default='generated_api_schemas',
150 help='C++ namespace for generated files. e.g extensions::api.') 157 help='C++ namespace for generated files. e.g extensions::api.')
151 parser.add_option('-g', '--generator', default=GENERATORS[0], 158 parser.add_option('-g', '--generator', default=GENERATORS[0],
152 choices=GENERATORS, 159 choices=GENERATORS,
153 help='The generator to use to build the output code. Supported values are' 160 help='The generator to use to build the output code. Supported values are'
154 ' %s' % GENERATORS) 161 ' %s' % GENERATORS)
155 parser.add_option('-D', '--dart-overrides-dir', dest='dart_overrides_dir', 162 parser.add_option('-D', '--dart-overrides-dir', dest='dart_overrides_dir',
156 help='Adds custom dart from files in the given directory (Dart only).') 163 help='Adds custom dart from files in the given directory (Dart only).')
157 parser.add_option('-i', '--impl-dir', dest='impl_dir', 164 parser.add_option('-i', '--impl-dir', dest='impl_dir',
158 help='The root path of all API implementations') 165 help='The root path of all API implementations')
166 parser.add_option('-I', '--include-rules',
167 help='A list of paths to include when searching for referenced objects,'
168 ' with the namespace separated by a \':\'. Example: '
169 '/foo/bar:Foo::Bar::%(namespace)s')
159 170
160 (opts, file_paths) = parser.parse_args() 171 (opts, file_paths) = parser.parse_args()
161 172
162 if not file_paths: 173 if not file_paths:
163 sys.exit(0) # This is OK as a no-op 174 sys.exit(0) # This is OK as a no-op
164 175
165 # Unless in bundle mode, only one file should be specified. 176 # Unless in bundle mode, only one file should be specified.
166 if (opts.generator not in ('cpp-bundle-registration', 'cpp-bundle-schema') and 177 if (opts.generator not in ('cpp-bundle-registration', 'cpp-bundle-schema') and
167 len(file_paths) > 1): 178 len(file_paths) > 1):
168 # TODO(sashab): Could also just use file_paths[0] here and not complain. 179 # TODO(sashab): Could also just use file_paths[0] here and not complain.
169 raise Exception( 180 raise Exception(
170 "Unless in bundle mode, only one file can be specified at a time.") 181 "Unless in bundle mode, only one file can be specified at a time.")
171 182
183 def split_path_and_namespace(path_and_namespace):
184 if ':' not in path_and_namespace:
185 raise ValueError('Invalid include rule "%s". Rules must be of '
186 'the form path:namespace' % path_and_namespace)
187 return path_and_namespace.split(':', 1)
188
189 include_rules = []
190 if opts.include_rules:
191 include_rules = map(split_path_and_namespace,
192 shlex.split(opts.include_rules))
193
172 result = GenerateSchema(opts.generator, file_paths, opts.root, opts.destdir, 194 result = GenerateSchema(opts.generator, file_paths, opts.root, opts.destdir,
173 opts.namespace, opts.dart_overrides_dir, 195 opts.namespace, opts.dart_overrides_dir,
174 opts.impl_dir) 196 opts.impl_dir, include_rules)
175 if not opts.destdir: 197 if not opts.destdir:
176 print result 198 print result
OLDNEW
« no previous file with comments | « tools/json_schema_compiler/cc_generator.py ('k') | tools/json_schema_compiler/cpp_generator.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698