Index: mojo/public/tools/bindings/mojom_bindings_generator.py |
diff --git a/mojo/public/tools/bindings/mojom_bindings_generator.py b/mojo/public/tools/bindings/mojom_bindings_generator.py |
index 5240dd7f4d2b0660e98794b2658fa8ce624114e8..12196badfb9837b591045a366e053c607b550c3f 100755 |
--- a/mojo/public/tools/bindings/mojom_bindings_generator.py |
+++ b/mojo/public/tools/bindings/mojom_bindings_generator.py |
@@ -49,6 +49,7 @@ _BUILTIN_GENERATORS = { |
"java": "mojom_java_generator.py", |
} |
+ |
def LoadGenerators(generators_string): |
if not generators_string: |
return [] # No generators. |
@@ -77,12 +78,28 @@ def MakeImportStackMessage(imported_filename_stack): |
zip(imported_filename_stack[1:], imported_filename_stack)])) |
-def FindImportFile(dir_name, file_name, search_dirs): |
- for search_dir in [dir_name] + search_dirs: |
- path = os.path.join(search_dir, file_name) |
+class RelativePath(object): |
+ """Represents a path relative to the source tree.""" |
+ def __init__(self, path, source_root): |
+ self.path = path |
+ self.source_root = source_root |
+ |
+ def relative_path(self): |
+ return os.path.relpath(os.path.abspath(self.path), |
+ os.path.abspath(self.source_root)) |
+ |
+ |
+def FindImportFile(rel_dir, file_name, search_rel_dirs): |
+ """Finds |file_name| in either |rel_dir| or |search_rel_dirs|. Returns a |
+ RelativePath with first file found, or an arbitrary non-existent file |
+ otherwise.""" |
+ for rel_search_dir in [rel_dir] + search_rel_dirs: |
+ path = os.path.join(rel_search_dir.path, file_name) |
if os.path.isfile(path): |
- return path |
- return os.path.join(dir_name, file_name) |
+ return RelativePath(path, rel_search_dir.source_root) |
+ return RelativePath(os.path.join(rel_dir.path, file_name), |
+ rel_dir.source_root) |
+ |
class MojomProcessor(object): |
def __init__(self, should_generate): |
@@ -105,18 +122,20 @@ class MojomProcessor(object): |
self._typemap[language] = language_map |
def ProcessFile(self, args, remaining_args, generator_modules, filename): |
- self._ParseFileAndImports(filename, args.import_directories, []) |
+ self._ParseFileAndImports(RelativePath(filename, args.depth), |
+ args.import_directories, []) |
return self._GenerateModule(args, remaining_args, generator_modules, |
- filename) |
+ RelativePath(filename, args.depth)) |
- def _GenerateModule(self, args, remaining_args, generator_modules, filename): |
+ def _GenerateModule(self, args, remaining_args, generator_modules, |
+ rel_filename): |
# Return the already-generated module. |
- if filename in self._processed_files: |
- return self._processed_files[filename] |
- tree = self._parsed_files[filename] |
+ if rel_filename.path in self._processed_files: |
+ return self._processed_files[rel_filename.path] |
+ tree = self._parsed_files[rel_filename.path] |
- dirname, name = os.path.split(filename) |
+ dirname, name = os.path.split(rel_filename.path) |
mojom = Translate(tree, name) |
if args.debug_print_intermediate: |
pprint.PrettyPrinter().pprint(mojom) |
@@ -124,22 +143,21 @@ class MojomProcessor(object): |
# Process all our imports first and collect the module object for each. |
# We use these to generate proper type info. |
for import_data in mojom['imports']: |
- import_filename = FindImportFile(dirname, |
- import_data['filename'], |
- args.import_directories) |
+ rel_import_file = FindImportFile( |
+ RelativePath(dirname, rel_filename.source_root), |
+ import_data['filename'], args.import_directories) |
import_data['module'] = self._GenerateModule( |
- args, remaining_args, generator_modules, import_filename) |
+ args, remaining_args, generator_modules, rel_import_file) |
module = OrderedModuleFromData(mojom) |
# Set the path as relative to the source root. |
- module.path = os.path.relpath(os.path.abspath(filename), |
- os.path.abspath(args.depth)) |
+ module.path = rel_filename.relative_path() |
# Normalize to unix-style path here to keep the generators simpler. |
module.path = module.path.replace('\\', '/') |
- if self._should_generate(filename): |
+ if self._should_generate(rel_filename.path): |
for language, generator_module in generator_modules.iteritems(): |
generator = generator_module.Generator( |
module, args.output_dir, typemap=self._typemap.get(language, {}), |
@@ -154,49 +172,56 @@ class MojomProcessor(object): |
generator.GenerateFiles(filtered_args) |
# Save result. |
- self._processed_files[filename] = module |
+ self._processed_files[rel_filename.path] = module |
return module |
- def _ParseFileAndImports(self, filename, import_directories, |
+ def _ParseFileAndImports(self, rel_filename, import_directories, |
imported_filename_stack): |
# Ignore already-parsed files. |
- if filename in self._parsed_files: |
+ if rel_filename.path in self._parsed_files: |
return |
- if filename in imported_filename_stack: |
- print "%s: Error: Circular dependency" % filename + \ |
- MakeImportStackMessage(imported_filename_stack + [filename]) |
+ if rel_filename.path in imported_filename_stack: |
+ print "%s: Error: Circular dependency" % rel_filename.path + \ |
+ MakeImportStackMessage(imported_filename_stack + [rel_filename.path]) |
sys.exit(1) |
try: |
- with open(filename) as f: |
+ with open(rel_filename.path) as f: |
source = f.read() |
except IOError as e: |
- print "%s: Error: %s" % (e.filename, e.strerror) + \ |
- MakeImportStackMessage(imported_filename_stack + [filename]) |
+ print "%s: Error: %s" % (e.rel_filename.path, e.strerror) + \ |
+ MakeImportStackMessage(imported_filename_stack + [rel_filename.path]) |
sys.exit(1) |
try: |
- tree = Parse(source, filename) |
+ tree = Parse(source, rel_filename.path) |
except Error as e: |
- full_stack = imported_filename_stack + [filename] |
+ full_stack = imported_filename_stack + [rel_filename.path] |
print str(e) + MakeImportStackMessage(full_stack) |
sys.exit(1) |
- dirname = os.path.split(filename)[0] |
+ dirname = os.path.split(rel_filename.path)[0] |
for imp_entry in tree.import_list: |
- import_filename = FindImportFile(dirname, |
+ import_file_entry = FindImportFile( |
+ RelativePath(dirname, rel_filename.source_root), |
imp_entry.import_filename, import_directories) |
- self._ParseFileAndImports(import_filename, import_directories, |
- imported_filename_stack + [filename]) |
+ self._ParseFileAndImports(import_file_entry, import_directories, |
+ imported_filename_stack + [rel_filename.path]) |
- self._parsed_files[filename] = tree |
+ self._parsed_files[rel_filename.path] = tree |
def _Generate(args, remaining_args): |
if args.variant == "none": |
args.variant = None |
+ for idx, import_dir in enumerate(args.import_directories): |
+ tokens = import_dir.split(":") |
+ if len(tokens) >= 2: |
+ args.import_directories[idx] = RelativePath(tokens[0], tokens[1]) |
+ else: |
+ args.import_directories[idx] = RelativePath(tokens[0], args.depth) |
generator_modules = LoadGenerators(args.generators_string) |
fileutil.EnsureDirectoryExists(args.output_dir) |
@@ -243,7 +268,10 @@ def main(): |
help="comma-separated list of generators") |
generate_parser.add_argument( |
"-I", dest="import_directories", action="append", metavar="directory", |
- default=[], help="add a directory to be searched for import files") |
+ default=[], |
+ help="add a directory to be searched for import files. The depth from " |
+ "source root can be specified for each import by appending it after " |
+ "a colon") |
generate_parser.add_argument("--typemap", action="append", metavar="TYPEMAP", |
default=[], dest="typemaps", |
help="apply TYPEMAP to generated output") |